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的代碼如下:

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文件,參照原來的內容進行修改。


附錄:

源碼下載:

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


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