OpevCV目标检测技术
Q1:Qt信号槽connect第五个参数
A1:
connect(th,SIGNAL(started()),tmpmyobject,SLOT(showID()));
: 当信号发送时,将确定默认值。如果接收器和发送器在同一线程中,则自动使用。Qt::DirectConnection类型。如果接收者和发送者不在同一线程中,则自动使用Qt::QueuedConnection类型。 :当信号发送时,槽函数将直接调用,槽函数将在信号发送者的线程中运行。效果看起来像是在信号发送位置直接调用槽函数。这在多线程环境中是危险的,可能会导致崩溃。 :当控制回到接收器所在线程的事件循环时,调用槽函数,并在信号接收器所在线程中运行。发送信号后,槽函数不会立即调用,直到接收器当前函数执行并进入事件循环。这通常用于多线程环境。 :调用槽函数的时机与Qt::QueuedConnection一致,但发送信号后,发送者的线程将被阻塞,直到槽函数运行。接收者和发送者不得在同一线程中,否则程序将被锁定。这可能需要在多线程之间同步。 :这个flag可按位或按位(|)结合以上四个。当这个。flag设置时,当某个信号和槽已经连接时,再进行重复的连接就会失败。也就是避免了重复连接。
一、帧差法
(一)识别原理
??比较前后两帧图像之间的差异,获取图像图像中正在移动的物体,从而实现目标检测。
(二)缺点
??图中所有的运动物都被识别。 ??例如,在检测车辆运动时,屏幕中风驱动的叶子也会计算在筛选范围内。
二、级联分类器
(1)级联分类器原理
(二) 创建分类器样本
特点:耗时耗资源
样本:正样本和负样本
??一般来说,样本基数越大,生成的分类器的精度就越高。如果检测目标是固定物体,则没有变化(如特定商标,logo等等),这样的物体只要提供样本就可以训练。 然而,大多数时候,我们想要训练的目标是非绝对固定的物体,如人类检测,包括人脸识别、汽车等。因此,创建合适的样本是非常重要的。
正样本
??正样本,只包括检测目标图片(背景最好一致)。
负样本
??负样本,即任何不包含检测目标的图片。
操作步骤
-
样本数据采集(目标检测对象照片)
-
负样本数据采集(非目标检测对象图片)
-
调用OpenCV程序opencv_createsample.exe样本数据采集程序
-
调用OpenCV程序opencv_traincascade.exe样本训练程序进行训练
-
生成级联分类器文件
(3)分类器识别过程
1. 创建级联分类器对象
创建并加载级联分类器对象。
///加载级联分类器 CascadeClassifier cascade; cascade.load("***.xml");//xxx.xml训练好的级联分类器模型
2. 创建视频流
读取待识别视频路径并显示。
Mat frame; VideoCapture cap("***");//视频路径待检测 while(cap.read(frame)) {
imshow("frame", frame);///显示读取的视频帧 detectCarTarget(frame, cascade, 2);//将读取的帧传入函数执行目标检测
waitKey(25);//帧率
}
3. 视频帧灰度处理
将读取到的视频帧进行灰度处理,压缩数据量,提升传输和计算速度。
//灰度处理:提高图像处理速度
Mat gray;
cvtColor(frame, gray, CV_RGB2GRAY);
4. 压缩多余空通道
原通道为RGB三通道图片数据,转换为灰度图后,变为单通道数据,多余的通道可以压缩掉,可以看到图片大小缩减至三分之一。
//构建压缩容器
Mat smaller(cvRound(frame.rows/scale), cvRound(frame.cols/scale), CV_8UC1);
//压缩灰度图(线性压缩)
resize(gray, smaller, smaller.size(), 0, 0, INTER_LINEAR);
5. 直方图均值化
直方图均值化:将二次压缩后的灰度图进行对比度调整。
equalizeHist(smaller, smaller);
6. 调用级联分类器
void detectMultiScale( InputArray image, CV_OUT std::vector
& objects, CV_OUT std::vector& rejectLevels, CV_OUT std::vector& levelWeights, double scaleFactor = 1.1, int minNeighbors = 3, int flags = 0, Size minSize = Size(), Size maxSize = Size(), bool outputRejectLevels = false ); :image–待检测图片,一般为灰度图像加快检测速度。 :objects–被检测物体的矩形框向量组。 :scaleFactor–表示在前后两次相继的扫描中,搜索窗口的比例系数。默认为1.1,即每次搜索窗口依次扩大10%。 :minNeighbors–表示构成检测目标的相邻矩形的最小个数(默认为3个)。 如果组成检测目标的小矩形的个数和小于 min_neighbors - 1 都会被排除。 如果min_neighbors 为 0,则函数不做任何操作就返回所有的被检候选矩形框,这种设定值一般用在用户 自定义对检测结果的组合程序上。 :flags–要么使用默认值,要么使用CV_HAAR_DO_CANNY_PRUNING,如果设置为CV_HAAR_DO_CANNY_PRUNING,那么函数将会使用Canny边缘检测来排除边缘过多或过少的区域,因此这些区域通常不会是人脸所在区域。 :minSize和maxSize用来限制得到的目标区域的范围。
//保存车辆容器
vector<Rect>cars;
//级联分类器检测 甄别车辆
cascade.detectMultiScale(smaller, cars, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(30,30));
//绘制车辆矩形框
vector<Rect>::const_iterator iter;
for(iter = cars.begin(); iter != cars.end(); iter++)
{
rectangle(frame, CvPoint(cvRound(iter->x*scale), cvRound(iter->y*scale)),
CvPoint(cvRound((iter->x+iter->width)*scale), cvRound((iter->y+iter->height)*scale)), Scalar(0, 255, 0),2,8);
}
imshow("resframe", frame);