一、环境介绍 操作系统: windows10 64位
qt版本: 5.12.6 (我的程序里主要是qt+opencv实现图像处理显示的)
opencv版本: opencv3.4.7
二、下载安装opencv windows下不用下载源码,可以直接在官网下载编译好的文件解压即可使用。
opencv官网下载地址: https://opencv.org/releases/ 下载之后解压到指定目录即可,我这里是直接解压到c盘的。
因为在官网下载的版本是vc版本,而我的qt使用的是mingw编译器,上面下在官网下载的安装包里的库用不了,需要再下载一个mingw版本。 下载地址:https://github.com/huihut/opencv-mingw-build
为什么需要下载两个版本? 其实主要是mingw版本的opencv里带的两个训练分类器(opencv_traincascade.exe)的文件在我电脑上无法使用,可能库冲突,具体问题没有深究,就干脆再下载了一个vc版本是opencv,vc版本里opencv_traincascade.exe文件是可以正常使用。 其实下载的vc版本opencv主要是为了用这两个文件(opencv_traincascade.exe、opencv_createsamples.exe)
三、测试opencv自带的分类器 3.1 自带的分类器文件介绍 opencv的官方已经提供了很多训练好的分类器文件,在opencv的安装目录下有。
上面文件中提供了常见的 人脸检测、眼睛检测、猫脸检测、行人检测等,看xml文件的命名即可得知。
下面编写qt程序,调用opencv的级联分类器进行测试。
3.2 qt的示例代码 下面的qt界面很简单,主要是为了测试分类器文件。
xxx.cpp文件代码:
#include widget.h#include ui_widget.hwidget::widget(qwidget *parent) : qwidget(parent) , ui(new ui::widget){ ui->setupui(this); dir=c:/; ui->label_source->setalignment(qt::alignvcenter); ui->label_2->setalignment(qt::alignvcenter);}widget::~widget(){ delete ui;}qimage widget::mat2qimage(const mat& mat){ // 8-bits unsigned, no. of channels = 1 if(mat.type() == cv_8uc1) { qimage image(mat.cols, mat.rows, qimage::format_indexed8); // set the color table (used to translate colour indexes to qrgb values) image.setcolorcount(256); for(int i = 0; i < 256; i++) { image.setcolor(i, qrgb(i, i, i)); } // copy input mat uchar *psrc = mat.data; for(int row = 0; row < mat.rows; row ++) { uchar *pdest = image.scanline(row); memcpy(pdest, psrc, mat.cols); psrc += mat.step; } return image; } // 8-bits unsigned, no. of channels = 3 else if(mat.type() == cv_8uc3) { // copy input mat const uchar *psrc = (const uchar*)mat.data; // create qimage with same dimensions as input mat qimage image(psrc, mat.cols, mat.rows, mat.step, qimage::format_rgb888); return image.rgbswapped(); } else if(mat.type() == cv_8uc4) { // copy input mat const uchar *psrc = (const uchar*)mat.data; // create qimage with same dimensions as input mat qimage image(psrc, mat.cols, mat.rows, mat.step, qimage::format_argb32); return image.copy(); } else { return qimage(); }}//打开本地图片void widget::on_pushbutton_open_clicked(){ filename=qfiledialog::getopenfilename(this,选择打开的文件,dir,tr(*.bmp *.jpg *.png)); if(filename.isempty())return; qfileinfo info(filename); dir=info.path(); //保存当前路径}//人脸检测代码void widget::opencv_face(qimage qimage){ qtime time; time.start(); //定义级联分类器 cascadeclassifier face_cascade; //加载分类文件 // if( !face_cascade.load(c:/opencv_3.4.7/opencv-mingw-build-opencv-3.4.7/etc/haarcascades/haarcascade_frontalcatface.xml) ) { qdebug()< pos.txt 打开生成的pos.txt文件内容如下。
将文件的内容稍作修改,加上检测目标个数、目标图片左上位置坐标、图片宽高参数。
我这里准备的样本图片尺寸都是40x40,所以填写的代码:1 0 0 40 40
修改效果如下:
如果图片数量很大,手动修改比较麻烦, 直接使用文本编辑器,搜索替换即可。
****
3.3 创建负样本描述文件 负样本描述文件创建方法与正样本描述文件一样,进入到负样本图片的目录下,生成neg.txt文件,代码如下:
命令1:cd /d d:\linux-share-dir\opencv_trainingdata\negativesample命令2:dir /b/s/p/w *.jpg > neg.txt 注意:负样本neg.txt文件不需要做任何修改,以下就是最终文件。
3.4 生成正样本的.vec文件 为了方便填路径,将生成的正负样本描述文件pos.txt和neg.txt拷贝到上层目录下。
正样本的.vec文件生成,执行命令如下:
命令1:cd /d d:\linux-share-dir\opencv_trainingdata命令2:c:\opencv_3.4.7\opencv-vc-3.4.7\build\x64\vc15\bin\opencv_createsamples.exe -vec pos.vec -info pos.txt -num 54 -w 40 -h 40 参数介绍:
opencv_createsamples.exe: 生成样本描述文件的可执行程序(opencv自带),前面是我电脑上的路径。
-vec pos.vec 指定生成的vec文件
-info pos.txt 指定源样本的描述文件
-num 54 指定标定目标样本总数量,就是样本描述文件里所有第2列的数字之和。
-w 40 指定样本缩放后的宽,如果之前图片不是40,那么这里就会缩放成40,有了这个参数就可以省去之前的图片处理过程。
-h 40 指定样本缩放后的高,如果之前图片不是40,那么这里就会缩放成40,有了这个参数就可以省去之前的图片处理过程。
我电脑上opencv的安装路径:
生成结果如下:
****
执行成功之后在当前目录下生成pos.vec文件。
说明: 负样本不需要生成vec文件。
3.5 开始训练样本命令1:cd /d d:\linux-share-dir\opencv_trainingdata命令2:c:\opencv_3.4.7\opencv-vc-3.4.7\build\x64\vc15\bin\opencv_traincascade.exe -data xml -vec pos.vec -bg neg.txt -numpos 50 -numneg 133 -numstages 20 -w 40 -h 40 -mode all 参数介绍:
-data 指定输出目录,训练生成的xml文件就放在这个目录下
-vec 指定正样本生成的 vec 文件
-bg 指定负样本数据文件,即前面生成的neg.txt文件
-numpos 指定正样本数目,这个数值一定要比准备正样本时的数目少,不然会报 can not get new positive sample。
参考理由:minhitrate:影响每个强分类器阈值,当设置为0.95时如果正训练样本个数为10000个,那么其中的500个就很可能背叛别为负样本,第二次选择的时候必须多选择后面的500个,按照这种规律我们为后面的每级多增加numpos*minhitrate个正样本,根据训练的级数可以得到如下公式
numpos+(numstages-1)numpos(1-minhitrate)《=准备的训练样本
以上式子也只是根据训练级数和准备的正样本总和设置一个参与训练的正样本个数,只能作为估算,小于计算出来的数可能没有问题,但是大于那个数肯定有问题
现在解释下”可能有问题“是如何理解的:因为我们总是默认每次添加固定个数的正训练样本,但是有时候后面的固定个数的正训练样本中也可能存在不满足条件的样本,这些样本跟我们排除的样本类似,所以比如我们打算添加500个样本就够了,但是实际需要添加600个,这时候就出现问题了。
从上面例子的结果中可以看出,每级我们允许丢掉12000*0.001个正样本=12,需要注意的是万一第11个或者第10个跟第12个的阈值是一样的,那么我们之丢掉了前面的10个或者9个而已,因此每次增加的个数可能要小于12个,大于12个的情况就是上面所说的”可能有问题“。
-numstages 指定训练级数
-numneg 指定负样本数目
-w 40 -h 40 指定样本图尺寸
-mode 指定haar特征的种类,basio仅仅使用垂直特征,al1表示使用垂直以及45度旋转特征
开始训练:
训练成功之后在xml目录下会生成cascade.xml文件,这个文件就是最终训练成功的文件,可以替换到到上面代码里测试。
科创板安集科技董事、董事长、总经理Shumin Wang介绍、履历信息
探讨DLTAP713SD芯片在智能吸奶器中的应用
2018年全年全球智能手表出货量创4500万台历史新高 苹果依然稳
AR助力新印刷技术发展 BizBash计划投放AR元素
无人机投放的塑料包也引来的许多以色列路人的注意?
OpenCV编程:OpenCV3.X训练自己的分类器
电动汽车用动力电池应满足的要求
浅谈单片机的程序执行过程
Fusion Debug调试系统的各项技术、指标介绍
oppor11怎么样?r11拍照效果媲美单反
净水器到底有多少科技含量?
NASA正在与蓝色起源合作发展商用月球着陆器
美国通用电器公司(GE)转向新电池储能平台
六款值得种草的便携蓝牙音箱
全球嵌入式技术和物联网发展趋势
过电压保护器使用场景受到哪些限制
一文解读域名系统(DNS),了解其的工作原理和基础知识
如何选择合适的DAQ软件
DVD光驱间隔性不读盘的解决方案
现场直击丨艾迈斯欧司朗亮点纷呈,闪耀electronica 2022