mini6410成功移植OPENCV-2.0.0實現人臉檢測

     研究這個東西很長時間了,以前是想在arm9上實現這個東西,但是夭折了,現在正好手裏面有mini6410的板子,而且對浮點數運算支持較好。所以就試了試。

實現的功能:移植opencv-2.0.0到mini6410,利用QT圖形庫實現人臉檢測。在mini6410上利用Video for Linux接口和QT圖形庫,對攝像頭數據進行採集和顯示,在利用opencv的函數對採集的一幀圖片進行處理。在利用QT圖形庫進行顯示。
開發環境及工具:

ubuntu10.10 gcc version 4.4.5 
arm-linux-gcc-4.4.1 
qt-4.7.2
opencv-2.0.0

1.開發環境的搭建
主要是交叉編譯安裝qt-4.7.2和交叉編譯安裝opencv-2.0.0
他們的配置文件分別是:
(1)qt-4.7.2
./configure -qt-kbd-tty -qt-gfx-linuxfb -no-gfx-transformed -no-gfx-multiscreen -qt-mouse-pc -no-gfx-qvfb -no-gfx-vnc -qt-kbd-tty -qt-gfx-linuxfb -no-gfx-qvfb -no-gfx-vnc -qt-mouse-tslib -no-glib -prefix /usr/local/arm/QtEmbedded-4.7.2-arm-4.4.1 -embedded arm -release -shared -fast -no-largefile -qt-sql-sqlite -no-qt3support -no-xmlpatterns -no-mmx -no-3dnow -no-sse -no-sse2 -no-svg -no-webkit -qt-zlib -qt-gif -qt-libtiff -qt-libpng -qt-libmng -qt-libjpeg -make libs -nomake tools -nomake examples -nomake docs -nomake demo -no-nis -no-cups -no-iconv -no-dbus -no-openssl -xplatform qws/linux-arm-g++ -little-endian -qt-freetype -depths 16,18,24 -I/usr/local/arm/tslib/include -L/usr/local/arm/tslib/lib -v -D__ARM_ARCH_5TEJ__
(2)opencv-2.0.0
./configure --host=arm-linux --without-carbon --without-quicktime --without-1394libs --without-ffmpeg --without-python --without-swig --without-gtk --enable-static --disable-shared --disable-apps

配置之後顯示
HighGUI configuration ================================================

    Windowing system --------------
    Use Carbon / Mac OS X:    no
    Use gtk+ 2.x:             no
    Use gthread:              no

    Image I/O ---------------------
    Use ImageIO / Mac OS X:   no
    Use libjpeg:              yes
    Use zlib:                 yes
    Use libpng:               yes
    Use libtiff:              no
    Use libjasper:            no
    Use libIlmImf/OpenEXR:    no

    Video I/O ---------------------
    Use QuickTime / Mac OS X: no
    Use xine:                 no
    Use gstreamer:            no
    Use ffmpeg:               no
    Use dc1394 & raw1394:     no
    Use dc1394_v2 & raw1394:  no
    Use v4l:                  yes
    Use v4l2:                 yes
    Use unicap:               no

Wrappers for other languages =========================================

    SWIG                      
    Python                    no
    Octave                    no

Additional build settings ============================================

    Build demo apps           no

Now run make ...
如果大家可以把ffmpeg也編譯上,那麼編寫攝像頭採集程序的時候就可以不用寫採集的程序了。直接調用opencv的顯示函數就可以拉。但是我一直不能把他編譯到opencv中,所以就自己寫的採集的程序。

然後就是make 和make install拉。祝大家順利!

然後就是編寫程序拉。大致的思路我說一下,因爲移植gtk是相對比較複雜的,在嵌入式linux下。我們常用的圖形庫就是QT拉,所以我們主要的目的就是。利用V4l程序把攝像頭的圖像數據讀出來,然後把圖像數據顯示QLabel上,主要是利用QPixmap讀數據和顯示。在將想要人臉檢測的圖像保存到本地。

保存圖像代碼
    unsigned char * pBuffer =video_dev.buffer;
    fp=fopen("./photo.jpg","w");
    fwrite(pBuffer,12000,1,fp);
    fclose(fp);
在利用IplImage把圖片讀到內存中。接着就是對他進行人臉檢測處理。
void photo::detect_and_draw(IplImage *img)
{
    static CvScalar colors[] =
    {
        {{0,0,255}},
        {{0,128,255}},
        {{0,255,255}},
        {{0,255,0}},
        {{255,128,0}},
        {{255,255,0}},
        {{0,255,0}},
        {{255,0,255}}
    };

    double scale = 2;
    //建立一個空的灰度圖
    IplImage* gray = cvCreateImage( cvSize(img->width,img->height), 8, 1 );
    //建立一個空圓形的灰度圖
    IplImage* small_img = cvCreateImage( cvSize( cvRound (img->width/scale),
                         cvRound (img->height/scale)),
                     8, 1 );
    int i;
    //圖像轉換RGB模式轉爲灰度圖
    cvCvtColor( img, gray, CV_BGR2GRAY );

    cvResize( gray, small_img, CV_INTER_LINEAR );
    cvEqualizeHist( small_img, small_img );
    cvClearMemStorage( storage );

    if( cascade )
    {
        double t = (double)cvGetTickCount();
        CvSeq* faces = cvHaarDetectObjects( small_img, cascade, storage,
                                            1.1, 2, 0/*CV_HAAR_DO_CANNY_PRUNING*/,
                                            cvSize(30, 30) );
        t = (double)cvGetTickCount() - t;
        printf( "detection time = %gms/n", t/((double)cvGetTickFrequency()*1000.) );

        for( i = 0; i < (faces ? faces->total : 0); i++ )
        {
            CvRect* r = (CvRect*)cvGetSeqElem( faces, i );
            CvPoint center;
            int radius;
            center.x = cvRound((r->x + r->width*0.5)*scale);
            center.y = cvRound((r->y + r->height*0.5)*scale);
            radius = cvRound((r->width + r->height)*0.25*scale);
            //cvCircle( img, center, radius, colors[i%8], 3, 8, 0 );
            cvRectangle(img,cvPoint(center.x-radius,center.y-radius),cvPoint(center.x+radius,center.y+radius),colors[i%8],3,8,0);
            //cvRect(center.x-radius,center.y-radius,center.x+radius,center.y+radius);

        }
    }
}
最後就是將IplImage轉換爲QImage格式
    cvCvtColor(img,img,CV_BGR2RGB);
    uchar *imgData=(uchar *)img->imageData;
    image=new QImage(imgData,img->width,img->height,QImage::Format_RGB888);

然後利用QPainter把QImage畫出來。
大體的代碼和思路就是這樣子。目前就是先單獨一幀的處理和圖片的顯示。處理一幀的時間目前是1s左右,我優化了之後估計可以達到0.5s。如果在視頻中畫出來在顯示,效果不是很理想(比較卡)。

之後就是移植過程了,這個就不多說拉。大家把opencv需要的庫拷到板子上就OK拉。
最後看看圖片吧。拍的不好,大家見諒。


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