windows下Qt调用opencv完成目标检测

网友投稿 959 2022-05-29

windows下Qt调用opencv完成目标检测

一、前言

OpenCV是开源的计算机视觉、机器学习软件库,其图片处理的功能非常强大,并且速度很快。

作为目标检测功能,OpenCV里本身就自带了很多的模型,比如: 人眼检测、鼻子检测、嘴巴检测、人脸检测、人体检测、猫脸检测等等,下载完OpenCV,就能直接进行图像识别测试体验,并且OpenCV也可以直接调用YOLO的模型,精确识别各种物体,yolo v3 里自带的模型文件可以精确识别常见的很多物体: 比如: 狗、汽车、自行车、人体、书本、手机等等。

这篇文章就介绍在Qt里如何部署opencv环境,完成目标物体检测。

二、部署OpenCV开发环境

首先介绍我的开发环境:

我分别使用常用的两种编译器部署OpenCV环境。

MSVC 2017 64位

MinGW 730 32位

OpenCV的官网-: https://opencv.org/releases/page/3/

OpenCV 在2.X版本的时候还有x86的库,从3.X版本开始就只有x64的库,并且只是支持MSVC编译器。

目前我使用的OpenCV版本是: OpenCV 3.4.7

-就是上面的地址,直接向下翻就可以找到这个版本。

下载下来是一个exe文件,双击就可以安装,实际就是解压,可以选择解压的路径,解压出来的文件包含源文件、库文件一大堆,比较大,可以直接放在一个固定的目录,后面程序里直接填路径来调用即可。 这个下载下来的库文件里只包含了X64的库,适用于MSVS 64位编译器。

如果是MinGw编译器,可以从这里https://github.com/huihut/OpenCV-MinGW-Build下载对应的OpenCV库进行使用。

GitHub的地址在CodeChina有镜像,可以从这里去下载,速度比较快:https://gitcode.net/mirrors/huihut/opencv-mingw-build?utm_source=csdn_github_accelerator

打开链接后,自己去选择适合自己编译器的版本,我的MinGW是730刚好就使用下面这个版本。

下面分别介绍VS2017 64位编译器和MinGW 32位编译器如何引用OpenCV的库。

MSVC 64位编译器–QT的xx.pro工程文件里的写法

INCLUDEPATH += C:/opencv/build/include\ INCLUDEPATH += C:/opencv/build/include/opencv\ INCLUDEPATH += C:/opencv/build/include/opencv2 LIBS += -LC:/opencv/build/x64/vc14/lib\ -lopencv_world347d LIBS += -LC:/opencv/build/x64/vc14/lib\ -lopencv_world347

MinGW 32位编译器–QT的xx.pro工程文件里的写法

INCLUDEPATH+=C:/OpenCV-MinGW-Build-OpenCV-3.4.7/include \ C:/OpenCV-MinGW-Build-OpenCV-3.4.7/include/opencv \ C:/OpenCV-MinGW-Build-OpenCV-3.4.7/include/opencv2 LIBS+=C:/OpenCV-MinGW-Build-OpenCV-3.4.7/x86/mingw/bin/libopencv_*.dll

工程编程成功之后,需要将OpenCV对应的dll文件拷贝到exe同级目录,否则运行时找不到dll会导致程序异常结束。 这些dll文件就是在OpenCV的bin目录下。

三、调用OpenCV完成目标检测(以人脸检测为例)

OpenCV自带的模型文件在C:\opencv\sources\data\haarcascades_cuda 这个目录下。

这个就是人脸检测模型文件:

OpenCV完成目标检测有两种调用方法。

3.1 方法1: cvHaarDetectObjects

