Opencv-2.0.0的ARM移植和使用(Ubuntu10.04 / OK6410開發板 / linux3.01)

環境:

Ubuntu10.04

OK6410開發板

ARM Linux3.01系統

QT4.7.1

OpenCV-2.0.0

arm-linux-g++ 4.3.2 / arm-linux-gcc 4.3.2

CMake-gui 2.8.0

(建議先參考我的另外一篇博文Ubuntu上安裝Opencv-2.0.0)


特別標註:

有些網站轉載我的文章不標明出處,並且轉載不到位,沒有把相應的鏈接一塊轉過去,比如說下載鏈接或相關文獻的鏈接等,導致一些網友閱讀和使用出現障礙和知識的不連續,所以在此特別標註:我的這篇文章發表在CSDN博客上,可以到CSDN博客來閱讀。


OpenCV2.0.0交叉編譯過程:

1、在usr/local新建文件夾

# mkdir opencv

把下載的OpenCV-2.0.0.tar.bz2解壓到 usr/local/opencv 目錄下

2、然後在usr/local/opencv  新建一個 opencv-arm 文件夾,作爲CMake編譯arm版本的工作目錄

# mkdir opencv-arm

如下圖所示:

3、在終端裏調出CMake gui界面:

# cmake-gui

按照下圖方式選擇源碼目錄和build目錄

然後點擊Configure按鈕,保持generator爲Unix Makefiles,選擇Specify options for cross-compiling,點擊Next

按照如下方式配置:

注:/usr/local/arm/4.3.2 爲交叉編譯工具 arm-linux-g++/gcc 的所在包含文件夾(在bin文件夾裏面)

然後點擊 “Finish” 按鈕;

修改默認配置,默認安裝目錄爲/usr/local,但我想對它統一歸類,所以我在/usr/local/arm/4.3.2/lib目錄下新建了一個opencv文件夾,在Cmake-gui裏修改CMAKE_INSTALL_PREFIX變量改爲/usr/local/arm/4.3.2/lib/opencv/

(另外,如果沒有安裝tiff圖像的支持,請去掉WITH_TIFF)

然後點擊Generate按鈕生成Makefile;

4、在終端界面中,進入目錄/usr/local/opencv/opencv-arm,運行make編譯opencv

編譯時發現如下錯誤:
Linking CXX executable ../../bin/opencv_createsamples
../../lib/libcxcore.so: undefined reference to `clock_gettime'
../../lib/libcxcore.so: undefined reference to `pthread_key_create'
../../lib/libcxcore.so: undefined reference to `pthread_getspecific'
../../lib/libcxcore.so: undefined reference to `pthread_setspecific'

原因是cmake不認識我定義的arm-linux系統標記,沒有加上庫pthread和rt的鏈接選項

此時需要修改CMakeCache.txt,CMAKE_EXE_LINKER_FLAGS原來爲空,加上-lpthread -lrt,如下圖:

重新make編譯,錯誤消除,編譯成功之後的界面如下:

5、然後運行make install,將opencv生成的庫和頭文件安裝到目錄/usr/local/arm/4.3.2/lib/opencv/,結果如下:

6、把這5個 .so 庫文件拷貝到ARM板系統中的 /lib 目錄下面:(如下是添加之後的截圖)

  

7、下來就是編寫驗證程序了:

首先得確保攝像頭在ARM板上的使用是正常的,具體情況請查閱我的另外一篇博文:

《攝像頭在liunx上的QT顯示和OK6410 ARM開發板上的使用》

在這篇文章裏我曾提到過要使用opencv,但是攝像頭出來的是UVC格式,所以我要走一個圖像轉換流程:UVC轉QImage轉IplImage;

8、還是那個簡單思路:現在ubuntu PC上實現,然後再移植至ARM上;

具體工程代碼下載請看附錄。

