cortex-A8 ARM核 opencv程序移植

整體思路:利用TI提供的交叉編譯器(arm-none-liunux-gnueabi-gcc)交叉編譯opencv庫;利用eclipse 編譯算法工程,在工程中調用交叉編譯後的opencv庫;編譯好的算法放到文件系統下,在板子上運行,此過程可以利用GDB server實現代碼的遠程調試。

1.交叉編譯opencv庫。

這裏參考的文章是http://processors.wiki.ti.com/index.php/Building_OpenCV_for_ARM_Cortex-A8http://blog.csdn.net/yr119111/article/details/7732336。唯恐以後資源找不到,還是貼到這裏吧。

 

Introduction:

This wiki provides instructions that specify how to building OpenCV for ARM Cortex-A8 platform using Cmake in a linux environment. The instructions below have been tested for OpenCV 2.2 by cross compiling it on a Ubuntu 10.04 machine. The toolchain is Codesourcery 2010.12.

Build Instructions

OpenCV 2.2 uses cmake to build. Cmake is a meta-makefile system that generates makefiles. We need to install this first.

  • Update Ubuntu to install and setup cmake
  $ sudo apt-get install cmake cmake-curses-gui
  $ export PATH=$PATH:/opt/arm-2010.12/bin
  $ tar -jxf OpenCV-2.2.0.tar.bz2
  • Cmake supports building outside the source tree. We will use this method to build OpenCV. So, create a directory in $HOME as build
  $ mkdir ~/build && cd ~/build
  • We need to now create a toolchain.cmake file that we will pass to cmake so that it knows how to cross-compile.
  $ vi toolchain.cmake
  • Add the following to toolchain.cmake and save it. This assumes that your NFS targetfs is at ~/targetfs
  set( CMAKE_SYSTEM_NAME Linux )
  set( CMAKE_SYSTEM_PROCESSOR arm )
  set( CMAKE_C_COMPILER arm-none-linux-gnueabi-gcc )
  set( CMAKE_CXX_COMPILER arm-none-linux-gnueabi-g++ )
  set( CMAKE_FIND_ROOT_PATH ~/targetfs )

Important: The CMake build setup in OpenCV 2.2 and earlier does not have NEON ENABLE flag to to take advantage of neon accelearation. Hence please make the following modifications to the file CMakeLists.txt in OpenCV 2.2 to enable neon acceleration.

         # Other optimizations 
         if(USE_O2)    
                set(EXTRA_C_FLAGS_RELEASE "${EXTRA_C_FLAGS_RELEASE} -O2 -mfpu=neon")
         endif()

This may not be required in later versions of OpenCV since OpenCV 2.3 has the option to enable neon in the CMake build process.

  • Now we run cmake to process and generate makefile
  $ cmake -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake ../OpenCV-2.2.0/
  • When cross compiling for ARM, I found that some items do not build. So, we need to use the cmake curses gui to customize cmake output and re-generate the makefile before we can build. Now launch the cmake curses gui to customize the make file generation
  $ ccmake .
  • This will bring up a screen full of options that can be edited. Make sure that the following items are OFF. If it is ON, you can toggle it by scrolling to the option and hitting Enter
    • BUILD_NEW_PYTHON_SUPPORT
    • BUILD_TESTS
    • WITH_1394
    • WITH_CUDA
    • WITH_EIGEN2                     
    • WITH_FFMPEG                      
    • WITH_GSTREAMER                   
    • WITH_GTK
    • WITH_JASPER                     
    • WITH_JPEG                       
    • WITH_OPENEXR                    
    • WITH_PNG                        
    • WITH_PVAPI                      
    • WITH_QT                         
    • WITH_QT_OPENGL                  
    • WITH_TBB                        
    • WITH_TIFF                       
    • WITH_UNICAP                     
    • WITH_V4L                        
    • WITH_XINE    

Note: Do not forget to keep the USE_O2  option ON in the configuration to take adavntage of neon acceleration that you added to this option

  • Now, press 'c' to configure and 'g' to generate the makefiles again.
  • Now you are ready to build OpenCV. Run make from the command line and it should generate the OpenCV libraries. You can try to customize the build by turning on the various options that we disabled earlier and see if it builds for you.

 

opencv2.3.1在arm端的移植( 更新測試結果)

更新:測試結果就是,本文中使用的main.cpp這個例子,在SBC3730這塊板子上運行成功!

           所以我估計在omapl138上也會成功。

更新:更新了 編譯命令    `pkg-config --cflags --libs opencv`   的更改以及使用方法

