{"id":18,"date":"2009-03-12T12:02:15","date_gmt":"2009-03-12T02:02:15","guid":{"rendered":"http:\/\/computer-vision-software.com\/blog\/?p=18"},"modified":"2009-11-30T14:45:49","modified_gmt":"2009-11-30T04:45:49","slug":"arm-wrestling-with-opencv","status":"publish","type":"post","link":"http:\/\/www.computer-vision-software.com\/blog\/2009\/03\/arm-wrestling-with-opencv\/","title":{"rendered":"ARM-wrestling with OpenCV"},"content":{"rendered":"<p>I played with two ARM9-based single board computers (SBC) recently to investigate how OpenCV would operate on embedded platforms. The SBCs are &#8211; <a onclick=\"javascript:pageTracker._trackPageview('\/outgoing\/www.embeddedarm.com\/products\/board-detail.php?product=TS-7800');\"  href=\"http:\/\/www.embeddedarm.com\/products\/board-detail.php?product=TS-7800\">TS-7800<\/a> and <a onclick=\"javascript:pageTracker._trackPageview('\/outgoing\/www.embedinfo.com\/english\/Product\/SBC2440-III.asp');\"  href=\"http:\/\/www.embedinfo.com\/english\/Product\/SBC2440-III.asp\">SBC2440-III<\/a>.<\/p>\n<p>OpenCV uses floating point operations a lot, but not all of the ARM processors have FP coprocessor, so developers should use either some FP library, or as in my case &#8211; use Linux kernel FP emulation. There are two types of such emulation OABI and EABI. More details can be found <a onclick=\"javascript:pageTracker._trackPageview('\/outgoing\/wiki.debian.org\/ArmEabiPort');\"  href=\"http:\/\/wiki.debian.org\/ArmEabiPort\">here<\/a> and <a onclick=\"javascript:pageTracker._trackPageview('\/outgoing\/www.linuxdevices.com\/articles\/AT5920399313.html');\"  href=\"http:\/\/www.linuxdevices.com\/articles\/AT5920399313.html\">here<\/a>. Kernel release 2.6.16 was the first one to include ARM EABI support.<\/p>\n<p>Unfortunately, CPUs of both SBCs do not support floating point in hardware, but luckily enough, TS-7800 has Debian Linux with 2.6.21 kernel. So I had a chance to compare OpenCV performance for OABI and EABI.<\/p>\n<p>Both SBCs have necessary tool-chains in package &#8211; TS-7800 has Linux and Windows(Cygwin) tool-chains, SBC-2440 &#8211; only Linux one.\u00a0 In addition to these I downloaded newer release of Codesourcery ARM tool-chain for Windows, because the one from TS-7800 SW package didn&#8217;t work properly with Cygwin.<br \/>\n<!--more--><br \/>\nI wrote a pretty simple script to ease OpenCV (version 1.1pre1 from <a onclick=\"javascript:pageTracker._trackPageview('\/outgoing\/sourceforge.net\/project\/showfiles.php?group_id=22870&amp;package_id=16948&amp;release_id=634504');\"  href=\"http:\/\/sourceforge.net\/project\/showfiles.php?group_id=22870&amp;package_id=16948&amp;release_id=634504\">here<\/a>) configuration for various toolchains. Here it is:<\/p>\n<pre class=\"python:nogutter\">#!\/bin\/bash\r\n##======== TS-7800 environment settings======\r\n#### Linux host. EABI complier\r\n#export DEVROOT=\/opt\/crosstool\/arm-none-linux-gnueabi\r\n#export APP_PREFIX=arm-none-linux-gnueabi\r\n#export GCC_HOST=i686-pc-linux-gnu\r\n##-O3 kills gcc : cvpyrsegmentation.cpp:1021: internal compiler error: in verify_local_live_at_start, at flow.c:546\r\n#export OFLAGS=-O2\r\n\r\n### Linux host. OABI compiler\r\n#export DEVROOT=\/opt\/crosstool\/arm-linux\/gcc-3.3.4-glibc-2.3.2\r\n#export APP_PREFIX=arm-linux\r\n#export GCC_HOST=i686-pc-linux-gnu\r\n##Any optimization causes SEGFAULTS during face detection application execution\r\n#export OFLAGS=-O0\r\n\r\n### Windows (Cygwin) host. EABI compiler (Codesourcery 2008q3-72)\r\nexport APP_PREFIX=arm-none-linux-gnueabi\r\nexport DEVROOT=\/opt\/crosstool\/codesourcery\r\nexport CYGPATH=d:\/cygwin\/bin\/cygpath\r\nexport GCC_HOST=i686-pc-cygwin\r\n\r\n###Windows (Cygwin) host. OABI compiler\r\n#export APP_PREFIX=arm-unknown-linux-gnu\r\n#export DEVROOT=\/opt\/crosstool\/gcc-3.3.4-glibc-2.3.2\r\n#export CYGPATH=d:\/cygwin\/bin\/cygpath\r\n#export GCC_HOST=i686-pc-cygwin\r\n##Any optimization causes SEGFAULTS during face detection application execution\r\n#export OFLAGS=-O0\r\n\r\n##======== SBC2440-III environment settings======\r\n####Linux host only. OABI compiler only. (Out of the box kernel does not support EABI)\r\n#export DEVROOT=\/usr\/local\/arm\/3.4.1\r\n#export APP_PREFIX=arm-linux\r\n#export GCC_HOST=i686-pc-linux-gnu\r\n##Any optimization causes SEGFAULTS during face detection application execution\r\n#export OFLAGS=-O0\r\n##===============================================\r\n\r\nexport PATH=$DEVROOT\/$APP_PREFIX\/bin:$PATH\r\n\r\n.\/configure \\\r\n --target=$APP_PREFIX \\\r\n --host==$APP_PREFIX \\\r\n --build=$GCC_HOST \\\r\n --disable-shared \\\r\n --enable-static \\\r\n --without-imageio  --without-carbon \\\r\n --without-quicktime --without-python \\\r\n --without-gtk --without-swig \\\r\n --without-v4l \\\r\n --disable-apps \\\r\n --prefix=$DEVROOT\/$APP_PREFIX \\\r\n CC=$DEVROOT\/bin\/$APP_PREFIX-gcc \\\r\n CXXFLAGS=\"-fsigned-char $OFLAGS -pipe\" \\\r\n LD=$DEVROOT\/bin\/$APP_PREFIX-ld \\\r\n CPP=$DEVROOT\/bin\/$APP_PREFIX-cpp \\\r\n CXXCPP=$DEVROOT\/bin\/$APP_PREFIX-cpp \\\r\n CXX=$DEVROOT\/bin\/$APP_PREFIX-g++ \\\r\n AR=$DEVROOT\/bin\/$APP_PREFIX-ar \\\r\n RANLIB=$DEVROOT\/bin\/$APP_PREFIX-ranlib \\\r\n NM=$DEVROOT\/bin\/$APP_PREFIX-nm \\\r\n STRIP=$DEVROOT\/bin\/$APP_PREFIX-strip \\\r\n AS=$DEVROOT\/bin\/$APP_PREFIX-as<\/pre>\n<p>Just uncomment setting you need, and comment all the others and you&#8217;re all set. <code>-fsigned-char<\/code> in <code>CXXFLAGS<\/code> is a must. OpenCV will (somehow) work even without this flag, but some functionality will be broken &#8211; JPEG parser for example (to say the truth, it will still be broken event with <code>-fsigned-char<\/code>, but at least it will correctly parse JPEG headers).<br \/>\nAfter script finished run <code>make<\/code> and then <code>make install<\/code> . Libraries and headers will be placed in directory, specified with <code>--prefix=<\/code> parameter.<\/p>\n<p>Now when OpenCV is built and ready it&#8217;s time to &#8220;feel the power in your ARMs&#8221;.<\/p>\n<p>I used facedetect sample application (\/samples\/c\/) to test OpenCV on SBCs. I had to remove UILib -related code and add ome more parameter to application, named <code>--extension<\/code>, which allows specifying of input file type (BMP, YML, JPG). Changes I made to file can be observed <a href=\"http:\/\/computer-vision-software.com\/blog\/wp-content\/uploads\/2009\/03\/diff.htm\">here<\/a><br \/>\nThe makefile I sued to build the application is written in a way similar to the previous configure script:<\/p>\n<pre class=\"python:nogutter\"># TS-7800 environment settings\r\n#DEVROOT=\/opt\/crosstool\/arm-none-linux-gnueabi\r\n#APP_PREFIX=arm-none-linux-gnueabi\r\n#SBC2440-III environment settings\r\n#DEVROOT=\/usr\/local\/arm\/3.4.1\r\n#APP_PREFIX=arm-linux\r\n#CodeSourcery setup\r\nDEVROOT=\/opt\/crosstool\/codesourcery\r\nAPP_PREFIX=arm-none-linux-gnueabi\r\n\r\nCC = $(DEVROOT)\/bin\/$(APP_PREFIX)-g++\r\nCPP = $(DEVROOT)\/bin\/$(APP_PREFIX)-cpp\r\nLD=$(DEVROOT)\/bin\/$(APP_PREFIX)-ld\r\n\r\nCXXFLAGS = -I\"$(DEVROOT)\/$(APP_PREFIX)\/include\" -I\"$(DEVROOT)\/$(APP_PREFIX)\/include\/opencv\"\r\nCXXFLAGS+= -fsigned-char\r\nLDFLAGS = -static -L\"$(DEVROOT)\/$(APP_PREFIX)\/lib\" -lcv -lhighgui -lcxcore -lml -lcvaux -lpthread -ldl\r\n\r\nall: facedetect.o\r\n$(CC) facedetect.o $(LDFLAGS) -o facedetect\r\n\r\nfacedetect.o:\r\n$(CC) $(CXXFLAGS) -c facedetect.c\r\n\r\nclean:\r\nrm -f facedetect facedetect.o<\/pre>\n<p>Copy and paste this text to a file, say makefile_facedetect, and then use it: <code>make -f makefile_facedetect<\/code>. It will build statically linked executable &#8211; I didn&#8217;t want to bother with shared OpenCV libraries.<br \/>\nThe file used to detect face was lena.jpg (512&#215;512) from OpenCV samples\/c\/ directory. I also converted it to BMP and YML, since JPEG parser does not work properly on ARM.<br \/>\nExecution results<br \/>\n<strong>TS-7800<\/strong><br \/>\nEABI build: detection time = 31 512.1ms<\/p>\n<p><strong>SBC-2440-III<\/strong><br \/>\nOABI build: detection time = 448 151 ms<\/p>\n<p>Conclusions:<br \/>\n1) EABI is MUCH better than OABI<br \/>\n2) Even with EABI FP support, there is still much needed to be improved in OpenCV to make it usable on ARM processors.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I played with two ARM9-based single board computers (SBC) recently to investigate how OpenCV would operate on embedded platforms. The SBCs are &#8211; TS-7800 and SBC2440-III. OpenCV uses floating point operations a lot, but not all of the ARM processors have FP coprocessor, so developers should use either some FP library, or as in my [&hellip;]<\/p>\n","protected":false},"author":4,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[84],"tags":[7,10,12,11,6],"class_list":["post-18","post","type-post","status-publish","format-standard","hentry","category-opencv","tag-arm","tag-arm9","tag-eabi","tag-oabi","tag-opencv"],"_links":{"self":[{"href":"http:\/\/www.computer-vision-software.com\/blog\/wp-json\/wp\/v2\/posts\/18","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\/4"}],"replies":[{"embeddable":true,"href":"http:\/\/www.computer-vision-software.com\/blog\/wp-json\/wp\/v2\/comments?post=18"}],"version-history":[{"count":0,"href":"http:\/\/www.computer-vision-software.com\/blog\/wp-json\/wp\/v2\/posts\/18\/revisions"}],"wp:attachment":[{"href":"http:\/\/www.computer-vision-software.com\/blog\/wp-json\/wp\/v2\/media?parent=18"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.computer-vision-software.com\/blog\/wp-json\/wp\/v2\/categories?post=18"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.computer-vision-software.com\/blog\/wp-json\/wp\/v2\/tags?post=18"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}