{"id":35,"date":"2009-03-31T13:47:25","date_gmt":"2009-03-31T03:47:25","guid":{"rendered":"http:\/\/computer-vision-software.com\/blog\/?p=35"},"modified":"2009-11-30T12:54:05","modified_gmt":"2009-11-30T02:54:05","slug":"running-opencv-facedetect-sample-on-pocket-pc","status":"publish","type":"post","link":"http:\/\/www.computer-vision-software.com\/blog\/2009\/03\/running-opencv-facedetect-sample-on-pocket-pc\/","title":{"rendered":"Running OpenCV facedetect sample on Windows CE (Windows Mobile)"},"content":{"rendered":"<p>Here is a brief description of compiling and running OpenCV&#8217;s facedetect sample on Pocket PC.<\/p>\n<p><strong>Compiling<\/strong><\/p>\n<p>I used Visual Studio 2005 Team Suite edition to compile OpenCV 1.1 pre 1. It compiled without any trouble for Win32.<\/p>\n<p>Then I tried to compile for Pocket PC (set Platform to Pocket PC 2003 (ARMV4)). Some compilation errors occured. As I only needed to compile a facedetect sample, I decided to compile the necessary files only.<\/p>\n<p>\u00a0<!--more--><\/p>\n<p>To build cxcore I had to change the following:<\/p>\n<p>cxmisc.h, line 125 to<br \/>\n#elif defined WIN32 || defined WIN64 || defined WINCE<\/p>\n<p>cxswitcher.cpp, line 57 to<br \/>\n#if defined WIN32 || defined WIN64 || defined WINCE<\/p>\n<p>line 90 to<br \/>\n#if defined WIN32 &amp;&amp; !defined\u00a0 WIN64 &amp;&amp; !defined WINCE<\/p>\n<p>line 137, 140: constants wrapped in #ifdef<br \/>\n#ifndef WINCE<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8220;HARDWARE\\\\DESCRIPTION\\\\SYSTEM\\\\CentralProcessor\\\\0\\\\&#8221;,<br \/>\n#else<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 L&#8221;HARDWARE\\\\DESCRIPTION\\\\SYSTEM\\\\CentralProcessor\\\\0\\\\&#8221;,<br \/>\n#endif<br \/>\n#ifndef WINCE<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8220;~MHz&#8221;,<br \/>\n#else<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 L&#8221;~MHz&#8221;,<br \/>\n#endif<\/p>\n<p>approx line 435, 600: added name translation<br \/>\n#ifdef WINCE<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 size_t origsize = strlen(name) + 1;<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 WCHAR wname[100];<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 MultiByteToWideChar(CP_ACP,0,name,origsize,wname,100);<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 addr = (uchar*)GetProcAddress( plugins[idx].handle, wname );<br \/>\n#else<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 addr = (uchar*)GetProcAddress( plugins[idx].handle, name );<br \/>\n#endif<\/p>\n<p>cxerror.cpp line 45 to<br \/>\n#if defined WIN32 || defined WIN64 || defined WINCE<\/p>\n<p>line 92 added<br \/>\n#define TLS_OUT_OF_INDEXES ((DWORD)0xFFFFFFFF)<\/p>\n<p>line with DllMain to<br \/>\n#if defined WIN32 || defined WIN64<br \/>\nBOOL WINAPI DllMain(<br \/>\n#ifdef WINCE<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 HANDLE<br \/>\n#else<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 HINSTANCE<br \/>\n#endif<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 , DWORD\u00a0 fdwReason, LPVOID )<\/p>\n<p>a fragment in cvGuiBoxReport to<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 sprintf( message, &#8220;%s (%s)\\nin function %s, %s(%d)\\n\\n&#8221;<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8220;Press \\&#8221;Abort\\&#8221; to terminate application.\\n&#8221;<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8220;Press \\&#8221;Retry\\&#8221; to debug (if the app is running under debugger).\\n&#8221;<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8220;Press \\&#8221;Ignore\\&#8221; to continue (this is not safe).\\n&#8221;,<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 cvErrorStr(code), err_msg ? err_msg : &#8220;no description&#8221;,<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 func_name, file, line );<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 sprintf( title, &#8220;OpenCV GUI Error Handler&#8221; );<\/p>\n<p>#ifdef WINCE<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 WCHAR wmsg[2048];<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 MultiByteToWideChar(CP_ACP,0,title,strlen(message),wmsg,2048);<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 int answer = MessageBox( NULL, wmsg, L&#8221;OpenCV GUI Error Handler&#8221;, MB_ICONERROR|MB_ABORTRETRYIGNORE);<br \/>\n#else<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 int answer = MessageBox( NULL, message, title, MB_ICONERROR|MB_ABORTRETRYIGNORE|MB_SYSTEMMODAL );<br \/>\n#endif<\/p>\n<p>Changed preprocessor definitions to<br \/>\nNDEBUG;_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);WINCE;_WINDOWS;_USRDLL;CV_CE_EXPORTS;$(ARCHFAM);$(_ARCHFAM_);_UNICODE;UNICODE<\/p>\n<p>Subsystem to<br \/>\nWindowsCE (\/SUBSYSTEM:WINDOWSCE)<\/p>\n<p>Target machine to<br \/>\nMachineARM (\/MACHINE:ARM)<\/p>\n<p>Added dependency to<br \/>\nsecchk.lib<\/p>\n<p>After building cxcore, import library (.lib) was not generated for some reason. I was not able to resolve this, but as I only needed a running sample, i setup a new project and added all the necessary source from existing opencv projects to it. That is, cxcore, cv and some files from highgui.<\/p>\n<p>I had to turn off precompiled headers (as the header file was different in cxcore and other projects).<\/p>\n<p>There were linking errors in cvkdtree.obj, so i just removed cvkdtree.cpp from compilation as it was not needed for my sample.<\/p>\n<p>cvconfig.h file was added to cv\/include directory<\/p>\n<p>..\\..\\otherlibs\\highgui added to include paths<\/p>\n<p>Only loadsave.cpp, utils.cpp and window_w32.cpp from highgui root were added to sample project. grfmts contents were also added.<\/p>\n<p>As cvShowImage implementation was not added, i removed it from cxcore.h:<br \/>\n#ifndef WINCE<br \/>\n#define CV_SET_IMAGE_IO_FUNCTIONS() \\<br \/>\n\u00a0\u00a0\u00a0 cvSetImageIOFunctions( cvLoadImage, cvLoadImageM, cvSaveImage, cvShowImage )<br \/>\n#else<br \/>\n#define CV_SET_IMAGE_IO_FUNCTIONS() \\<br \/>\n\u00a0\u00a0\u00a0 cvSetImageIOFunctions( cvLoadImage, cvLoadImageM, cvSaveImage, NULL )<br \/>\n#endif<\/p>\n<p><strong>Running sample application<\/strong><\/p>\n<p>I changed a facedetect sample so that not to use gui. With these changes, facedtetect sample works fine both on emulator and Pocket PC.<br \/>\nI have to use .bmp files however as jpg files were not loaded properly.<\/p>\n<p>Speaking about emulator, there is something wrong with the timing, the fragment<br \/>\n\u00a0\u00a0\u00a0 log_to_file(&#8220;Test app started&#8221;);<br \/>\n\u00a0\u00a0\u00a0 Sleep(1000);<br \/>\n\u00a0\u00a0\u00a0 log_to_file(&#8220;This should be logged approximately 1 second after start&#8221;);<br \/>\ngenerates log<br \/>\n000000.063ms: Test app started<br \/>\n000966.265ms: This should be logged approximately 1 second after start.<br \/>\nHowever, it looks as expected on the real device.<\/p>\n<p>It turned out that release version built with floating point emulation takes approximately same time as the version built with emulation (\/QRfpe). I tested this on emulator only.<br \/>\nGenerally, simulator is very slow.<\/p>\n<p>I used a 640&#215;480 24bit sample with 4 faces. Here are the results<br \/>\n4 face(s) detected in 000702.286ms \/\/ my PC<br \/>\n4 face(s) detected in 329986.632ms \/\/ emulator and a build without fp emulation<br \/>\n4 face(s) detected in 334343.969ms \/\/ emulator and a build with fp emulation<br \/>\n4 face(s) detected in 066759.889ms\/\/ Fujitsu Siemens Pocket Loox PXA270 &#8211; 624Mhz and a build without fp emulation<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A description of steps required to compile the part of the OpenCV 1.1 needed to run facedetect samle and the results received.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[84],"tags":[7,6,17,18],"class_list":["post-35","post","type-post","status-publish","format-standard","hentry","category-opencv","tag-arm","tag-opencv","tag-pocket-pc","tag-windows-ce"],"_links":{"self":[{"href":"http:\/\/www.computer-vision-software.com\/blog\/wp-json\/wp\/v2\/posts\/35","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.computer-vision-software.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.computer-vision-software.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.computer-vision-software.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.computer-vision-software.com\/blog\/wp-json\/wp\/v2\/comments?post=35"}],"version-history":[{"count":0,"href":"http:\/\/www.computer-vision-software.com\/blog\/wp-json\/wp\/v2\/posts\/35\/revisions"}],"wp:attachment":[{"href":"http:\/\/www.computer-vision-software.com\/blog\/wp-json\/wp\/v2\/media?parent=35"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.computer-vision-software.com\/blog\/wp-json\/wp\/v2\/categories?post=35"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.computer-vision-software.com\/blog\/wp-json\/wp\/v2\/tags?post=35"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}