首先,opencv是個好東西,對於我這樣的菜鳥,來說,既是好用的工具,也是最好的學習資料。

此次移植是在ubuntu12.04 32位,針對omapl138的arm端來進行的。(其實只要是arm應該都一樣)

本來呢,是想移植到c6748的。但是我感覺這個對我來說難度有點大。。而網上對於移植arm的資料也很多。

所以先移植到arm再說把。

 

不過還是希望有高手能給我指導一下,將opencv移植至c6748該怎麼做。在CCS裏或者linux裏都行。因爲我想使用gpp+dsp模式。將算法做成包,然後跑在dsp端。


此文有一部分綜合了網上多人的方法,也有自己在進行移植時的經驗。

當然,移植的效果還沒有給出,因爲板子不在身邊,無法進行測試。等有板子了,再進行測試,確定是否移植成功。

結果會在本文更新。

好。先下載opencv。

下載OpenCV 2.3.1 , http://sourceforge.net/projects/opencvlibrary/files/

然後解壓

tar xvf OpenCV-2.3.1.tar.bz2

在此要說明的是,此次移植是在前面omapl138的DVSDK都安裝並且配置好的情況下進行的。

我的DVSDK安裝路徑是/home/yr/ti-dvsdk_omapl138-evm_04_03_00_06

我使用omapl138中的交叉編譯鏈。

即交叉編譯鏈存在於

/home/yr/ti-dvsdk_omapl138-evm_04_03_00_06/linux-devkit/bin   這個目錄中。

剛纔解壓了opencv,現在在你的工作目錄裏建立一個新的文件夾opencv_arm。名稱和具體路徑看個人愛好。

然後進入終端運行cmake-gui。如果以前沒有安裝過,終端會提示你使用apt-get命令安裝。

安裝好之後就可以運行了。

cmake-gui

之後出現下面的界面


選擇source code目錄   /home/yr/OpenCV-2.3.1

以及build目錄              /home/yr/opencv_arm

點configure

然後按照下圖中所選擇的:

generator爲Unix Makefiles,選擇Specify options for cross-compiling


next之後,在下圖這幾個位置填寫路徑


Operating System填寫arm-arago-linux

Compilers裏,C選擇   /home/yr/ti-dvsdk_omapl138-evm_04_03_00_06/linux-devkit/bin/arm-arago-linux-gnueabi-gcc  

                    C++選擇 /home/yr/ti-dvsdk_omapl138-evm_04_03_00_06/linux-devkit/bin/arm-arago-linux-gnueabi-g++  

可以看出來我都是用的DVSDK中的目錄。

Target Root選擇   /home/yr/ti-dvsdk_omapl138-evm_04_03_00_06/linux-devkit  

然後finish。

cmake便返回下圖


圖中紅色部分是我們可以配置的位置。這裏要提醒一下的是,更改完配置之後,記得再點一下左下角的configure按鈕。不然更改不會應用。

具體的配置當然是根據需要來進行的。

這裏要說明一下:

因爲在之前安裝過opencv  是x86版本的,即在PC上使用的,所以/usr/local中的include以及lib都有opencv的相關庫存在,

所以爲了方便自己使用以及不出問題,建議將arm版的opencv的安裝目錄更改一下,

我將下圖位置的CMAKE_INSTALL_PREFIX後面的/usr/local改成了

/usr/local/arm  


同時,我還更改了一些配置,卻掉了一些我不用的功能,以及導致編譯出錯的功能。比如

WITH_CUDA是我用不到的功能,

WITH_TIFF是因爲我在編譯的時候出錯了,

然後我去掉了這個功能。(我在網上看到,有人沒有去掉這個功能也能編譯,可能是因爲我係統裏缺少什麼東西吧?)

配置更改完了之後點一下左下角的configure。然後再點generate.

到這裏,cmake的工作做完了。

從終端進入  opencv_arm這個文件夾然後

make。

但是,肯定會出錯。

必然會遇到的錯誤如下:

/home/yr/OpenCV-2.3.1/modules/flann/include/opencv2/flann/dist.h: In function 'T cvflann::abs(T) [with T = long double]':
/home/yr/OpenCV-2.3.1/modules/flann/include/opencv2/flann/dist.h:63: error: 'fabsl' was not declared in this scope
make[2]: *** [modules/flann/CMakeFiles/opencv_flann_pch_dephelp.dir/opencv_flann_pch_dephelp.obj] Error 1
make[1]: *** [modules/flann/CMakeFiles/opencv_flann_pch_dephelp.dir/all] Error 2
make: *** [all] Error 2

