<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Computer Vision Software &#187; OpenCV</title>
	<atom:link href="http://www.computer-vision-software.com/blog/category/opencv/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.computer-vision-software.com/blog</link>
	<description>Rhonda Ltd., computer vision software blog</description>
	<lastBuildDate>Tue, 10 Aug 2010 00:43:24 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Compiling OpenCV for Android using NDK 3</title>
		<link>http://www.computer-vision-software.com/blog/2010/04/android/</link>
		<comments>http://www.computer-vision-software.com/blog/2010/04/android/#comments</comments>
		<pubDate>Thu, 22 Apr 2010 06:01:50 +0000</pubDate>
		<dc:creator>apermyakov</dc:creator>
				<category><![CDATA[OpenCV]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[ARM]]></category>
		<category><![CDATA[face detection]]></category>
		<category><![CDATA[NDK]]></category>

		<guid isPermaLink="false">http://www.computer-vision-software.com/blog/?p=116</guid>
		<description><![CDATA[Build platform: Ubuntu 9.10 Target platform: Android Download and prepare OpenCV library source code. 1. Download the latest version of OpenCV (http://sourceforge.net/project/showfiles.php?group_id=22870). 2. As build platform is Linux, select linux version (for example OpenCV2.1.0.tat.bz). 3. Unpack somewhere to home dir. Download and prepare cross-compiler 1. Download Android NDK 3 for Linux (http://developer.android.com/sdk/ndk/index.html) 2. Unpack it [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.computer-vision-software.com/blog/wp-content/uploads/2010/04/Picture-18.jpg"></a></p>
<p>Build platform: Ubuntu 9.10<br />
Target platform: Android</p>
<p><strong>Download and prepare OpenCV library source code. </strong></p>
<p><strong>1. </strong>Download the latest version of OpenCV (<a href="http://sourceforge.net/project/showfiles.php?group_id=22870" target="_blank">http://sourceforge.net/project/showfiles.php?group_id=22870</a>).</p>
<p>2. As build platform is Linux, select linux version (for example<em> OpenCV2.1.0.tat.bz</em>).</p>
<p><span id="more-116"></span></p>
<p><strong>3. </strong>Unpack somewhere to home dir.</p>
<p><strong>Download and prepare cross-compiler</strong></p>
<p><strong><span style="font-weight: normal;">1. Download Android NDK 3 for Linux (<a href="http://developer.android.com/sdk/ndk/index.html" target="_blank">http://developer.android.com/sdk/ndk/index.html</a>)</span></strong></p>
<p><strong><span style="font-weight: normal;">2. Unpack it to <em>~/android_ndk_3/</em></span></strong></p>
<p><strong><span style="font-weight: normal;"><em><span style="font-style: normal;"><strong>3. </strong>Then run <em>~/android_ndk_3/build/host-setup.sh</em> but first fix the error in line 119</span></em></span></strong></p>
<p><strong><span style="font-weight: normal;"><em><span style="font-style: normal;">Change</span></em></span></strong></p>
<p><strong><span style="font-weight: normal;"><em><span style="font-style: normal;">if [ "$result" = "Pass" ] ; then</span></em></span></strong></p>
<p><strong><span style="font-weight: normal;"><em><span style="font-style: normal;">to</span></em></span></strong></p>
<p><strong><span style="font-weight: normal;"><em><span style="font-style: normal;">if [ "$result" == "Pass" ] ; then</span></em></span></strong></p>
<p><strong><span style="font-weight: normal;"><em><span style="font-style: normal;"><strong>4. </strong>Do/install whatever needed to let host-setup.sh complete successful.</span></em></span></strong></p>
<p><strong>Create NDK project/Modify Makefiles</strong></p>
<p>There is one big issue with NKD toolchein. It has trimmed stdc library which does not contain STL. Because of that some files (like <em>cvkdtree.cpp</em> in cv) can not be compiled since they use vector, list and other stuff. The solution is to compile STL from source code. In my OpenCV NDK project I used STL sources from uClibc (<a href="http://www.uclibc.org" target="_blank">http://www.uclibc.org</a>).</p>
<p>The simpliest way to start your OpenCV NDK project is to update <em>hello-jni</em> project with OpenCV source files.</p>
<p>The <em>~/android_ndk_3/apps/hello-jni/project/jni</em> folder of hello-jni project may look like this</p>
<ol>cv<br />
- hdr<br />
- src<br />
cvaux<br />
- hdr<br />
- src<br />
cxcore<br />
- hdr<br />
- src<br />
stl<br />
- hdr<br />
- src<br />
Android.mk<br />
hello-jni.c</ol>
<p>The <em>~/android_ndk_3/apps/hello-jni/project/jni/Android.mk</em> may looks like this</p>
<ol>APPS_PATH := $(call my-dir)############################<br />
# stl<br />
############################<br />
include $(CLEAR_VARS)LOCAL_PATH := $(APPS_PATH)/stl/src<br />
LOCAL_C_INCLUDES := $(APPS_PATH)/stl/hdrLOCAL_MODULE := stl<br />
LOCAL_SRC_FILES := string.cpp algorithm.cpp char_traits.cpp iterator.cpp limits.cpp list.cpp vector.cppinclude $(BUILD_STATIC_LIBRARY)############################<br />
# cxcore<br />
############################<br />
include $(CLEAR_VARS)LOCAL_PATH := $(APPS_PATH)/cxcore/src<br />
LOCAL_C_INCLUDES := $(APPS_PATH)/cxcore/hdrLOCAL_CXXFLAGS := -DHAVE_CONFIG_HLOCAL_MODULE := cxcore<br />
LOCAL_SRC_FILES := cxalloc.cpp cxarithm.cpp cxarray.cpp cxcmp.cpp cxconvert.cpp cxcopy.cpp cxdatastructs.cpp cxdrawing.cpp cxdxt.cpp cxerror.cpp cximage.cpp cxjacobieigens.cpp cxlogic.cpp cxlut.cpp cxmathfuncs.cpp cxmatmul.cpp cxmatrix.cpp cxmean.cpp cxmeansdv.cpp cxminmaxloc.cpp cxnorm.cpp cxouttext.cpp cxpersistence.cpp cxprecomp.cpp cxrand.cpp cxsumpixels.cpp cxsvd.cpp cxswitcher.cpp cxtables.cpp cxutils.cpp dummy.cppinclude $(BUILD_STATIC_LIBRARY)############################<br />
# cv<br />
############################<br />
include $(CLEAR_VARS)</p>
<p>LOCAL_PATH := $(APPS_PATH)/cv/src<br />
LOCAL_C_INCLUDES := $(APPS_PATH)/cv/hdr $(APPS_PATH)/cxcore/hdr $(APPS_PATH)/stl/hdr</p>
<p>LOCAL_MODULE := cv<br />
LOCAL_SRC_FILES := cvkdtree.cpp cvaccum.cpp cvadapthresh.cpp cvapprox.cpp cvcalccontrasthistogram.cpp cvcalcimagehomography.cpp cvcalibinit.cpp cvcalibration.cpp cvcamshift.cpp cvcanny.cpp cvcolor.cpp cvcondens.cpp cvcontours.cpp cvcontourtree.cpp cvconvhull.cpp cvcorner.cpp cvcornersubpix.cpp cvderiv.cpp cvdistransform.cpp cvdominants.cpp cvemd.cpp cvfeatureselect.cpp cvfilter.cpp cvfloodfill.cpp cvfundam.cpp cvgeometry.cpp cvhaar.cpp cvhistogram.cpp cvhough.cpp cvimgwarp.cpp cvinpaint.cpp cvkalman.cpp cvlinefit.cpp cvlkpyramid.cpp cvmatchcontours.cpp cvmoments.cpp cvmorph.cpp cvmotempl.cpp cvoptflowbm.cpp cvoptflowhs.cpp cvoptflowlk.cpp cvpgh.cpp cvposit.cpp cvprecomp.cpp cvpyramids.cpp cvpyrsegmentation.cpp cvrotcalipers.cpp cvsamplers.cpp cvsegmentation.cpp cvshapedescr.cpp cvsmooth.cpp cvsnakes.cpp cvstereobm.cpp cvstereogc.cpp cvsubdivision2d.cpp cvsumpixels.cpp cvsurf.cpp cvswitcher.cpp cvtables.cpp cvtemplmatch.cpp cvthresh.cpp cvundistort.cpp cvutils.cpp dummy.cpp</p>
<p>LOCAL_STATIC_LIBRARIES := cxcore stl</p>
<p>include $(BUILD_STATIC_LIBRARY)</p>
<p>############################<br />
# cvaux<br />
############################<br />
include $(CLEAR_VARS)</p>
<p>LOCAL_PATH := $(APPS_PATH)/cvaux/src<br />
LOCAL_C_INCLUDES := $(APPS_PATH)/cvaux/hdr $(APPS_PATH)/cv/hdr $(APPS_PATH)/cv/src $(APPS_PATH)/cxcore/hdr $(APPS_PATH)/stl/hdr</p>
<p>LOCAL_MODULE := cvaux<br />
LOCAL_SRC_FILES := camshift.cpp cvaux.cpp cvauxutils.cpp cvbgfg_acmmm2003.cpp cvbgfg_codebook.cpp cvbgfg_common.cpp cvbgfg_gaussmix.cpp cvcalibfilter.cpp cvclique.cpp cvcorrespond.cpp cvcorrimages.cpp cvcreatehandmask.cpp cvdpstereo.cpp cveigenobjects.cpp cvepilines.cpp cvface.cpp cvfacedetection.cpp cvfacetemplate.cpp cvfindface.cpp cvfindhandregion.cpp cvhmm.cpp cvhmm1d.cpp cvhmmobs.cpp cvlcm.cpp cvlee.cpp cvlevmar.cpp cvlevmarprojbandle.cpp cvlevmartrif.cpp cvlines.cpp cvlmeds.cpp cvmat.cpp cvmorphcontours.cpp cvmorphing.cpp cvprewarp.cpp cvscanlines.cpp cvsegment.cpp cvsubdiv2.cpp cvtexture.cpp cvtrifocal.cpp cvvecfacetracking.cpp cvvideo.cpp decomppoly.cpp dummy.cpp enmin.cpp extendededges.cpp precomp.cpp vs/bgfg_estimation.cpp vs/blobtrackanalysis.cpp vs/blobtrackanalysishist.cpp vs/blobtrackanalysisior.cpp vs/blobtrackanalysistrackdist.cpp vs/blobtrackgen1.cpp vs/blobtrackgenyml.cpp vs/blobtrackingauto.cpp vs/blobtrackingcc.cpp vs/blobtrackingccwithcr.cpp vs/blobtrackingkalman.cpp vs/blobtrackinglist.cpp vs/blobtrackingmsfg.cpp vs/blobtrackingmsfgs.cpp vs/blobtrackpostprockalman.cpp vs/blobtrackpostproclinear.cpp vs/blobtrackpostproclist.cpp vs/enteringblobdetection.cpp vs/enteringblobdetectionreal.cpp vs/testseq.cpp</p>
<p># failed to compile<br />
#cv3dtracker.cpp</p>
<p>LOCAL_STATIC_LIBRARIES := cv cxcore stl</p>
<p>include $(BUILD_STATIC_LIBRARY)</ol>
<p>The <em>~/android_ndk_3/apps/hello-jni/Application.mk</em> file needs to be updated as follows</p>
<ol>APP_PROJECT_PATH := $(call my-dir)/project<br />
APP_MODULES      := stl cxcore cv cvaux hello-jni</ol>
<p>To build the project go to <em>~/android_ndk_3</em> and type</p>
<ol>make APP=hello-jni</ol>
<p>Of course there will be compile issues. Understand and fix them. Easiest cases are related to syntax mismatch between different compilers. In more complicated cases some code should be commented out. For example usage of libs with optimizations for Intel processor is not needed for ARM.</p>
<p>HighGui is also can be built but only partially. Simply remove files that causing problems from Android.mk. In my case the rest of files were enough to use cvLoadImage function for bmp file.</p>
<p><strong>Running facedetect openCV example</strong></p>
<p>There is no way to run native C code as separate application on Android. Instead native C functions can be called from Java apps. Because of that I made native function FaceDetect using OpenCV example application facedetect.c.</p>
<p>The declaration looks like this</p>
<ol>void<br />
Java_com_example_hellojni_HelloJni_FaceDetect( JNIEnv* env, jobject thiz, jbyteArray jyuv_buff, int w, int h, jbyteArray jbgra_buff)<br />
{<br />
&#8230;<br />
}</ol>
<p>This function takes YUV_NV21 buffer (preview from camera captured by Java app), converts it to BGRA8888, searches the faces, draws circles around the faces and returns updated RGBA8888 buffer back to Java app. Java app can draw it on the screen.</p>
<p style="text-align: center;"><a href="http://www.computer-vision-software.com/blog/wp-content/uploads/2010/04/Picture-18.jpg"><img class="aligncenter" title="Picture 18" src="http://www.computer-vision-software.com/blog/wp-content/uploads/2010/04/Picture-18-300x225.jpg" alt="" width="300" height="225" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.computer-vision-software.com/blog/2010/04/android/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>USD banknotes recognition</title>
		<link>http://www.computer-vision-software.com/blog/2009/12/usd-banknotes-recognition/</link>
		<comments>http://www.computer-vision-software.com/blog/2009/12/usd-banknotes-recognition/#comments</comments>
		<pubDate>Tue, 15 Dec 2009 11:11:22 +0000</pubDate>
		<dc:creator>Yuri Vashchenko</dc:creator>
				<category><![CDATA[Demo]]></category>
		<category><![CDATA[Demo video]]></category>
		<category><![CDATA[Demo videos]]></category>
		<category><![CDATA[OpenCV]]></category>
		<category><![CDATA[YouTube]]></category>
		<category><![CDATA[Currency recognition]]></category>
		<category><![CDATA[Object Recognition]]></category>

		<guid isPermaLink="false">http://www.computer-vision-software.com/blog/?p=110</guid>
		<description><![CDATA[The currency recognition demo application works under Windows XP, Intel P4 3GHz. Quality of recognition: 85%. The solution is cross-platform. The application was tested on Linux, ARM11 and on Linux/Windows, Intel Atom.]]></description>
			<content:encoded><![CDATA[<p><object width="425" height="355"><param name="movie" value="http://www.youtube.com/v/fyr-HuROFpk&amp;rel=0&amp;color1=0xd6d6d6&amp;color2=0xf0f0f0"></param><param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/fyr-HuROFpk&amp;rel=0&amp;color1=0xd6d6d6&amp;color2=0xf0f0f0" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355"></object></p>
<p>The currency recognition demo application works under Windows XP, Intel P4 3GHz. Quality of recognition: 85%. The solution is cross-platform. The application was tested on Linux, ARM11 and on Linux/Windows, Intel Atom.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.computer-vision-software.com/blog/2009/12/usd-banknotes-recognition/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>FAQ: OpenCV Haartraining</title>
		<link>http://www.computer-vision-software.com/blog/2009/11/faq-opencv-haartraining/</link>
		<comments>http://www.computer-vision-software.com/blog/2009/11/faq-opencv-haartraining/#comments</comments>
		<pubDate>Tue, 10 Nov 2009 06:59:44 +0000</pubDate>
		<dc:creator>rhondasw</dc:creator>
				<category><![CDATA[OpenCV]]></category>
		<category><![CDATA[face detection]]></category>
		<category><![CDATA[Haar]]></category>
		<category><![CDATA[HaarTraining]]></category>
		<category><![CDATA[Object detection]]></category>
		<category><![CDATA[OPENMP]]></category>
		<category><![CDATA[Viola-Jones]]></category>

		<guid isPermaLink="false">http://www.computer-vision-software.com/blog/?p=106</guid>
		<description><![CDATA[Hi All, before posting your question, please look at this FAQ carefully! Also you can read OpenCV haartraining article.  If you are sure, there is no answer to your question, feel free to post comment.  Also please, put comments about improvement of this post.  This post will be updated, if needed. Positive images Why positive [...]]]></description>
			<content:encoded><![CDATA[<p>Hi All, before posting your question, <span style="text-decoration: underline;">please look at this FAQ</span><span style="text-decoration: underline;"> carefully!</span> Also you can read <a title="OpenCV Haartraining" href="http://www.computer-vision-software.com/blog/2009/06/opencv-haartraining-detect-objects-using-haar-like-features/" target="_blank">OpenCV haartraining article</a>.  If you are sure, there is no answer to your question, feel free to post comment.  Also please, put comments about improvement of this post.  This post will be updated, if needed.</p>
<h1><span id="more-106"></span></h1>
<h2 style="text-align: left;"><em><span style="color: #ff9900;">Positive images</span></em></h2>
<p><em><span style="color: #ff9900;"><br />
</span></em></p>
<h3><em>Why positive images are named so?</em></h3>
<p>Because a positive image contains the target object which you want machine to detect. Unlike them, a negative image doesn&#8217;t contain such target objects.</p>
<h3><em>What&#8217;s vec file in OpenCV haartraining?</em></h3>
<p>During haartraining positive samples should have the same width and height as you define in command &#8220;-w -h size&#8221;.  So original positive images are resized  and packed as thumbs to vec file. Vec file has header: number of positive samples, width, height and contain positive thumbs in body.</p>
<h3><em><em>Is it possible to merge vec files?</em></em></h3>
<p>Yes, use Google, there are free tools, written by OpenCV&#8217;s community.</p>
<h3><em>I have  positive images, how create vec file of positive samples?</em></h3>
<p>There is tool in C:\Program Files\OpenCV\apps\HaarTraining\src createsamples.cpp.  Usage:</p>
<p>createsamples -info positive_description.txt -vec samples.vec -w 20 -h 20</p>
<h3><em>What&#8217;s positive description file?</em></h3>
<p>The matter is that, on each positive image, there can be several objects. They have bounding rectangles: x,y, width, height.  So you can write such description info of image:</p>
<p>positive_image_name  num_of_objects x y width height x y width height &#8230;</p>
<p>Text file, which contains such info about positive images is called description file. So during vec file generation,  <span style="text-decoration: underline;">really objects are packed</span>, but not whole image. Essentially vec file is needed to speed up machine learning.</p>
<h3><em>Do I always need description file, even if I have only one object on a image?</em></h3>
<p>Yes, with createsamples you need description file.  If you have only one object, it&#8217;s bounding rectangle may be bounding rectangle of whole image. If you want, write your own tool for vec file generation =)</p>
<h3><em>Should lightning conditions and background be various on positive images?</em></h3>
<p><span style="text-decoration: underline;">Yes, it&#8217;s very important</span>. On each positive image, beside object, there is background. Try to fill this background with random noise, avoid constant background.</p>
<h3><em>How much background should be on positive image?</em></h3>
<p>If you have much background pixels on your positive images in comparison with object&#8217;s pixels &#8211; it&#8217;s bad since the haartraining could remember the background as feature of positive image.</p>
<p>If you don&#8217;t have background pixels at all &#8211; it&#8217;s also bad. There should be small background frame on positive image</p>
<h3><em>Should all original positive images have the same size?</em></h3>
<p>No, original images can have any size.  But it&#8217;s important that width, height of this rectangle have the same aspect ratio as -w -h.</p>
<h3><em><em>What&#8217; s  -w and -h should I put in createsamples? Should it be always square? </em></em></h3>
<p>You can put any value to -w and -h depend on aspect ratio of the target object which you want to detect.  <span style="text-decoration: underline;">But objects of smaller size will not be detected</span>! For faces, commonly used values are 24&#215;24, 20&#215;20. But you may use 24&#215;20, 20&#215;24, etc.</p>
<h3><em>Errors during vec file generation: </em>Incorrect size of input array, 0 kb vec file,</h3>
<p>-First check you description file: positive_image_name should be <span style="text-decoration: underline;">absolute path name</span> without spaces like &#8220;C:\content\image.jpg&#8221; not &#8220;C:\con tent\image.jpg&#8221; or <span style="text-decoration: underline;">relative path name</span>.</p>
<p>-Avoid empty lines in description file</p>
<p>-Resolution of original positive image file should be not less, then -w -h parameters you put.</p>
<p>-Check that positive images are available in your file systems and not corrupted.</p>
<p>-There can be unsupported formats. Jpeg, Bmp, PPM are supported!</p>
<h3><em>Example of vec file generation!</em></h3>
<p>Let&#8217;s working directory be C:\haartraining. In it there is createsamples.exe. There is folder</p>
<p>C:\haartraining\positives. So create description file positive_desc.txt.</p>
<p>positives\image1.jpg 1 10 10 20 20</p>
<p>positives\image2.jpg 2 30 30 50 50 60 60 70 70</p>
<p>or</p>
<p>C:\haartraining\positives\image1.jpg 1 10 10 20 20</p>
<p>C:\haartraining\positives\image2.jpg 2 30 30 50 50 60 60 70 70</p>
<p>You should avoid empty lines and empty space in image&#8217;s path</p>
<p><span style="color: #0000ff;">createsamples<span style="color: #000000;"> -info positive_desc.txt -vec samples.vec -w 20 -h 20</span></span></p>
<h2 style="text-align: left;"><span style="color: #ffffff;"><em><strong><br />
</strong></em></span></h2>
<h2 style="text-align: left;"><em><span style="color: #ff9900;"><strong>Negative images</strong></span></em></h2>
<p><em><span style="color: #ff9900;"><strong><br />
</strong></span></em></p>
<h3><em>What negative images should I take?</em></h3>
<p>You can use any image of OpenCV supported formats, which does not contain target objects (which are present on positive images). But they <span style="text-decoration: underline;">should be various</span> &#8211; it&#8217;s important! Good enough database is <a href=" 	  http://tutorial-haartraining.googlecode.com/svn/trunk/data/negatives/">here</a></p>
<h3><em>Should negative images have the same size?</em></h3>
<p>No. But the size should not be less than -w -h, which were put during vec file generation.</p>
<h3><em>What&#8217;s description file for negative image? </em></h3>
<p>It&#8217;s just text file, often called negative.dat, which contains full path to negative images like:</p>
<p>image_name1.jpg</p>
<p>image_name2.jpg</p>
<p>Avoid empty lines in it.</p>
<h3><em>How many negative/positive image should I take?</em></h3>
<p>It depends on your task.  For real cascades there should be about 1000 positive images and 2000 negative images e.g.</p>
<p>Good enough proportion is  positive:negative = 1:2, but it&#8217;s not hard rule! I would recommend first to use small number of samples, generate cascade, test it, then enlarge number of samples.</p>
<h2 style="text-align: left;"><span style="color: #ff9900;"><em><strong>Launch haartraining.exe (OpenCV\apps\HaarTraining\src</strong></em></span><em><strong><em><span style="color: #ff9900;"><strong><span style="color: #ff9900;">)</span></strong></span></em></strong></em></h2>
<p><em><strong><em><span style="color: #ff9900;"><strong><span style="color: #ff9900;"><br />
</span></strong></span></em></strong></em></p>
<h3><em><em>Example of launching</em></em></h3>
<p>Working directory is C:\haartraining with haartraining.exe tool and samples.vec file.</p>
<p>Let&#8217;s negative images are in C:\haartraining\negative, in this case negative.dat should be like this:</p>
<p>negative\neg1.jpg</p>
<p>negative\neg2.jpg</p>
<p>&#8230;</p>
<p>So in C:\haartraining launch this:  <span style="color: #0000ff;">haartraining</span> -data haarcascade -vec samples.vec -bg negatives.dat -nstages 20  -minhitrate 0.999 -maxfalsealarm 0.5 -npos 1000 -nneg 2000 -w 20 -h 20 -nonsym -mem 1024</p>
<ul>
<li><span style="color: #000000;">w  h  is the same, you put during vec file generation</span></li>
<li><span style="color: #000000;">npos nneg  &#8211; number of positive samples and negative samples</span></li>
<li><span style="color: #000000;">mem &#8211; RAM memory, that program may use</span></li>
<li><span style="color: #000000;">maxfalsealarm &#8211; maximum false alarm, that stage may have. If big false alarm &#8211; it could be bad detection system<br />
</span></li>
<li><span style="color: #000000;">minhitrate &#8211; minimal hit rate, that should stage have at least<br />
</span></li>
<li><span style="color: #000000;">nstage &#8211; number of stages in cascade</span></li>
</ul>
<h3><em>What&#8217; s falsealarm and hitrate of stage?</em></h3>
<p>You should read theory of adaboost about strong classifier. Stage is <span style="text-decoration: underline;">strong classifier</span>. In short:</p>
<ul>
<li>For example you have 1000 positive samples. You want your system to detect 900 of them. So desired hitrate = 900/1000 = 0.9. <span style="text-decoration: underline;">Commonly, put minhitrate = 0.999</span></li>
<li>For example you have 1000 negative samples. Because it&#8217;s negative, you don&#8217;t want your system to detect them. But your system, because it has error, will detect some of them. Let error be about 490 samples, so false alarm = 490/1000 = 0.49. <span style="text-decoration: underline;">Commonly,put false alarm  = 0.5</span></li>
</ul>
<h3><em>Are falsealarm and hitrate depend on each other?</em></h3>
<p>Yes, <span style="color: #000000;">there is </span><span style="text-decoration: underline;">dependency</span>. You could not put <span style="color: #000000;">minhitrate = 1.0 and </span><span style="color: #000000;">maxfalsealarm = 0.0. </span>.</p>
<p>Firstly, the system builds classifier with desired hitrate, then it will calculate it&#8217;s falsealarm, if the false alarm is higher than maxfalsealarm, the system will reject such classifier and will build the next one. During haartraining you may see such:</p>
<p style="padding-left: 60px;">N |%SMP|F| ST.THR | HR | FA | EXP. ERR|<br />
+—-+—-+-+———+———+———+———+<br />
| 0 |25%|-|-1423.312590| 1.000000| 1.000000| 0.876272|</p>
<p style="padding-left: 60px;">HR &#8211; hitrate</p>
<p style="padding-left: 60px;">FA &#8211; falsealarm</p>
<h3><em>What&#8217;s falsealarm and hitrate of whole cascade?</em></h3>
<p>Cascade is linked list (or three) of stages. That&#8217;s why:</p>
<ul>
<li>False alarm of cascade = false alarm of  stage 1* false alarm of  stage 2* &#8230;</li>
<li>Hit rate = hitrate of  stage 1 * hitrate of stage 2* &#8230;</li>
</ul>
<h3><em>How many stages should be used?</em></h3>
<ul>
<li>If you set big number of stages, then you will achieve better false alarm, but it will take more time for generating cascade.</li>
<li>If you set big number of stages, then the detection time could be slower</li>
<li>If you set big number of stages, then the worse hitrate will be (0.99*0.99*&#8230; etc). <span style="text-decoration: underline;">Commonly 14-25 stages are enough</span></li>
<li>It&#8217;s useless to set many stage, if you have small number of positive, negative samples</li>
</ul>
<h3><em>What&#8217;s weighttrimming, eqw, bt, nonsym options?</em></h3>
<p>Really all these parameters are related to <a href="http://en.wikipedia.org/wiki/Adaboost">Adaboost</a>, read theory. In short:</p>
<ul>
<li>nonsym &#8211; If you positive samples are not X or Y symmetric, put -nonsym, -sym is default!</li>
<li>eqw &#8211; if you have different number of pos and neg images, it&#8217;s better to put no eqw</li>
<li>weighttrimming &#8211; for calculation optimization. It can reduce calculation time a little, but quality may be worse</li>
<li>bt &#8211; what Adaboost algorithm to use: Real AB, Gentle AB, etc.</li>
</ul>
<h3><em>What&#8217;s  minpos, nsplits, maxtreesplits options?</em></h3>
<p>These parameters are related to clustering. In Adaboost different week classifier may be used: <span style="text-decoration: underline;">stump-based</span> or <span style="text-decoration: underline;">tree-based</span>.  If you choose nsplits &gt; 0, tree-based will be used and you should set up minpos and maxtreesplits.</p>
<ul>
<li>nsplits &#8211; minimun number of nodes in tree</li>
<li>maxtreesplits &#8211; maximum number of nodes in tree. If maxtreesplits &lt; nsplits,  tree will not be built</li>
<li>minpos &#8211; number of positive images, that can be used by one node during training.  All positive images are splitted between nodes. Generally minpos  should be not less than  npos/nsplits.</li>
</ul>
<h3><em>Errors and stranges during haartraining!</em></h3>
<ul>
<li>Error (valid only for Discrete and Real AdaBoost): misclass &#8211; it&#8217;s warning, but no error.  Some options are specific to D and R Adaboost.  So your haartraining is ok.</li>
<li>Screen is filled with such | 1000 |25%|-|-1423.312590| 1.000000| 1.000000| 0.876272| &#8211; your training is cycled, restart it. First column should have value &lt; 100</li>
<li>cvAlloc fails. Our of memory &#8211; you give too much negative images or sample.vec is too big. All these pictures are loaded to RAM.</li>
<li>Pay attention you put the same -w and -h, as during vec file generation</li>
<li>Pay attention, that number of positive samples and negative samples, you put in -npos -nneg are really available</li>
<li>Avoid empty line in negative.dat file</li>
<li>Required leaf false alarm rate achieved. Branch training terminated &#8211; it&#8217;s impossible to build classifier with good false alarm on this negative images. Check your negative images are really negative =),  maxfalsealarm should be in [0.4-0.5]</li>
</ul>
<h2 style="text-align: left;"><span style="color: #ff9900;"><em><strong>OpenCV XML haarcascade</strong></em></span></h2>
<p><span style="color: #ff9900;"><em><strong><br />
</strong></em></span></p>
<h3><em>During haartraining, there are txt file in haarcascade folder, how can we get XML  from them?</em></h3>
<p>There is OpenCV/samples/c/convert_cascade.c. Use like:</p>
<p><span style="color: #0000ff;">convert_cascade</span> &#8211;size=&#8221;20&#215;20&#8243; haarcascade haarcascade.xml</p>
<h3><em>How can I test generated XML cascade?<br />
</em></h3>
<p style="text-align: left;"><span style="color: #ff9900;"><em><strong> </strong></em></span><span style="color: #ff9900;"><span style="color: #000000;">There is </span></span>OpenCv/apps/HaarTraining/src<strong><span style="color: #ff9900;"><strong><span style="color: #000000;"> </span></strong></span></strong>/perfomance.cpp. You need have positive images(not used during training) and positive description file.  Use like:</p>
<p><span style="color: #0000ff;">performance</span> -data haarcascade -w 20 -h 20 -info positive_description.txt -ni</p>
<p><span style="color: #0000ff;">performance </span>-data haarcascade.xml -info positive_description.txt -ni</p>
<h2 style="text-align: left;"><span style="color: #ff9900;"><em><strong><em><strong>Time and Speed of haar cascade generation</strong></em></strong></em></span></h2>
<p><span style="color: #ff9900;"><em><strong><em><strong><br />
</strong></em></strong></em></span></p>
<h3><em>Average time to generate cascade on PC?</em></h3>
<p>It depends on task and your machine.  I generated cascade for face detection, for this used such parameters: -nstages 20 -minhitrate 0.999 -maxfalsealarm 0.5 -npos 4000 -nneg 5000 -w 20 -h 20 -nonsym -mem 1024.  It took <span style="color: #ff0000;">6 days</span> on Pentium 2.7GHZ 2GB RAM.</p>
<h3><em>What is <a href="http://en.wikipedia.org/wiki/OpenMP">OpenMP</a>?</em></h3>
<p>&#8220;<em>The <strong>OpenMP</strong> (Open Multi-Processing) is an <a title="Application programming interface" href="http://en.wikipedia.org/wiki/Application_programming_interface">application programming interface</a> (API) that supports multi-platform <a title="Shared memory" href="http://en.wikipedia.org/wiki/Shared_memory">shared memory</a> <a title="Multiprocessing" href="http://en.wikipedia.org/wiki/Multiprocessing">multiprocessing</a> programming in <a title="C (programming language)" href="http://en.wikipedia.org/wiki/C_%28programming_language%29">C</a>, <a title="C++" href="http://en.wikipedia.org/wiki/C%2B%2B">C++</a> and <a title="Fortran" href="http://en.wikipedia.org/wiki/Fortran">Fortran</a> on many architectures, including <a title="Unix" href="http://en.wikipedia.org/wiki/Unix">Unix</a> and <a title="Microsoft Windows" href="http://en.wikipedia.org/wiki/Microsoft_Windows">Microsoft Windows</a> platforms</em>&#8220;. If you have MT processor, you can use it.  In code you should add OpenMP defines and put compile options.  For example in VisualStudio2005: Properties-&gt;C/C++-&gt;Language-&gt;OpenMP support</p>
<h3><em>Is it possible to improve speed of haartraining?</em></h3>
<p>Yes, one of possible ways is to use parallel programming. We have realized OpenCV haartraining using MPI for linux cluster. You can read it <a href="http://www.computer-vision-software.com/blog/2009/06/parallel-world-of-opencv/">here</a></p>
<h2><span style="color: #ff9900;"><em><strong>Object detection with OpenCV XML cascades</strong></em></span></h2>
<p><span style="color: #ff9900;"><em><strong><br />
</strong></em></span></p>
<h3><em>Is it possible to detect rotated faces?</em></h3>
<p>Yes. It is impossible to generate cascade, which can detect face in all orientations. But you can generate cascade for each orientation separately. For this you need positive content of rotated faces. You can try to generate cascade with OpenCV , add -mode ALL, with it tilted haar feature will be used. But it&#8217;s badly implemented, at least in OpenCV 1.1. If you want you can add your own feature to opencv haartraining &#8211; it&#8217;s not too hard.</p>
<p>Another approach is to write head pose estimator. Then rotate your pictures, so that you have frontal face and detect it with OpenCV default face cascade</p>
<h3><em>Is it possible to recognize gender, attention, race with  Haar features?</em></h3>
<p>We tried, but could not do it with OpenCV haartraining. That&#8217;s why for such classification, we used our own <a href="http://www.computer-vision-software.com/blog/2009/07/gender-detection/" target="_blank">gender </a>and <a href="http://www.computer-vision-software.com/blog/2009/11/detect-attention-please/">attention</a> classificators. Of course you can use Adaboost for this task, which is implemented in haartraining, but we did not get good results.</p>
<h3><em>Is it possible to detect faces in real time?</em></h3>
<p>Yes.  On PC default OpenCV facedetector takes about 200 ms for 640&#215;480 picture, about 5fps &#8211; it&#8217;s not real time. We have changed facedetector and get about 15 fps &#8211; which is real time. You can see results  <a href="http://www.computer-vision-software.com/blog/2009/06/fastfurious-face-detection-with-opencv/" target="_blank">here</a> and <a href="http://www.computer-vision-software.com/blog/2009/10/audience-measurement-face-tracker-gender-recognition-attention-recognition-etc/" target="_blank">here</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.computer-vision-software.com/blog/2009/11/faq-opencv-haartraining/feed/</wfw:commentRss>
		<slash:comments>53</slash:comments>
		</item>
		<item>
		<title>Detect attention, please!</title>
		<link>http://www.computer-vision-software.com/blog/2009/11/detect-attention-please/</link>
		<comments>http://www.computer-vision-software.com/blog/2009/11/detect-attention-please/#comments</comments>
		<pubDate>Mon, 09 Nov 2009 01:13:35 +0000</pubDate>
		<dc:creator>rhondasw</dc:creator>
				<category><![CDATA[OpenCV]]></category>
		<category><![CDATA[Attention classifier]]></category>
		<category><![CDATA[Machine learning]]></category>
		<category><![CDATA[SVM]]></category>
		<category><![CDATA[Viola-Jones]]></category>

		<guid isPermaLink="false">http://www.computer-vision-software.com/blog/?p=100</guid>
		<description><![CDATA[Nowadays, different audience measurement systems become more and more popular. They are used in active advertising, for gathering statistics, etc. One of the key features of these smart systems is attention detection.  For advertisers, for instance,  it seems very  important to know, how much attention commercial attracts. In this article, I will describe attention detector [...]]]></description>
			<content:encoded><![CDATA[<p style="padding-left: 30px;">Nowadays, different audience measurement systems become more and more popular. They are used in active advertising, for gathering statistics, etc. One of the key features of these smart systems is <strong>attention detection</strong>.  For advertisers, for instance,  it seems very  important to know, how much attention commercial attracts. In this article, I will describe attention detector module, used in our <a href="http://www.computer-vision-software.com/blog/2009/10/audience-measurement-face-tracker-gender-recognition-attention-recognition-etc/" target="_blank">Audience Measurement system</a>.</p>
<p><span id="more-100"></span></p>
<p>We started our work with attempts to understand, what attention we want to detect.  On the one hand, It seems very easy  to say, if person has attention or not.  On the other hand,  it&#8217;s very difficult to formalize: <strong>What attention is</strong>.  In some articles, it&#8217;s considered to detect attention based on <em>eyes information</em>.  But if person wears sunglasses? Another &#8220;criteria&#8221; is to to use <em>nose information</em>: Where nose points at! For our business case nose information is not enough either. More over, nose can also be &#8220;hidden&#8221;.</p>
<p>That&#8217;s why our attention is based on <strong>head pose information</strong>. We collected face images, which in our opinion, have attention and don&#8217;t have attention.  To be honest, most of images with attention were <em>frontal faces</em> and vice versa.  These two sets resolve task.</p>

<a href='http://www.computer-vision-software.com/blog/2009/11/detect-attention-please/nonatt/' title='nonatt'><img width="150" height="150" src="http://www.computer-vision-software.com/blog/wp-content/uploads/2009/11/nonatt-150x150.jpg" class="attachment-thumbnail" alt="nonatt" title="nonatt" /></a>
<a href='http://www.computer-vision-software.com/blog/2009/11/detect-attention-please/attention-2/' title='attention'><img width="150" height="150" src="http://www.computer-vision-software.com/blog/wp-content/uploads/2009/11/attention1-150x150.jpg" class="attachment-thumbnail" alt="attention" title="attention" /></a>

<p>To teach machine to detect attention , we need a machine learning algorithm. We have Viola Jones one and if it can detect face/non face, why not use it to detect attention/non attention? Learning samples we have&#8230; So with Adabost, we chose 100 Haar-like features. With them, each image is converted to 100-dimensional vector.  To classify it, we used C4.5.  Self-test was very good: 97% accuracy.  But when started testing on real video, we had bad result: 60% accuracy. The problems begun, when  <span style="text-decoration: underline;">lightning conditions were modified</span> or <span style="text-decoration: underline;">face shifted some pixels</span>, even despite the fact that, we used normalization like in OpenCV Viola Jones algorithm. The matter is that, face and non-face images are very different, but faces with attention and with non-attention are very similar.</p>
<p>Thus, we needed <strong>lightning-invariant method</strong>, which is not so sensitive to XY-shifting.  We developed our own template-matching method.  First, using PCA, we get templates of face. With these templates, each face is  converted to N-dimensional vector, which is classified with SVM. Accuracy of our attention system is about <strong>90%</strong>.  Its working you can see in our <a href="../2009/10/audience-measurement-face-tracker-gender-recognition-attention-recognition-etc/" target="_blank">Audience Measurement system</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.computer-vision-software.com/blog/2009/11/detect-attention-please/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Object Recognition (Nike logo)</title>
		<link>http://www.computer-vision-software.com/blog/2009/10/object-recognition-nike-logo/</link>
		<comments>http://www.computer-vision-software.com/blog/2009/10/object-recognition-nike-logo/#comments</comments>
		<pubDate>Thu, 22 Oct 2009 09:43:40 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[Demo]]></category>
		<category><![CDATA[Demo video]]></category>
		<category><![CDATA[Demo videos]]></category>
		<category><![CDATA[OpenCV]]></category>
		<category><![CDATA[YouTube]]></category>
		<category><![CDATA[ARM]]></category>
		<category><![CDATA[Object detection]]></category>
		<category><![CDATA[Object Recognition]]></category>

		<guid isPermaLink="false">http://www.computer-vision-software.com/blog/?p=98</guid>
		<description><![CDATA[nike.avi This is a demo video of the invariant orientation and scale fast object detection algorithm. The algorithm is a robust in cases when the object is deformed a little The algorithm is a cross-platform solution. Performance: on ARM11 530MHz, the algorithm gives 1 fps for 640&#215;480 frame; on Intel P4 3Hz, the algorithm gives 12 fps and more for 640&#215;480 frame. [...]]]></description>
			<content:encoded><![CDATA[<p><object width="425" height="355"><param name="movie" value="http://www.youtube.com/v/Hgb5IFd2QPY&amp;rel=0&amp;color1=0xd6d6d6&amp;color2=0xf0f0f0"></param><param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/Hgb5IFd2QPY&amp;rel=0&amp;color1=0xd6d6d6&amp;color2=0xf0f0f0" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355"></object></p>
<p><a href="http://www.computer-vision-software.com/files/videos/nike.avi">nike.avi</a></p>
<p>This is a demo video of the invariant orientation and scale fast object detection algorithm. The algorithm is a robust in cases when the object is deformed a little <img src='http://www.computer-vision-software.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p><span id="more-98"></span></p>
<p>The algorithm is a cross-platform solution.</p>
<p><strong>Performance</strong>:</p>
<ul>
<li>on ARM11 530MHz, the algorithm gives 1 fps for 640&#215;480 frame;</li>
<li>on Intel P4 3Hz, the algorithm gives 12 fps and more for 640&#215;480 frame.</li>
</ul>
<p><strong>Quality</strong>: 86%.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.computer-vision-software.com/blog/2009/10/object-recognition-nike-logo/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
<enclosure url="http://www.computer-vision-software.com/files/videos/nike.avi" length="21383022" type="video/x-msvideo" />
		</item>
		<item>
		<title>Audience Measurement (face tracker, gender recognition, attention recognition, etc)</title>
		<link>http://www.computer-vision-software.com/blog/2009/10/audience-measurement-face-tracker-gender-recognition-attention-recognition-etc/</link>
		<comments>http://www.computer-vision-software.com/blog/2009/10/audience-measurement-face-tracker-gender-recognition-attention-recognition-etc/#comments</comments>
		<pubDate>Mon, 05 Oct 2009 08:23:13 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[Demo]]></category>
		<category><![CDATA[Demo video]]></category>
		<category><![CDATA[Demo videos]]></category>
		<category><![CDATA[OpenCV]]></category>
		<category><![CDATA[YouTube]]></category>
		<category><![CDATA[Demography]]></category>
		<category><![CDATA[Demography classifier]]></category>
		<category><![CDATA[face detection]]></category>
		<category><![CDATA[Face tracker]]></category>
		<category><![CDATA[Gender recognition]]></category>
		<category><![CDATA[Object Tracking]]></category>

		<guid isPermaLink="false">http://www.computer-vision-software.com/blog/?p=91</guid>
		<description><![CDATA[am-3.avi This is a demo video of Rhonda Audience Measurement system (MyAudience product, www.MyAudience.com). The system is able to recognize gender of a person. So, red rectangle is for a woman, dark blue rectangle is for a man. The quality of gender recognition algorithm is 90%. The system works on Intel Atom: 10 fps and higher, and [...]]]></description>
			<content:encoded><![CDATA[<p><object width="425" height="355"><param name="movie" value="http://www.youtube.com/v/cPEGXJAvy0Q&amp;rel=0&amp;color1=0xd6d6d6&amp;color2=0xf0f0f0"></param><param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/cPEGXJAvy0Q&amp;rel=0&amp;color1=0xd6d6d6&amp;color2=0xf0f0f0" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355"></object></p>
<p><a href="http://www.computer-vision-software.com/files/videos/am-3.avi">am-3.avi</a></p>
<p>This is a demo video of Rhonda Audience Measurement system (MyAudience product, <a href="http://www.MyAudience.com">www.MyAudience.com</a>).</p>
<p><span id="more-91"></span></p>
<p>The system is able to recognize gender of a person. So, red rectangle is for a woman, dark blue rectangle is for a man. The quality of gender recognition algorithm is 90%.</p>
<p>The system works on Intel Atom: 10 fps and higher, and on Intel Pentium 4: 15 fps and higher. Besides, it is a cross-platform solution. It was tested on both Windows XP and Linux, and also it was tested on ARM Cortext-A8.</p>
<p>No accelerations (CUDA, fixed point, etc) are used! So, the solution has great potential for improvements.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.computer-vision-software.com/blog/2009/10/audience-measurement-face-tracker-gender-recognition-attention-recognition-etc/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
<enclosure url="http://www.computer-vision-software.com/files/videos/am-3.avi" length="26675290" type="video/x-msvideo" />
		</item>
		<item>
		<title>Cross-platform solution for getting MJPEG stream from AXIS ip-camera (AXIS 211M)</title>
		<link>http://www.computer-vision-software.com/blog/2009/08/cross-platform-solution-for-getting-mjpeg-stream-from-axis-ip-camera-axis-211m/</link>
		<comments>http://www.computer-vision-software.com/blog/2009/08/cross-platform-solution-for-getting-mjpeg-stream-from-axis-ip-camera-axis-211m/#comments</comments>
		<pubDate>Sat, 29 Aug 2009 07:55:42 +0000</pubDate>
		<dc:creator>Andrew Chen</dc:creator>
				<category><![CDATA[OpenCV]]></category>
		<category><![CDATA[ARM]]></category>
		<category><![CDATA[IpCamera]]></category>
		<category><![CDATA[IplImage]]></category>
		<category><![CDATA[MJPEG]]></category>

		<guid isPermaLink="false">http://www.computer-vision-software.com/blog/?p=86</guid>
		<description><![CDATA[This paper describes how-to get MJPEG stream from AXIS ip-camera in your C++ application. My approach is a cross-platform solution and much better than solution from http://www.computer-vision-software.com/blog/2009/04/how-to-get-mjpeg-stream-from-axis-ip-cameras-axis-211m-and-axis-214-ptz-as-camera-device-in-opencv-using-directshow/. Dependencies We used boost library (boost/asio, http://www.boost.org). There are very useful network interfaces: boost::asio::io_service: the io_service class provides the core I/O functionality for users of the asynchronous I/O objects; [...]]]></description>
			<content:encoded><![CDATA[<div style="text-align: left;">
<p style="text-align: left;">This paper describes how-to get MJPEG stream from AXIS ip-camera in your C++ application. My approach is a cross-platform solution and much better than solution from <a href="http://www.computer-vision-software.com/blog/2009/04/how-to-get-mjpeg-stream-from-axis-ip-cameras-axis-211m-and-axis-214-ptz-as-camera-device-in-opencv-using-directshow/">http://www.computer-vision-software.com/blog/2009/04/how-to-get-mjpeg-stream-from-axis-ip-cameras-axis-211m-and-axis-214-ptz-as-camera-device-in-opencv-using-directshow/</a>.</p>
<p><span id="more-86"></span></p>
<p><strong>Dependencies</strong></p>
<p>We used boost library (boost/asio, <a href="http://www.boost.org/">http://www.boost.org</a>). There are very useful network interfaces:</p>
<ul>
<li><span style="color: #003366;"><em><strong>boost::asio::io_service</strong>: </em><span style="color: #000000;">the </span></span>io_service class provides the core I/O functionality for users of the asynchronous I/O objects;</li>
<li><span style="color: #003366;"><strong><em>boost::asio::ip::tcp::socket</em></strong>: <span style="color: #000000;">the </span></span>socket class has a function that will retrieve the remote endpoint;</li>
<li><span style="color: #003366;"><strong><em>boost::asio::ip::tcp::resolver</em></strong>:</span> the resolver class init net-connection.</li>
</ul>
<p><strong>Network interface implementing</strong></p>
<p>I created few useful network functions over &#8221;boost::asio&#8221;: connecting, sending and receiving packets.</p>
<p>The network interface will be implemented via boost objects. Definitions are:</p>
<p><span style="color: #003366;"><em><strong>boost::asio::io_service</strong> m_ios;<br />
<strong>boost::asio::ip::tcp::socket</strong> m_socket(m_ios);<br />
<strong>boost::asio::ip::tcp::resolver</strong> m_resolver(m_ios);</em></span></p>
<p>So, the functions like:</p>
<pre class="python:nogutter">void connect(void)
{
    boost::asio::ip::tcp::resolver::iterator   end_point;
    boost::system::error_code                   ecode;
    boost::asio::ip::tcp::resolver::query     query(boost::asio::ip::tcp::v4(),
                                                                   “192.168.0.1”, “80”);

    end_point = m_resolver.resolve(query);
    m_socket.connect(*iterator, ecode);

    assert(!ecode);
}

int send(void *buffer, int buf_size)
{
    boost::system::error_code   ecode;
    boost::uint32_t                  sent_size = 0;

    sent_size = boost::asio::write(m_socket,
                                             boost::asio::buffer(buffer, buffer_size),
                                             boost::asio::transfer_all(),
                                             ecode);
    if(ecode)
        printf("socket write operation failed\n");

    return sent_size;
}

int receive(void *buffer, int buf_size)
{
    boost::system::error_code   ecode;
    int                                   received_size = 0;

    received_size = boost::asio::read(m_socket,
                                                  boost::asio::buffer(buffer, buffer_size),
                                                  boost::asio::transfer_at_least(1),
                                                  ecode);

    if(ecode)
        printf("socket read operation failed\n");

    return received_size;
}</pre>
<p>Also there is disconnect function, it is written in the same manner.</p>
<p><em>Note: this is reductive version of code for better interpretation. </em></p>
<p><strong>Getting JPEG frame from ip camera<br />
</strong></p>
<p>We should send request to the camera for getting mjpeg stream. The command like:</p>
<p><span style="color: #003366;"><em>“GET /axis-cgi/mjpg/video.cgi?resolution=&lt;width&gt;x&lt;height&gt;&amp;fps=&lt;fps&gt;\r\n\r\n”,</em></span></p>
<p>where:</p>
<ul>
<li><span style="color: #003366;"><em><strong>&lt;width&gt;</strong></em></span> &#8211; width of requested frame;</li>
<li><span style="color: #003366;"><em><strong>&lt;height&gt;</strong></em></span> &#8211; height of requested frame;</li>
<li><span style="color: #003366;"><em><strong>&lt;fps&gt;</strong></em></span> &#8211; the requested number of frames per second;</li>
<li><em><span style="color: #003366;"><strong>“\r\n\r\n</strong>”</span></em> – end marker of request.</li>
</ul>
<p>Example is:</p>
<p><span style="color: #003366;"><em>“GET /axis-cgi/mjpg/video.cgi?resolution=640&#215;480&amp;fps=15\r\n\r\n”</em></span></p>
<p>The device sends response: 183 bytes. We need to check the response to make sure that is ok.</p>
<p>E.g. successful response:</p>
<p><span style="color: #003366;"><em>“HTTP/1.0 200 OK\r\nCache-Control: no-cache\r\nPragma: no-cache\r\nExpires: Thu, 01 Dec 1994 16:00:00 GSM\r\nConnection: close\r\nContent-Type: multipart/x-mixed-replace; boundary=&#8211;myboundary”</em></span></p>
<p>E.g. unsuccessful response:</p>
<p><em><span style="color: #003366;">“HTTP/1.0 501 Not implemented\r\nDate: Sat, 29 Aug 2009 14:00:10 GSM\r\nAccept-Ranges: bytes\r\nConnection: close\r\n…”</span></em></p>
<p>As you can see, the successful response must contain <span style="color: #003366;"><em>“HTTP/1.0 200 OK”</em></span> string at beginning.</p>
<p>The value of “boundary” (<span style="color: #003366;"><em>“&#8211;myboundary”</em></span>) field is most important, because this string will be used as separator further.</p>
<p>The frame will be received part by part. The first packet size is 67 bytes it is meta-information. E.g.:</p>
<p><span style="color: #003366;"><em>“&#8211;myboundary\r\nContent-Type: image/jpeg\r\nContent-Length: 56296\r\n\r\n”</em></span></p>
<p><span style="color: #003366;"><em>“&#8211;myboundary”</em></span> string at the begin is confirmation of beginning of new frame. Also, we should read and save value of the field <span style="color: #003366;"><em>“Content-Length”</em></span> (56296). It is size of  compressed jpeg frame. The second and following packets are jpeg-picture essentially. We receive few packets with jpg data and save each packet to memory buffer and calculate total size of received packets, and if the total size is equal to value<em> </em>of <em><span style="color: #003366;">“Content-Length”</span></em>, it means that full picture is received and the memory buffer contains it. Now, you can save the memory buffer to the disc-storage (into “123.jpg” file e.g.), and open it with any graphic-viewer and make sure that is usual jpg image.</p>
<p>Note: the jpeg picture should contain the end marker<span style="color: #003366;"><em> “\r\n”</em></span> (2 bytes), so I recommend you to receive 2 bytes more.</p>
<p>Next frame can be received with the same aproach: the first package size is 67 bytes…</p>
<p>Note:  symbols <span style="color: #003366;"><em>“\r\n”</em></span> – 2 byte 0x0A and 0x0D accordingly.</p>
<p>Also, I recommend to develop separated thread for getting JPG frames from ip camera in order to avoid losing of connection&#8230;</p>
<p>We tested this solution under MS Windows, Linux, Intel P4 and also under Intel Atom and ARM Cortex-A8. All works fine.</p>
<p>We are using this approach in my module which decodes each JPG frame from Axis camera and convertes it to OpenCV IplImage (BGR frame).</p>
<p>P.S. Besides, we developed solutions for Arecont and ACTi ip-cameras. Sure, the implementations are different, but common idea is the same.</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.computer-vision-software.com/blog/2009/08/cross-platform-solution-for-getting-mjpeg-stream-from-axis-ip-camera-axis-211m/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Fast &amp; Furious face detection with OpenCV</title>
		<link>http://www.computer-vision-software.com/blog/2009/06/fastfurious-face-detection-with-opencv/</link>
		<comments>http://www.computer-vision-software.com/blog/2009/06/fastfurious-face-detection-with-opencv/#comments</comments>
		<pubDate>Thu, 18 Jun 2009 04:06:49 +0000</pubDate>
		<dc:creator>rhondasw</dc:creator>
				<category><![CDATA[OpenCV]]></category>
		<category><![CDATA[ARM]]></category>
		<category><![CDATA[face detection]]></category>
		<category><![CDATA[Haar]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Viola-Jones]]></category>

		<guid isPermaLink="false">http://www.computer-vision-software.com/blog/?p=75</guid>
		<description><![CDATA[In OpenCV/Samples there is  facedetect program.  This program can detect  faces on images and video.  It&#8217;s very fun, but its speed leaves much to be desired =(.  Of course  with OpenMP,  it works  faster; on Intel Core Duo 2.7GHZ, it works fast;  but will it work fast on ARM? I have big doubts.  I compiled [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify; padding-left: 30px;">In OpenCV/Samples there is  facedetect program.  This program can detect  faces on images and video.  It&#8217;s very fun, but its speed leaves much to be desired =(.  Of course  with OpenMP,  it works  faster; on Intel Core Duo 2.7GHZ, it works fast;  but will it work fast on ARM? I have big doubts.  I compiled facedetect without OpenMP and on average it takes 600 ms for 640&#215;480 resolution to find one face.   I wanted to find out, if it&#8217;s possible to improve this time by software means or not&#8230;  After some investigations, code refactoring and improvements, facedetect started to work <strong>2.5 time faster</strong>, even on ARM.  Of course, <strong>without big quality loss</strong> =)</p>
<p><span id="more-75"></span></p>
<p style="text-align: justify;">I started investigation with profiling cvHaarDetectObjects on 640&#215;480 image.  Function cvRunHaarClassifierCascade tooks <span style="text-decoration: underline;">70% of computation time</span>.  But cvRunHaarClassifierCascade is not so heavy, why it takes so much time? Scanning 20&#215;20 window is moved on X-direction and Y-direction and Scale-direction and on each scanning window, cvRunHaarClassifierCascade is called.  Totally we have <strong>160000</strong> calls!</p>
<p>So to reduce time, we need <span style="text-decoration: underline;">optimize this triple cycle</span>.  I know several ways:</p>
<ol>
<li>change parameters in cvHaarDetectObjects function.  Sometimes, it really helps, but let&#8217;s resort to such shamanism another time.   I used &#8220;default&#8221; parameters: <em>1.1 scale factor, 20&#215;20 window</em>.</li>
<li>use fixed point in algorithm.  We did it <a title="here" href="http://www.computer-vision-software.com/blog/2009/04/fixing-opencv/" target="_blank">here</a></li>
<li>optimize OpenCV default frontal face cascade.  <a title="Cascade generation" href="http://www.computer-vision-software.com/blog/2009/06/parallel-world-of-opencv/" target="_blank">Cascade generation</a> takes much time and who knows, will it be good or not =)</li>
<li>somehow reduce number of cvRunHaarClassifierCascade calls.  Image contains only several real faces, not 160000 &#8211; so all this makes sence.</li>
</ol>
<p>We have researched a lot of approaches and combination of ways above and got the result (Intel Core Duo 2.7GHZ):</p>
<p><img class="aligncenter size-full wp-image-80" title="2" src="http://www.computer-vision-software.com/blog/wp-content/uploads/2009/06/22.JPG" alt="2" width="775" height="395" /></p>
<div id="_mcePaste" style="overflow: hidden; position: absolute; width: 1px; height: 1px; top: 288px; left: -10000px;">
<table style="width: 440pt; border-collapse: collapse;" border="0" cellspacing="0" cellpadding="0" width="587">
<colgroup span="1">
<col style="width: 116pt;" span="1" width="155"></col>
<col style="width: 54pt;" span="6" width="72"></col>
</colgroup>
<tbody>
<tr style="height: 75pt;" height="100">
<td class="xl65" style="width: 116pt; height: 75pt;" width="155" height="100"></td>
<td class="xl66" style="border-left: medium none; width: 162pt;" colspan="3" width="216">Original face detect</td>
<td class="xl66" style="border-left: medium none; width: 162pt;" colspan="3" width="216">Fast face detect</td>
</tr>
<tr style="height: 22.5pt;" height="30">
<td class="xl67" style="border-top: medium none; height: 22.5pt;" height="30"></td>
<td class="xl68" style="border-top: medium none; border-left: medium none; width: 54pt;" width="72">ColorFERET<br />
frontal</td>
<td class="xl68" style="border-top: medium none; border-left: medium none; width: 54pt;" width="72">LabeledFaces<br />
InTheWild</td>
<td class="xl68" style="border-top: medium none; border-left: medium none; width: 54pt;" width="72">NoFaces<br />
(Negative)</td>
<td class="xl68" style="border-top: medium none; border-left: medium none; width: 54pt;" width="72">ColorFERET<br />
frontal</td>
<td class="xl68" style="border-top: medium none; border-left: medium none; width: 54pt;" width="72">LabeledFaces<br />
InTheWild</td>
<td class="xl68" style="border-top: medium none; border-left: medium none; width: 54pt;" width="72">NoFaces<br />
(Negative)</td>
</tr>
<tr style="height: 30pt;" height="40">
<td class="xl65" style="border-top: medium none; height: 30pt;" height="40"></td>
<td class="xl69" style="border-top: medium none; border-left: medium none;">512&#215;768</td>
<td class="xl69" style="border-top: medium none; border-left: medium none;">250&#215;250</td>
<td class="xl70" style="border-top: medium none; border-left: medium none; width: 54pt;" width="72">up to<br />
1280&#215;1024</td>
<td class="xl69" style="border-top: medium none; border-left: medium none;">512&#215;768</td>
<td class="xl69" style="border-top: medium none; border-left: medium none;">250&#215;250</td>
<td class="xl70" style="border-top: medium none; border-left: medium none; width: 54pt;" width="72">up to<br />
1280&#215;1024</td>
</tr>
<tr style="height: 15pt;" height="20">
<td class="xl65" style="border-top: medium none; height: 15pt;" height="20"></td>
<td class="xl69" style="border-top: medium none; border-left: medium none;"></td>
<td class="xl69" style="border-top: medium none; border-left: medium none;"></td>
<td class="xl69" style="border-top: medium none; border-left: medium none;"></td>
<td class="xl69" style="border-top: medium none; border-left: medium none;"></td>
<td class="xl69" style="border-top: medium none; border-left: medium none;"></td>
<td class="xl69" style="border-top: medium none; border-left: medium none;"></td>
</tr>
<tr style="height: 15pt;" height="20">
<td class="xl65" style="border-top: medium none; height: 15pt;" height="20">Total</td>
<td class="xl69" style="border-top: medium none; border-left: medium none;">5444</td>
<td class="xl69" style="border-top: medium none; border-left: medium none;">1872</td>
<td class="xl69" style="border-top: medium none; border-left: medium none;">1748</td>
<td class="xl69" style="border-top: medium none; border-left: medium none;">5276</td>
<td class="xl69" style="border-top: medium none; border-left: medium none;">1872</td>
<td class="xl69" style="border-top: medium none; border-left: medium none;">1748</td>
</tr>
<tr style="height: 15pt;" height="20">
<td class="xl65" style="border-top: medium none; height: 15pt;" height="20"></td>
<td class="xl69" style="border-top: medium none; border-left: medium none;"></td>
<td class="xl69" style="border-top: medium none; border-left: medium none;"></td>
<td class="xl69" style="border-top: medium none; border-left: medium none;"></td>
<td class="xl69" style="border-top: medium none; border-left: medium none;"></td>
<td class="xl69" style="border-top: medium none; border-left: medium none;"></td>
<td class="xl69" style="border-top: medium none; border-left: medium none;"></td>
</tr>
<tr style="height: 15pt;" height="20">
<td class="xl65" style="border-top: medium none; height: 15pt;" height="20">Fount</td>
<td class="xl69" style="border-top: medium none; border-left: medium none;">5420</td>
<td class="xl69" style="border-top: medium none; border-left: medium none;">1765</td>
<td class="xl69" style="border-top: medium none; border-left: medium none;"></td>
<td class="xl69" style="border-top: medium none; border-left: medium none;">5191</td>
<td class="xl69" style="border-top: medium none; border-left: medium none;">1685</td>
<td class="xl69" style="border-top: medium none; border-left: medium none;"></td>
</tr>
<tr style="height: 15pt;" height="20">
<td class="xl71" style="border-top: medium none; height: 15pt;" height="20">Hit rate</td>
<td class="xl72" style="border-top: medium none; border-left: medium none;">99,6%</td>
<td class="xl72" style="border-top: medium none; border-left: medium none;">94,3%</td>
<td class="xl72" style="border-top: medium none; border-left: medium none;"></td>
<td class="xl72" style="border-top: medium none; border-left: medium none;">98,4%</td>
<td class="xl72" style="border-top: medium none; border-left: medium none;">90,0%</td>
<td class="xl72" style="border-top: medium none; border-left: medium none;"></td>
</tr>
<tr style="height: 15pt;" height="20">
<td class="xl65" style="border-top: medium none; height: 15pt;" height="20">FP (incorrect found)</td>
<td class="xl69" style="border-top: medium none; border-left: medium none;">57</td>
<td class="xl69" style="border-top: medium none; border-left: medium none;">12</td>
<td class="xl69" style="border-top: medium none; border-left: medium none;">37</td>
<td class="xl69" style="border-top: medium none; border-left: medium none;">18</td>
<td class="xl69" style="border-top: medium none; border-left: medium none;">10</td>
<td class="xl69" style="border-top: medium none; border-left: medium none;">13</td>
</tr>
<tr style="height: 15pt;" height="20">
<td class="xl73" style="border-top: medium none; height: 15pt;" height="20">False alarm rate</td>
<td class="xl74" style="border-top: medium none; border-left: medium none;"></td>
<td class="xl74" style="border-top: medium none; border-left: medium none;"></td>
<td class="xl72" style="border-top: medium none; border-left: medium none;">2,1%</td>
<td class="xl69" style="border-top: medium none; border-left: medium none;"></td>
<td class="xl69" style="border-top: medium none; border-left: medium none;"></td>
<td class="xl72" style="border-top: medium none; border-left: medium none;">0,7%</td>
</tr>
<tr style="height: 15pt;" height="20">
<td class="xl65" style="border-top: medium none; height: 15pt;" height="20">FN (not found)</td>
<td class="xl69" style="border-top: medium none; border-left: medium none;">23</td>
<td class="xl69" style="border-top: medium none; border-left: medium none;">107</td>
<td class="xl69" style="border-top: medium none; border-left: medium none;"></td>
<td class="xl69" style="border-top: medium none; border-left: medium none;">85</td>
<td class="xl69" style="border-top: medium none; border-left: medium none;">187</td>
<td class="xl69" style="border-top: medium none; border-left: medium none;"></td>
</tr>
<tr style="height: 15pt;" height="20">
<td class="xl65" style="border-top: medium none; height: 15pt;" height="20"></td>
<td class="xl69" style="border-top: medium none; border-left: medium none;"></td>
<td class="xl69" style="border-top: medium none; border-left: medium none;"></td>
<td class="xl69" style="border-top: medium none; border-left: medium none;"></td>
<td class="xl69" style="border-top: medium none; border-left: medium none;"></td>
<td class="xl69" style="border-top: medium none; border-left: medium none;"></td>
<td class="xl69" style="border-top: medium none; border-left: medium none;"></td>
</tr>
<tr style="height: 15pt;" height="20">
<td class="xl65" style="border-top: medium none; height: 15pt;" height="20">Average time, ms</td>
<td class="xl69" style="border-top: medium none; border-left: medium none;"></td>
<td class="xl69" style="border-top: medium none; border-left: medium none;"></td>
<td class="xl69" style="border-top: medium none; border-left: medium none;"></td>
<td class="xl69" style="border-top: medium none; border-left: medium none;"></td>
<td class="xl69" style="border-top: medium none; border-left: medium none;"></td>
<td class="xl69" style="border-top: medium none; border-left: medium none;"></td>
</tr>
<tr style="height: 15pt;" height="20">
<td class="xl73" style="border-top: medium none; height: 15pt;" height="20">not found</td>
<td class="xl69" style="border-top: medium none; border-left: medium none;">623,98</td>
<td class="xl69" style="border-top: medium none; border-left: medium none;">85,43</td>
<td class="xl69" style="border-top: medium none; border-left: medium none;">775,23</td>
<td class="xl69" style="border-top: medium none; border-left: medium none;">139,07</td>
<td class="xl69" style="border-top: medium none; border-left: medium none;">39,48</td>
<td class="xl69" style="border-top: medium none; border-left: medium none;">287,98</td>
</tr>
<tr style="height: 15pt;" height="20">
<td class="xl73" style="border-top: medium none; height: 15pt;" height="20">one face found</td>
<td class="xl69" style="border-top: medium none; border-left: medium none;">629,53</td>
<td class="xl69" style="border-top: medium none; border-left: medium none;">87,07</td>
<td class="xl69" style="border-top: medium none; border-left: medium none;">1053,49</td>
<td class="xl69" style="border-top: medium none; border-left: medium none;">248,26</td>
<td class="xl69" style="border-top: medium none; border-left: medium none;">42,99</td>
<td class="xl69" style="border-top: medium none; border-left: medium none;">455,31</td>
</tr>
<tr style="height: 15pt;" height="20">
<td class="xl73" style="border-top: medium none; height: 15pt;" height="20">two or more face found</td>
<td class="xl69" style="border-top: medium none; border-left: medium none;">632,32</td>
<td class="xl69" style="border-top: medium none; border-left: medium none;">88,04</td>
<td class="xl69" style="border-top: medium none; border-left: medium none;"></td>
<td class="xl69" style="border-top: medium none; border-left: medium none;">245,12</td>
<td class="xl69" style="border-top: medium none; border-left: medium none;">43,39</td>
<td class="xl69" style="border-top: medium none; border-left: medium none;"></td>
</tr>
</tbody>
</table>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.computer-vision-software.com/blog/2009/06/fastfurious-face-detection-with-opencv/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
		<item>
		<title>Parallel world of OpenCV (HaarTraining)</title>
		<link>http://www.computer-vision-software.com/blog/2009/06/parallel-world-of-opencv/</link>
		<comments>http://www.computer-vision-software.com/blog/2009/06/parallel-world-of-opencv/#comments</comments>
		<pubDate>Wed, 03 Jun 2009 01:25:37 +0000</pubDate>
		<dc:creator>rhondasw</dc:creator>
				<category><![CDATA[OpenCV]]></category>
		<category><![CDATA[face detection]]></category>
		<category><![CDATA[Haar]]></category>
		<category><![CDATA[HaarTraining]]></category>
		<category><![CDATA[MPI]]></category>
		<category><![CDATA[OPENMP]]></category>
		<category><![CDATA[parallel]]></category>
		<category><![CDATA[Profiling]]></category>

		<guid isPermaLink="false">http://www.computer-vision-software.com/blog/?p=70</guid>
		<description><![CDATA[If you want to generate cascade with OpenCV training tools, you should be ready for waiting plenty of time. For example, on training set: 3000 positive / 5000 negative, it takes about 6 days! to get cascade for face detection.  I wanted to generate many cascades with different training sets, also I added my own [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify; padding-left: 30px;">If you want to generate cascade with OpenCV training tools, you should be ready for waiting plenty of time. For example, on training set: 3000 positive / 5000 negative, it takes about <strong>6 days</strong>! to get cascade for face detection.  I wanted to generate many cascades with different training sets, also I added my own features to standart OpenCV&#8217;s ones  and refactor algorithms a little bit.  So waiting for 6 days to understand, that your cascade does nothing good =) was really anoying.  To reduce time, I chose paralleling methods.</p>
<p style="text-align: justify; padding-left: 30px;">
<p style="text-align: justify;"><span id="more-70"></span></p>
<h3 style="text-align: justify;"><strong>OpenMP.</strong></h3>
<p style="text-align: justify;">In OpenCV code supports OpenMP.  OpenMP is library, which allows to run program in several threads.  All this makes sence, if you have appropriate processor like Intel Core Duo or with Hyper Threading support at least.</p>
<p style="text-align: justify;">The advantage of this method is that, it&#8217;s already implemented and, I really believe, debugged in OpenCV.  OpenMP will speed up cascade generation &#8211; 4 days instead of 6 on my Intel Core2  1.8GHZ  2GB.</p>
<p><strong>MPI.</strong></p>
<p style="text-align: justify;">We constructed Linux-based cluster from 11 machines with  configuration:  2.7GHZ processor with 2GB RAM.    Computers are linked via 100 Ethernet LAN.</p>
<p><img class="aligncenter size-full wp-image-73" title="2" src="http://www.computer-vision-software.com/blog/wp-content/uploads/2009/06/2.jpg" alt="2" width="921" height="365" /></p>
<p style="text-align: justify;">OpenCV internal data structures are matrix and vectors &#8211; really good for paralleling.  So we decided to add MPI API calls to places with OpenMP defines &#8211; so just clone OpenMP schemas, who knows why we did so =) &#8211; hurry I suppose.   In this way we commonly paralleled  loops. <span style="text-decoration: underline;">But MPI does not have shared memory</span>, unlike OpenMP,  so data(MBs of traffic) synchronization time over Ethernet LAN brought computation speed-ups to nothing.  We understood, that  for MPI we needed parallel schema, in which data synchronization would be small.</p>
<p style="text-align: justify;">First, I wanted to investigate, what functions take most of all time -  printf  profiling in cvCreateTreeCascadeClassifier helped me.  And what do you think?  Function icvGetHaarTrainingDataFromBG is hero of the occasion &#8211; computation time was 9 hours on 11th cascade stage! Unlike it, icvGetHaarTrainingDataFromVec  took about 10 minutes. The matter is that, positive samples are resized to 20&#215;20, when make training vec file and each picture is just  run through  cascade. Negative samples have original resolution and it&#8217;s various, that&#8217;s why each picture is scanned with scalling 20&#215;20 window to find false-positive, like haardetect does.  The process is stopped, when we have required number of false-positive pictures.  To reduce time,  we needed to parallel icvGetHaarTrainingDataFromBG, but <span style="text-decoration: underline;">avoiding large data synchronization</span>.</p>
<p>icvGetHaarTrainingDataFromBG works in such way:</p>
<ul>
<li>it gets negative samples</li>
<li>found false positive until required number is reached</li>
<li>return false-positives</li>
</ul>
<p style="text-align: justify;">If we shuffle negative samples and then call icvGetHaarTrainingDataFromBG, what will happen?  Anything bad? In output we will have another false-positive pictures, but algorithm in whole will work correctly and generate right cascade.  So we decided to split negative samples into 11 parts(11 machines in cluster) and each cluster calls cvGetHaarTrainingDataFromBG on it&#8217;s own negative set, then clusters outputs are joined together.</p>
<p style="text-align: justify;">Computation time was accelerated much, instead of 6 days, cascade was generated within <span style="color: #ff0000;">21 hours</span>!  With perfomance tool we compare our cascade with one, generated on single machine with the same training set.  Results are very similar.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.computer-vision-software.com/blog/2009/06/parallel-world-of-opencv/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>OpenCV Haartraining: Detect objects using Haar-like features</title>
		<link>http://www.computer-vision-software.com/blog/2009/06/opencv-haartraining-detect-objects-using-haar-like-features/</link>
		<comments>http://www.computer-vision-software.com/blog/2009/06/opencv-haartraining-detect-objects-using-haar-like-features/#comments</comments>
		<pubDate>Tue, 02 Jun 2009 04:15:08 +0000</pubDate>
		<dc:creator>rhondasw</dc:creator>
				<category><![CDATA[OpenCV]]></category>
		<category><![CDATA[Haar]]></category>
		<category><![CDATA[Object detection]]></category>
		<category><![CDATA[Object Recognition]]></category>
		<category><![CDATA[Viola-Jones]]></category>

		<guid isPermaLink="false">http://www.computer-vision-software.com/blog/?p=64</guid>
		<description><![CDATA[OpenCV&#8217;s standart cascades allow to detect faces and eyes.  I wanted to create cascade in similar way to detect another objects:  pringles or plate for example.  I found some material in Net how to use OpenCV training tools, also I investigated training tool&#8217;s source  code myself  to found out, what training parameters can be tuned. [...]]]></description>
			<content:encoded><![CDATA[<p style="padding-left: 30px;">
<p style="padding-left: 30px; text-align: justify;">OpenCV&#8217;s standart cascades allow to detect faces and eyes.  I wanted to create cascade in similar way to detect another objects:  pringles or plate for example.  I found some material in Net how to use OpenCV training tools, also I investigated training tool&#8217;s source  code myself  to found out, what training parameters can be tuned.</p>
<h3><span style="color: #000000;"><strong>Prepare images.</strong></span></h3>
<p style="text-align: justify;">For training, I needed thousands of images, containing my object with different lightning conditions and perspectives. After trying to find required number of pictures with Google ,  I understood, that it&#8217;s really difficult task =).  So I decided <span style="text-decoration: underline;">to take video with my object</span>,  then I wrote simple program to crop object from video, frame by frame.  In such way,  I generated about 3000 positive samples (cropped images  with my object).  Resolution varied from 50&#215;50 to 100&#215;100.  The advantage of this method &#8211; you  get many samples with different reflections, illuminations and backgrounds.  It&#8217;s very important, that all these images &#8220;features&#8221; are various!</p>
<p style="text-align: justify;"><span id="more-64"></span></p>
<p style="text-align: justify;">Negative samples I got  from Internet public databases&#8230;, there were about 5000 images of different resolution, which did not contain my objects.   I worked with BMP format, due to compression artefacts in some compression levels of JPEG.</p>
<h3><strong>Sample/Test data creation.</strong></h3>
<p>So I split all my images into 4 sets:</p>
<ul>
<li>Positive images, containing my object &#8211; about 3000 images, for training.</li>
<li>Negative images &#8211; about 5000 images, for training.</li>
<li>Positive images &#8211; about 100 for testing.</li>
<li>Negative images &#8211; about 100 for testing.</li>
</ul>
<p style="text-align: justify;">Of course, I could use the same images for testing and training, but it&#8217;s not good.  Positive images should be be packed to OpenCV vec-file.  it can be done with createsamples program from OpenCV.  When packed, all images are resized to 20&#215;20 &#8211; it&#8217;s good size for training speed.  Also during object detection, object with smaller size will not be found.   For negative samples,  I only created negative.dat(list of negative file names) with win dir \b command.</p>
<h3><strong>Training.</strong></h3>
<p style="text-align: justify;">OpenCV implements Adaboost algorithm in haartraining. exe.  This tool  generates xml cascade file, which is used in haardetection tool for object detection.  There are some main characteristics of cascade:  number of stages, type of classifiers on each stage. These parameters can be configured when you launch haartraining. I configured it as per my training data (positives and negatives).</p>
<p style="padding-left: 30px;">
<p style="text-align: justify;">Training is finished, when required false alarm of cascade is achieved.  So cascade can contain less stages than nstage &#8211; it&#8217;s ok. It&#8217;s rather worse, when we achieve required number of stage, but required false alarm is not. It&#8217;s signal, that something is wrong either with content or with haartraining parameters.  Also maxfalsealarm is false alarm of stage, false alarm of cascade is multiplication of stage&#8217;s alarms.</p>
<p style="text-align: justify;">I used P4 2.7GHZ with 2 GB and it took about !6 days! of permanent working to finally get cascade.  If you have Hyper Threading, you can recompile haartraining.exe with OpenMP support, it will speed up process a little bit =).</p>
<h3><strong>Testing.</strong></h3>
<p>Finally I got haarcascade.xml file. OpenCV perfomance.exe tool can be used for testing cascade.  I tested it on my testing content  &#8211; sorry for pun =).</p>

<a href='http://www.computer-vision-software.com/blog/2009/06/opencv-haartraining-detect-objects-using-haar-like-features/picture1/' title='picture1'><img width="150" height="150" src="http://www.computer-vision-software.com/blog/wp-content/uploads/2009/06/picture1-150x150.jpg" class="attachment-thumbnail" alt="picture1" title="picture1" /></a>
<a href='http://www.computer-vision-software.com/blog/2009/06/opencv-haartraining-detect-objects-using-haar-like-features/attachment/11/' title='11'><img width="150" height="150" src="http://www.computer-vision-software.com/blog/wp-content/uploads/2009/06/11-150x150.png" class="attachment-thumbnail" alt="11" title="11" /></a>
<a href='http://www.computer-vision-software.com/blog/2009/06/opencv-haartraining-detect-objects-using-haar-like-features/attachment/2/' title='plate experiment 2'><img width="150" height="150" src="http://www.computer-vision-software.com/blog/wp-content/uploads/2009/06/2-150x150.png" class="attachment-thumbnail" alt="plate experiment 2" title="plate experiment 2" /></a>

]]></content:encoded>
			<wfw:commentRss>http://www.computer-vision-software.com/blog/2009/06/opencv-haartraining-detect-objects-using-haar-like-features/feed/</wfw:commentRss>
		<slash:comments>262</slash:comments>
		</item>
	</channel>
</rss>
