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库的编译。

 

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