解決方法:
修改OpenCV-2.3.1/modules/flann/include/opencv2/flann/dist.h文件第63行的源碼:{ return fabsl(x); }改爲{ return fabs(x); }
其實就是刪了個l這個字母。
然後再
make
當然,還有非常大概率遇到一下錯誤:
Linking CXX executable ../../bin/opencv_test_calib3d
../../lib/libopencv_core.so: undefined reference to `pthread_key_create'
../../lib/libopencv_core.so: undefined reference to `pthread_getspecific'
../../lib/libopencv_ts.so: undefined reference to `pthread_key_delete'
../../lib/libopencv_core.so: undefined reference to `pthread_once'
../../lib/libopencv_core.so: undefined reference to `clock_gettime'
../../lib/libopencv_core.so: undefined reference to `pthread_setspecific'
collect2: ld returned 1 exit status
make[2]: *** [bin/opencv_test_calib3d] Error 1
make[1]: *** [modules/calib3d/CMakeFiles/opencv_test_calib3d.dir/all] Error 2
make: *** [all] Error 2
解決方法:
修改opencv_arm目錄下的CMakeCache.txt,CMAKE_EXE_LINKER_FLAGS原來爲空,加上-lpthread -lrt,如下圖:

注意:每次錯誤產生,經修改後,只要再次執行make命令就接着編譯,
編譯成功後,執行
sudo make intall
就會安裝opencv。
將opencv安裝到
/usr/local/arm     這個位置。
安裝好之後,來嘗試交叉編譯一個例子試試。
我這裏使用的是opencv中文官網中的例子。
只不過考慮到我目前是通過NFS,在終端中使用minicom來運行omapl138中的linux,所以將裏面涉及到窗口及顯示的函數去掉了。
 
例子如下,命名爲main.cpp:(功能是將一副彩色圖片轉換爲灰度圖)
  1. #include "cv.h" 
  2. #include "highgui.h" 
  3.  
  4. int main( int argc, char** argv ) 
  5.   IplImage* pImg; //聲明IplImage指針 
  6.  
  7.   //載入圖像,強制轉化爲Gray 
  8.   if( argc == 3 && 
  9.       (pImg = cvLoadImage( argv[1], 0)) != 0 ) 
  10.     { 
  11.  
  12.       IplImage* pImg2 = cvCreateImage(cvGetSize(pImg), 
  13.                       pImg->depth, 
  14.                       pImg->nChannels); 
  15.       cvCopy(pImg, pImg2, NULL); 
  16.  
  17.       cvSaveImage(argv[2], pImg2);//把圖像寫入文件 
  18.  
  19.  
  20.       cvReleaseImage( &pImg ); //釋放圖像 
  21.       cvReleaseImage( &pImg2 ); //釋放圖像 
  22.       return 0; 
  23.     } 
  24.  
  25.   return -1; 
#include "cv.h"
#include "highgui.h"

int main( int argc, char** argv )
{
  IplImage* pImg; //聲明IplImage指針

  //載入圖像,強制轉化爲Gray
  if( argc == 3 &&
      (pImg = cvLoadImage( argv[1], 0)) != 0 )
    {

      IplImage* pImg2 = cvCreateImage(cvGetSize(pImg),
				      pImg->depth,
				      pImg->nChannels);
      cvCopy(pImg, pImg2, NULL);

      cvSaveImage(argv[2], pImg2);//把圖像寫入文件


      cvReleaseImage( &pImg ); //釋放圖像
      cvReleaseImage( &pImg2 ); //釋放圖像
      return 0;
    }

  return -1;
}

下面說一下我的編譯方法。依然使用DVSDK中的交叉編譯鏈。
我爲了方便將main.cpp拷入/home/yr/ti-dvsdk_omapl138-evm_04_03_00_06/linux-devkit/bin文件夾,即交叉編譯器所在文件夾
並且在終端中進入。直接
cd /home/yr/ti-dvsdk_omapl138-evm_04_03_00_06/linux-devkit/bin
 