主要涉及opencv的代碼如下:

  1. void Widget::paintEvent(QPaintEvent *)  
  2. {  
  3.     uchar * pImgBuf;  
  4.     unsigned int len;  
  5.     camReturn = m_camera->get_frame((void **)&pImgBuf,&len);  
  6.     convert_yuv_to_rgb_buffer(pImgBuf,imgBuf,image_width,image_height);  
  7.     frame->loadFromData((uchar *)imgBuf,/*len*/image_width * image_height * 3 * sizeof(char));  
  8.   
  9.     IplImage* src = QImageToIplImage(frame);  
  10.     if (!src)  
  11.     {  
  12.         printf("img error!");  
  13.         return;  
  14.     }  
  15.   
  16.     //更改圖像大小(後期對人臉檢測時間控制會有很大幫助)  
  17.     double sizeScale = imgSizeScaleSmall;  
  18.     CvSize img_cvsize;  
  19.     img_cvsize.width = src->width * sizeScale;  
  20.     img_cvsize.height = src->height * sizeScale;  
  21.     IplImage* dst = cvCreateImage(img_cvsize, src->depth, src->nChannels);  
  22.     cvResize(src, dst, CV_INTER_LINEAR);    //opencv函數更改圖片大小  
  23.   
  24. //    cvSaveImage("jason.jpg", src);    //ARM對opencv的highgui支持極其差,這個函數不能使用  
  25.   
  26.     //更改圖像大小,清晰度會下降  
  27.     sizeScale = imgSizeScaleBig;  
  28.     img_cvsize.width = dst->width * sizeScale;  
  29.     img_cvsize.height = dst->height * sizeScale;  
  30.     IplImage* img = cvCreateImage(img_cvsize, dst->depth, dst->nChannels);  
  31.     cvResize(dst, img, CV_INTER_LINEAR);  
  32.   
  33.     QImage qimage = QImage((uchar *)img->imageData, img->width,img->height, image_Format);  
  34.     //IplImage爲BGR格式,QImage爲RGB格式,所以要交換B和R通道顯示才正常  
  35.     //可以用OpenCV的cvConcertImage函數交換,也可以用QImage的rgbSwapped函數交換;  
  36.     qimage = qimage.rgbSwapped();  
  37.     ui->m_imgLabel->setPixmap(QPixmap::fromImage(qimage));  
  38.     camReturn = m_camera->unget_frame();  
  39.   
  40.     cvReleaseImage(&img);   //釋放圖片內存  
  41.     cvReleaseImage(&src);  
  42. }  

其中,QImage轉IplImage的處理函數如下:(在此感謝此篇博文的幫助:關於QImage和IplImage之間轉換的實現

  1. IplImage* Widget::QImageToIplImage(const QImage * qImage)  
  2. {  
  3.     int width = qImage->width();  
  4.     int height = qImage->height();  
  5.     CvSize Size;  
  6.     Size.height = height;  
  7.     Size.width = width;  
  8.     IplImage *IplImageBuffer = cvCreateImage(Size, IPL_DEPTH_8U, 3);  
  9.     for (int y = 0; y < height; ++y)  
  10.     {  
  11.         for (int x = 0; x < width; ++x)  
  12.         {  
  13.             QRgb rgb = qImage->pixel(x, y);  
  14.             cvSet2D(IplImageBuffer, y, x, CV_RGB(qRed(rgb), qGreen(rgb), qBlue(rgb)));  
  15.         }  
  16.     }  
  17.     return IplImageBuffer;  
  18. }  
運行結果如下圖所示:



這裏得注意一個問題,就是攝像頭的名詞,我的ubuntu上的名稱爲:/dev/video0,在ARM上爲:/dev/video2;注意修改此處的代碼



注:

對於編譯時出現的缺少或者不能打開opencv相應的文件或庫,原因是你的Makefile裏面的環境路徑配置有問題,不要把我的工程直接不做修改就拿來編譯,會出問題的,(不過編譯出來的最終程序也許可以使用)因爲我安裝的opencv路徑可能和你的不一樣,具體修改方式請打開Makefile文件,參照原來的內容進行修改。


附錄:

源碼下載:

1、Opencv2.0在PC Ubuntu上的應用

2、Opencv2.0在ARM Ok6410 linux3.0.1上的應用


參考文獻:

【1】mini6410成功移植OPENCV-2.0.0實現人臉檢測 http://blog.csdn.net/gfocean/article/details/6341155

【2】關於QImage和IplImage之間轉換的實現 http://blog.csdn.net/gfocean/article/details/6440844


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