環境:
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的代碼如下:
- void Widget::paintEvent(QPaintEvent *)
- {
- uchar * pImgBuf;
- unsigned int len;
- camReturn = m_camera->get_frame((void **)&pImgBuf,&len);
- convert_yuv_to_rgb_buffer(pImgBuf,imgBuf,image_width,image_height);
- frame->loadFromData((uchar *)imgBuf,/*len*/image_width * image_height * 3 * sizeof(char));
- IplImage* src = QImageToIplImage(frame);
- if (!src)
- {
- printf("img error!");
- return;
- }
- //更改圖像大小(後期對人臉檢測時間控制會有很大幫助)
- double sizeScale = imgSizeScaleSmall;
- CvSize img_cvsize;
- img_cvsize.width = src->width * sizeScale;
- img_cvsize.height = src->height * sizeScale;
- IplImage* dst = cvCreateImage(img_cvsize, src->depth, src->nChannels);
- cvResize(src, dst, CV_INTER_LINEAR); //opencv函數更改圖片大小
- // cvSaveImage("jason.jpg", src); //ARM對opencv的highgui支持極其差,這個函數不能使用
- //更改圖像大小,清晰度會下降
- sizeScale = imgSizeScaleBig;
- img_cvsize.width = dst->width * sizeScale;
- img_cvsize.height = dst->height * sizeScale;
- IplImage* img = cvCreateImage(img_cvsize, dst->depth, dst->nChannels);
- cvResize(dst, img, CV_INTER_LINEAR);
- QImage qimage = QImage((uchar *)img->imageData, img->width,img->height, image_Format);
- //IplImage爲BGR格式,QImage爲RGB格式,所以要交換B和R通道顯示才正常
- //可以用OpenCV的cvConcertImage函數交換,也可以用QImage的rgbSwapped函數交換;
- qimage = qimage.rgbSwapped();
- ui->m_imgLabel->setPixmap(QPixmap::fromImage(qimage));
- camReturn = m_camera->unget_frame();
- cvReleaseImage(&img); //釋放圖片內存
- cvReleaseImage(&src);
- }
其中,QImage轉IplImage的處理函數如下:(在此感謝此篇博文的幫助:關於QImage和IplImage之間轉換的實現)
- IplImage* Widget::QImageToIplImage(const QImage * qImage)
- {
- int width = qImage->width();
- int height = qImage->height();
- CvSize Size;
- Size.height = height;
- Size.width = width;
- IplImage *IplImageBuffer = cvCreateImage(Size, IPL_DEPTH_8U, 3);
- for (int y = 0; y < height; ++y)
- {
- for (int x = 0; x < width; ++x)
- {
- QRgb rgb = qImage->pixel(x, y);
- cvSet2D(IplImageBuffer, y, x, CV_RGB(qRed(rgb), qGreen(rgb), qBlue(rgb)));
- }
- }
- return IplImageBuffer;
- }
這裏得注意一個問題,就是攝像頭的名詞,我的ubuntu上的名稱爲:/dev/video0,在ARM上爲:/dev/video2;注意修改此處的代碼
注:
對於編譯時出現的缺少或者不能打開opencv相應的文件或庫,原因是你的Makefile裏面的環境路徑配置有問題,不要把我的工程直接不做修改就拿來編譯,會出問題的,(不過編譯出來的最終程序也許可以使用)因爲我安裝的opencv路徑可能和你的不一樣,具體修改方式請打開Makefile文件,參照原來的內容進行修改。
附錄:
源碼下載:
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