一、环境介绍
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
运行代码检测结果如下: