天天看點

Linux下QT配合OpenCV完成圖像處理(實作基本的人臉檢測)

一、環境介紹

​​​

ubuntu版本:  VM虛拟機運作ubuntu18.04 64位

OpenCV版本:  3.4.9

QT版本: 5.12

OpenCV在ubuntu下的編譯方法:

https://blog.csdn.net/xiaolong1126626497/article/details/105278882

二、建立QT工程加入OpenCV依賴庫

下面編寫例子很簡單,使用OpenCV自帶的分類器,檢測一張圖中的人臉,并圈出來。

opencv源碼自帶的人臉檢測分類器目錄:opencv-3.4.9/data/haarcascades_cuda/haarcascade_frontalface_alt2.xml

xxx.pro工程檔案代碼:

QT       += core gui
 
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
 
CONFIG += c++11
 
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
 
# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
 
SOURCES += \
    main.cpp \
    widget.cpp
 
HEADERS += \
    widget.h
 
FORMS += \
    widget.ui
 
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
 
#linu平台的路徑設定
linux {
#添加opencv頭檔案的路徑,需要根據自己的頭檔案路徑進行修改
INCLUDEPATH+=/home/wbyq/work_pc/opencv-3.4.9/_install/install/include\
             /home/wbyq/work_pc/opencv-3.4.9/_install/install/include/opencv\
             /home/wbyq/work_pc/opencv-3.4.9/_install/install/include/opencv2
 
LIBS+=/home/wbyq/work_pc/opencv-3.4.9/_install/install/lib/libopencv_calib3d.so
LIBS+=/home/wbyq/work_pc/opencv-3.4.9/_install/install/lib/libopencv_core.so
LIBS+=/home/wbyq/work_pc/opencv-3.4.9/_install/install/lib/libopencv_dnn.so
LIBS+=/home/wbyq/work_pc/opencv-3.4.9/_install/install/lib/libopencv_features2d.so
LIBS+=/home/wbyq/work_pc/opencv-3.4.9/_install/install/lib/libopencv_flann.so
LIBS+=/home/wbyq/work_pc/opencv-3.4.9/_install/install/lib/libopencv_highgui.so
LIBS+=/home/wbyq/work_pc/opencv-3.4.9/_install/install/lib/libopencv_imgcodecs.so
LIBS+=/home/wbyq/work_pc/opencv-3.4.9/_install/install/lib/libopencv_imgproc.so
LIBS+=/home/wbyq/work_pc/opencv-3.4.9/_install/install/lib/libopencv_ml.so
LIBS+=/home/wbyq/work_pc/opencv-3.4.9/_install/install/lib/libopencv_objdetect.so
LIBS+=/home/wbyq/work_pc/opencv-3.4.9/_install/install/lib/libopencv_photo.so
LIBS+=/home/wbyq/work_pc/opencv-3.4.9/_install/install/lib/libopencv_shape.so
LIBS+=/home/wbyq/work_pc/opencv-3.4.9/_install/install/lib/libopencv_stitching.so
LIBS+=/home/wbyq/work_pc/opencv-3.4.9/_install/install/lib/libopencv_superres.so
LIBS+=/home/wbyq/work_pc/opencv-3.4.9/_install/install/lib/libopencv_videoio.so
LIBS+=/home/wbyq/work_pc/opencv-3.4.9/_install/install/lib/libopencv_video.so
}      

widget.cpp檔案代碼:

#include "widget.h"
#include "ui_widget.h"
 
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    opencv_face();
}
 
Widget::~Widget()
{
    delete ui;
}
 
//分類器的路徑
#define source_xml_addr "/home/wbyq/work_pc/opencv-3.4.9/data/haarcascades_cuda/haarcascade_frontalface_alt2.xml"
 
//将要檢測的圖檔路徑
#define source_pix_addr "/mnt/hgfs/linux-share-dir/1.jpg"
 
//人臉檢測代碼
void Widget::opencv_face()
{
    static CvMemStorage* storage = 0;
    static CvHaarClassifierCascade* cascade = 0;
 
    fprintf( stderr, "start------------------------------>1 \n" );
 
    const char*cascade_name =source_xml_addr;
 
    //加載分類器
    cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 );
    if( !cascade )
    {
        fprintf( stderr, "ERROR: Could not load classifier cascade\n" );
        return ;
    }
 
    //建立記憶體空間
    storage = cvCreateMemStorage(0);
 
    //加載需要檢測的圖檔
    const char* filename =source_pix_addr;
    IplImage* img = cvLoadImage( filename, 1 );
 
    if(img ==nullptr )
    {
        fprintf( stderr, "jpg load error! \n" );
        return;
    }
 
     fprintf( stderr, "start------------------------------>2 \n" );
 
    double scale=1.2;
    static CvScalar colors[] = {
        {{0,0,255}},{{0,128,255}},{{0,255,255}},{{0,255,0}},
        {{255,128,0}},{{255,255,0}},{{255,0,0}},{{255,0,255}}
    };//Just some pretty colors to draw with
 
 
    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);
    cvCvtColor(img,gray, CV_BGR2GRAY);
    cvResize(gray, small_img, CV_INTER_LINEAR);
 
    cvEqualizeHist(small_img,small_img); //直方圖均衡
 
    cvClearMemStorage(storage);
 
    double t = (double)cvGetTickCount();
    CvSeq* objects = cvHaarDetectObjects(small_img,
                                           cascade,
                                           storage,
                                           1.1,
                                           2,
                                           0/*CV_HAAR_DO_CANNY_PRUNING*/,
                                           cvSize(30,30));
 
       t = (double)cvGetTickCount() - t;
 
     fprintf( stderr, "start------------------------------>3 \n" );
 
    //周遊找到對象和周圍畫盒
    for(int i=0;i<(objects->total);++i)
    {
        CvRect* r=(CvRect*)cvGetSeqElem(objects,i);
        cvRectangle(img, cvPoint(r->x*scale,r->y*scale), cvPoint((r->x+r->width)*scale,(r->y+r->height)*scale), colors[i%8]);
    }
 
     fprintf( stderr, "start------------------------------>4 \n" );
 
    for( int i = 0; i < (objects? objects->total : 0); i++ )
    {
        CvRect* r = (CvRect*)cvGetSeqElem( objects, 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 );
    }
 
    show_face(img);  //顯示檢測的結果
 
    cvReleaseImage(&gray);
    cvReleaseImage(&small_img);
 
    //釋放圖檔
    cvReleaseImage( &img );
}
//顯示檢測的結果
void Widget::show_face(IplImage* img)
{
    /*将opecv的圖檔轉為qimage格式*/
    uchar *imgData=(uchar *)img->imageData;
 
    QImage  my_image(imgData,img->width,img->height,QImage::Format_RGB888);
    my_image =my_image.rgbSwapped(); //BGR格式轉RGB
    QPixmap my_pix; //建立畫圖類
 
    my_pix.convertFromImage(my_image);
 
    /*在控件上顯示*/
    ui->label_display_face->setPixmap(my_pix);
}      

widget.h檔案代碼:

#ifndef WIDGET_H
#define WIDGET_H
 
#include <QWidget>
//opencv include
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
 
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
 
class Widget : public QWidget
{
    Q_OBJECT
 
public:
    Widget(QWidget *parent = nullptr);
    void opencv_face();
    ~Widget();
    void show_face(IplImage* img);
private:
    Ui::Widget *ui;
};
#endif // WIDGET_H      

運作代碼檢測結果如下:

Linux下QT配合OpenCV完成圖像處理(實作基本的人臉檢測)

繼續閱讀