//人脸检测代码 void ImageHandle::opencv_face(QImage qImage) { QTime time; time.start(); static CvMemStorage* storage = nullptr; static CvHaarClassifierCascade* cascade = nullptr; //加载分类器:正面脸检测 cascade = (CvHaarClassifierCascade*)cvLoad("C:/opencv/sources/data/haarcascades_cuda/haarcascade_frontalface_alt2.xml", 0, 0, 0 ); if(!cascade) { qDebug()<<"分类器加载错误.\n"; return ; } //创建内存空间 storage = cvCreateMemStorage(0); //加载需要检测的图片 IplImage* img = QImageToIplImage(&qImage); if(img ==nullptr ) { qDebug()<<"图片加载错误.\n"; return; } 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); cvCvtColor(img,gray, CV_BGR2GRAY); cvResize(gray, small_img, CV_INTER_LINEAR); cvEqualizeHist(small_img,small_img); //直方图均衡 /* * 指定相应的人脸特征检测分类器,就可以检测出图片中所有的人脸,并将检测到的人脸通过矩形的方式返回。 * 总共有8个参数,函数说明: 参数1:表示输入图像,尽量使用灰度图以加快检测速度。 参数2:表示Haar特征分类器,可以用cvLoad()函数来从磁盘中加载xml文件作为Haar特征分类器。 参数3:用来存储检测到的候选目标的内存缓存区域。 参数4:表示在前后两次相继的扫描中,搜索窗口的比例系数。默认为1.1即每次搜索窗口依次扩大10% 参数5:表示构成检测目标的相邻矩形的最小个数(默认为3个)。如果组成检测目标的小矩形的个数和小于 min_neighbors - 1 都会被排除。如果min_neighbors 为 0, 则函数不做任何操作就返回所有的被检候选矩形框,这种设定值一般用在用户自定义对检测结果的组合程序上。 参数6:要么使用默认值,要么使用CV_HAAR_DO_CANNY_PRUNING,如果设置为CV_HAAR_DO_CANNY_PRUNING,那么函数将会使用Canny边缘检测来排除边缘过多或过少的区域,因此这些区域通常不会是人脸所在区域。 参数7:表示检测窗口的最小值,一般设置为默认即可。 参数8:表示检测窗口的最大值,一般设置为默认即可。 函数返回值:函数将返回CvSeq对象,该对象包含一系列CvRect表示检测到的人脸矩形。 */ CvSeq* objects = cvHaarDetectObjects(small_img, cascade, storage, 1.1, 3, 0/*CV_HAAR_DO_CANNY_PRUNING*/, cvSize(50,50)/*大小决定了检测时消耗的时间多少*/); qDebug()<<"人脸数量:"<total; //遍历找到对象和周围画盒 QPainter painter(&qImage);//构建 QPainter 绘图对象 QPen pen; pen.setColor(Qt::blue); //画笔颜色 pen.setWidth(5); //画笔宽度 painter.setPen(pen); //设置画笔 for(int i=0;i<(objects->total);++i) { //得到人脸的坐标位置和宽度高度信息 CvRect* r=(CvRect*)cvGetSeqElem(objects,i); //将人脸区域绘制矩形圈起来 painter.drawRect(r->x*scale,r->y*scale,r->width*scale,r->height*scale); } cvReleaseImage(&gray); //释放图片内存 cvReleaseImage(&small_img); //释放图片内存 cvReleaseHaarClassifierCascade(&cascade); //释放内存-->分类器 cvReleaseMemStorage(&objects->storage); //释放内存-->检测出图片中所有的人脸 //释放图片 cvReleaseImage(&img); qDebug()<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); CV_IMAGE_ELEM( IplImageBuffer, uchar, y, x*3+0 ) = qBlue(rgb); CV_IMAGE_ELEM( IplImageBuffer, uchar, y, x*3+1 ) = qGreen(rgb); CV_IMAGE_ELEM( IplImageBuffer, uchar, y, x*3+2 ) = qRed(rgb); } } return IplImageBuffer; }

3.2 方法2: face_cascade.detectMultiScale

//人脸检测代码 void ImageHandle::opencv_face(QImage qImage) { QTime time; time.start(); //定义级联分类器 CascadeClassifier face_cascade; //加载分类文件 if(!face_cascade.load("C:/opencv/sources/data/haarcascades_cuda/haarcascade_frontalface_alt2.xml") ) { qDebug()<<"分类器加载错误"; return; } Mat frame=QImage2cvMat(qImage); cvtColor(frame, frame, COLOR_BGR2GRAY );//转换成灰度图像 std::vector faces; //正脸检测 face_cascade.detectMultiScale(frame,faces); qDebug()<

OpenCV Qt Windows

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:元启发式算法常用操作详解
下一篇:Python基础二
相关文章