在終端運行如下命令(此命令爲手動輸入庫文件極其目錄的方法):
./arm-arago-linux-gnueabi-gcc main.cpp -o main1 -I/usr/local/arm/include/opencv -I/usr/local/arm/include -L/usr/local/arm/lib -lpthread -ldl -lopencv_core -lrt -lopencv_highgui
然後出現了警告:
/home/yr/ti-dvsdk_omapl138-evm_04_03_00_06/linux-devkit/bin/../lib/gcc/arm-arago-linux-gnueabi/4.3.3/../../../../arm-arago-linux-gnueabi/bin/ld: warning: ../../lib/libopencv_core.so, needed by /usr/local/arm/lib/libopencv_highgui.so, not found (try using -rpath or -rpath-link)
/home/yr/ti-dvsdk_omapl138-evm_04_03_00_06/linux-devkit/bin/../lib/gcc/arm-arago-linux-gnueabi/4.3.3/../../../../arm-arago-linux-gnueabi/bin/ld: warning: ../../lib/libopencv_imgproc.so, needed by /usr/local/arm/lib/libopencv_highgui.so, not found (try using -rpath or -rpath-link)
這個問題是因爲交叉編譯器沒有找到這兩個庫(網上是這麼說的)。我將libopencv_core.so,libopencv_imgproc.so,這兩個庫拷貝到了
/home/yr/ti-dvsdk_omapl138-evm_04_03_00_06/linux-devkit/lib   中,即交叉編譯器的lib中。
然後再運行編譯命令。就ok了。沒有任何錯誤和警告了。
 
這裏要說明的是:
./arm-arago-linux-gnueabi-gcc main.cpp -o main1 -I/usr/local/arm/include/opencv -I/usr/local/arm/include -L/usr/local/arm/lib -lpthread -ldl -lrt -lopencv_core  -lopencv_highgui
這個命令中。-I後面都是頭文件include目錄。-L後面是庫文件目錄。而那些帶 - 的參數,就是我們要用到的庫文件,這個例子裏我只用到了
libopencv_core.so和libopencv_highgui.so這兩個庫,所以就只有-lopencv_core -lopencv_highgui這兩個。
要是程序用到了其他庫,那麼在參數後面添加就行了。
 
/*以下是更新部分
以上是編譯程序的第一種方法,另外一種便是通過配置
/usr/local/lib/pkgconfig中的opencv.pc文件並使用  `pkg-config --cflags --libs opencv`  來進行編譯
 
這種方法面去了輸入一大堆配置參數的麻煩。建議使用這種方法
 
因爲我在以前安裝過PC版的正常的opencv,所以在/usr/local/lib/pkgconfig裏會有opencv.pc這個文件。
如果以前沒有安裝過,可能就沒有這個文件,可以嘗試自己新建一個,應該也行。
 
首先 sudo gedit /usr/local/lib/pkgconfig/opencv.pc
將第一行的
prefix=/usr/local  更改爲
prefix=/usr/local/arm     這個目錄在cmake配置的時候提到過。即arm的opencv的安裝目錄。
然後再在Libs里加入-lpthread -lrt。
下面將整個opencv.pc文件貼出。
  1. # Package Information for pkg-config 
  2.  
  3. prefix=/usr/local/arm 
  4. exec_prefix=${prefix} 
  5. libdir=${exec_prefix}/lib 
  6. includedir_old=${prefix}/include/opencv 
  7. includedir_new=${prefix}/include 
  8.  
  9. Name: OpenCV 
  10. Description: Open Source Computer Vision Library 
  11. Version: 2.3.1 
  12. Libs: -L${libdir} -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_ml -lopencv_video -lopencv_features2d -lopencv_calib3d -lopencv_objdetect -lopencv_contrib -lopencv_legacy -lopencv_flann -lpthread -lrt 
  13. Cflags: -I${includedir_old} -I${includedir_new} 
# Package Information for pkg-config

prefix=/usr/local/arm
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir_old=${prefix}/include/opencv
includedir_new=${prefix}/include

Name: OpenCV
Description: Open Source Computer Vision Library
Version: 2.3.1
Libs: -L${libdir} -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_ml -lopencv_video -lopencv_features2d -lopencv_calib3d -lopencv_objdetect -lopencv_contrib -lopencv_legacy -lopencv_flann -lpthread -lrt
Cflags: -I${includedir_old} -I${includedir_new}
保存了opencv.pc之後,建議將/usr/local/arm/lib  裏的13個文件都複製進/home/yr/ti-dvsdk_omapl138-evm_04_03_00_06/linux-devkit/lib 中,
不然會出現類似與上面藍色字體的警告。
進入/home/yr/ti-dvsdk_omapl138-evm_04_03_00_06/linux-devkit/bin目錄,並運行命令
./arm-arago-linux-gnueabi-gcc `pkg-config --cflags --libs opencv` main.cpp -o main  
 

總結:依靠上面資料是可以完成opencv庫的編譯。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章