基于opencv3.0下的人脸检测和检测部分的高斯模糊…
2018-06-17 20:37:59来源:未知 阅读 ()
如题
这里将任务分解为三大部分:
1.录播放视频
2.人脸检测
3.部分高斯模糊
其中重点放在人脸检测和部分高斯模糊上
1.录播放视频(以opencv中的VideoCapture类进行实现)
首先罗列下操作环境:win10+vs2013+opencv3.0+单摄像头
opencv中提供了VideoCapture和CvCapture对视频进行操作
其中官方给出CvCapture的API为
实例化CvCapture对象的时候,需要调用cvCaptureFromCAM(int device)进行实例化。
博主的是单摄像头没有外接摄像头,根据API进行填写操作
1 #include<opencv2\highgui\highgui.hpp> 2 #include<opencv2\imgproc\imgproc.hpp> 3 #include<opencv2\core\core.hpp> 4 5 int main(int argc, const char** argv) 6 { 7 CvCapture* capture; 8 capture = cvCaptureFromCAM(0); 9 IplImage* frame; 10 namedWindow("video", 1); 11 while (true) 12 { 13 frame = cvQueryFrame(capture); 14 cvShowImage("video",frame); 15 char c = cvWaitKey(0); 16 if (c == 27)break;//捕获Esc 17 } 18 destroyWindow("video"); 19 cvReleaseCapture(&capture); 20 return 0; 21 }
通过简单的进行捕获摄像头的图像,结果如下:
并没有捕获到摄像头的所采集的图像。查阅的相关资料,有个方法将cvCaptureFromCAM()中填入-1。很遗憾是同样的效果。感兴趣的童鞋可以研究下,提出解决方案,共同促进学习。
所以这里采用VideoCapture进行采集视频
首先定义一个视频采集器,一个视频写入器;
VideoCapture capture;
VideoWriter writer;
初始化
1 /****************************************************** 2 函数名称: MyClass 3 函数功能: 初始化 4 传入参数: 5 返 回 值: 6 建立时间: 2018-05-13 7 修改时间: 8 建 立 人: 9 修 改 人: 10 其它说明: 11 ******************************************************/ 12 MyClass::MyClass() 13 { 14 if (!cascade.load(cascadeName)) 15 { 16 cerr << "ERROR: Could not load classifier cascade" << endl; 17 exit(1); 18 } 19 capture = 0; 20 string filepath = "test.avi"; 21 //获得帧的宽高 22 int w = static_cast<int>(capture.get(CV_CAP_PROP_FRAME_WIDTH)); 23 int h = static_cast<int>(capture.get(CV_CAP_PROP_FRAME_HEIGHT)); 24 Size S(w, h); 25 //获得帧率 26 double r = capture.get(CV_CAP_PROP_FPS); 27 //打开视频文件,准备写入 28 writer.open(filepath, -1, r, S, true); 29 //打开失败 30 if (!capture.isOpened()) 31 { 32 exit(1); 33 } 34 }
开始显示并录制:
1 /****************************************************** 2 函数名称: play 3 函数功能: 开始播放 4 传入参数: 5 返 回 值: 6 建立时间: 2018-05-13 7 修改时间: 8 建 立 人: 9 修 改 人: 10 其它说明: 11 ******************************************************/ 12 void MyClass::play(){ 13 Mat image; 14 namedWindow("直播页面按Esc退出", 1); 15 while (true) 16 { 17 capture >> image; 18 if (image.empty())break; 19 imshow("直播页面按Esc退出", image); 20 writer.write(image); 21 char c = waitKey(30); 22 if (c == 27)break; 23 } 24 cvDestroyWindow("直播页面按Esc退出"); 25 } 26 /******************************************************
下面是播放录制好的视频,校验原来是否成功录制:
1 /****************************************************** 2 函数名称: replay 3 函数功能: 播放测试 4 传入参数: 5 返 回 值: 6 建立时间: 2018-05-13 7 修改时间: 8 建 立 人: 9 修 改 人: 10 其它说明: 11 ******************************************************/ 12 void replay() 13 { 14 char* path = "test.avi"; 15 IplImage* frame; 16 CvCapture* capture=cvCreateFileCapture(path); 17 namedWindow("播放界面按Esc退出", 1); 18 while (true) 19 { 20 frame = cvQueryFrame(capture); 21 cvShowImage("播放界面按Esc退出", frame); 22 char c = waitKey(33); 23 if (c == 27)break; 24 } 25 26 }
结果:
成功播放了^.^.
2.人脸识别(以opencv中CascadeClassifier类进行实现)
在opencv安装处"../opencv/sources/samples/cpp/facedetect.cpp",里面有示例代码。(示例代码有图片和视频的识别,但是这种方式识别精准度不是很好。)
其中示例代码的视频处理部分主要的思想就是将视频中的每一帧提出来,然后根据CascadeClassifier类和haarcascade_frontalface_alt.xml所生成的对象,将图片进行类比区分。
ps:haarcascade_frontalface_alt.xml存储在"../opencv/sources/data/haarcascades"中。
将"../opencv/sources/data"包拷到项目中去,开始人脸识别。
1 /****************************************************** 2 函数名称: detectAndDraw 3 函数功能: 在人脸上绘制圆圈 4 传入参数: 5 返 回 值: 6 建立时间: 2018-05-13 7 修改时间: 8 建 立 人: 9 修 改 人: 10 其它说明: 11 ******************************************************/ 12 void MyClass::detectAndDraw(Mat& img,char* title) 13 { 14 Mat dog; 15 dog = imread("F:\\Pictures\\gdog.png",1); 16 Mat tempdog; 17 double alpha = 1; double beta = 1 - alpha; 18 19 double scale = 1; 20 vector<Rect> faces; 21 Mat gray,smallImg(cvRound(img.rows / scale), cvRound(img.cols / scale), CV_8UC1);; 22 cvtColor(img, gray, COLOR_BGR2GRAY); 23 resize(gray, smallImg, smallImg.size(), 0, 0, INTER_LINEAR); 24 equalizeHist(smallImg, smallImg); 25 cascade.detectMultiScale( smallImg, faces,1.1,2,0|CASCADE_SCALE_IMAGE,Size(30,30));//匹配人脸 26 for (vector<Rect>::const_iterator r = faces.begin(); r != faces.end(); r++){ 27 Scalar color = colors[6];//红色 28 int radius; 29 Point center; 30 double aspect_ratio = (double)r->width / r->height; 31 if (0.75 < aspect_ratio && aspect_ratio < 1.3) 32 { 33 center.x = cvRound((r->x + r->width*0.5)*scale); 34 center.y = cvRound((r->x + r->height*0.5)*scale); 35 radius = cvRound((r->width + r->height)*0.25*scale); 36 circle(img, center, radius, color, 3, 8, 0); 37 } 38 else 39 { 40 rectangle(img, CvPoint(cvRound(r->x*scale), cvRound(r->y*scale)), 41 CvPoint(cvRound((r->x + r->width - 1)*scale), cvRound((r->y + r->height - 1)*scale)), 42 color, 3, 8, 0); 43 44 } 45 } 46 writer.write(img); 47 cv::imshow(title,img); 48 }
然后在采集的方法(void play())中调用这个方法即可实现人脸识别。这里不展示结果。
3.部分高斯模糊
部分高斯模糊的关键是找到ROI(感兴趣区域)
其中在人脸识别的时候已经找出ROI了,所以只要对找到ROI进行高斯模糊就可以了
1 /****************************************************** 2 函数名称: detectAndDraw 3 函数功能: 绘制圆圈和高斯模糊 4 传入参数: 5 返 回 值: 6 建立时间: 2018-05-13 7 修改时间: 8 建 立 人: 9 修 改 人: 10 其它说明: 11 ******************************************************/ 12 void MyClass::detectAndDraw(Mat& img,char* title) 13 { 14 Mat dog; 15 dog = imread("F:\\Pictures\\gdog.png",1); 16 Mat tempdog; 17 double alpha = 1; double beta = 1 - alpha; 18 19 double scale = 1; 20 vector<Rect> faces; 21 Mat gray,smallImg(cvRound(img.rows / scale), cvRound(img.cols / scale), CV_8UC1);; 22 cvtColor(img, gray, COLOR_BGR2GRAY); 23 resize(gray, smallImg, smallImg.size(), 0, 0, INTER_LINEAR); 24 equalizeHist(smallImg, smallImg); 25 cascade.detectMultiScale( smallImg, faces,1.1,2,0|CASCADE_SCALE_IMAGE,Size(30,30));//匹配人脸 26 for (vector<Rect>::const_iterator r = faces.begin(); r != faces.end(); r++){ 27 Scalar color = colors[6];//红色 28 int radius; 29 Point center; 30 double aspect_ratio = (double)r->width / r->height; 31 if (0.75 < aspect_ratio && aspect_ratio < 1.3) 32 { 33 center.x = cvRound((r->x + r->width*0.5)*scale); 34 center.y = cvRound((r->x + r->height*0.5)*scale); 35 radius = cvRound((r->width + r->height)*0.25*scale); 36 circle(img, center, radius, color, 3, 8, 0); 37 Mat *imageROI=&img(Rect(r->x, r->y, 2 * radius, 2 * radius));//感兴趣区域 38 Mat temp = img(Rect(r->x, r->y, 2 * radius, 2 * radius)); 39 cv::GaussianBlur(temp, temp, Size(21, 21), 3, 3); 40 cv::GaussianBlur(temp, temp, Size(21, 21), 3, 3); 41 } 42 else 43 { 44 rectangle(img, CvPoint(cvRound(r->x*scale), cvRound(r->y*scale)), 45 CvPoint(cvRound((r->x + r->width - 1)*scale), cvRound((r->y + r->height - 1)*scale)), 46 color, 3, 8, 0); 47 48 } 49 } 50 writer.write(img); 51 cv::imshow(title,img); 52 }
结果:
:
成功生成人脸识别视频文件。
如需要源码请转移至码云:https://gitee.com/cjqbaba/MediaTest/tree/Face_Find进行源码克隆下载
如有问题请留言评论。转载请注明出处,谢谢。
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
下一篇:tomcat的配置使用详细版
- C++冒泡排序 (基于函数模板实现) 2020-05-31
- C++抓图服务 2020-03-31
- #《Essential C++》读书笔记# 第四章 基于对象的编程风格 2020-02-08
- 开源项目SMSS开发指南(二)——基于libevent的线程池 2020-01-11
- 第四章 复合类型 2019-12-16
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash