本程序主要通过videocapture打开摄像头,并且对所录视频的内容进行检测,如果视频内容发生改变则保存所录视频,并且对变化的内容进行检查是否包含人脸,包含人脸则将人脸标记出来,主要用到了opencv提供的haarcascade_frontalface_alt.xml分类器。话不多说,直接上代码。
#include <opencv\cvaux.hpp>
#include <opencv\cv.h>
#include<opencv\cxcore.hpp>
#include <opencv2\opencv.hpp>
#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <iostream>
#include <string>
#include <vector>
using namespace cv;
using namespace std;
double diffent_pixel_sum = 0;
string face_cascade_name = "E:\\opencv\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml";//引入
分类器,要根据自己的实际情况修改路径。
CascadeClassifier face_cascade;
void detectAndDisplay(Mat face){
vector<Rect> faces;
Mat face_gray;
cvtColor(face, face_gray, CV_BGR2GRAY); //rgb类型转换为灰度类型
equalizeHist(face_gray, face_gray); //直方图均衡化
face_cascade.detectMultiScale(face_gray, faces, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(150, 150));
for (int i = 0; i < faces.size(); i++){
Point center(faces[i].x + faces[i].width*0.5, faces[i].y + faces[i].height*0.5);
ellipse(face, center, Size(faces[i].width*0.5, faces[i].height*0.5), 0, 0, 360, Scalar(0, 0, 255), 2, 7, 0);
}
}
int main(){
if (!face_cascade.load(face_cascade_name)){
printf("级联分类器错误,可能未找到文件,拷贝该文件到工程目录下!\n");
return -1;
}
Mat frame, frame2, frame3, gray, gray2, gray3, gray_diff, gray_diff2;
VideoCapture capture(0);
double dWidth = capture.get(CV_CAP_PROP_FRAME_WIDTH); //get the width of frames of the video
double dHeight = capture.get(CV_CAP_PROP_FRAME_HEIGHT);
Size frameSize(static_cast<int>(dWidth), static_cast<int>(dHeight));
VideoWriter writer("C:\\Users\\Administrator\\Desktop\\VideoTest2.avi", CV_FOURCC('D', 'I', 'V', 'X'), 15.0, frameSize, true);
if (!capture.isOpened())
return -1;
int time = 0;
while (true)
{
time++;
capture >> frame;
//imshow("video", frame);
cvtColor(frame, gray, CV_BGR2BGRA);
waitKey(1);
capture >> frame2;
cvtColor(frame2, gray2, CV_BGR2BGRA);
/*waitKey(1);
capture >> frame3;
cvtColor(frame3, gray3, CV_BGR2BGRA);*/
subtract(gray, gray2, gray_diff);
//subtract(gray3, gray2, gray_diff2);//第三帧减第二帧
for (int i = 0; i < gray_diff.rows; i++){
for (int j = 0; j < gray_diff.cols; j++)
{
if (abs(gray_diff.at<unsigned char>(i, j)) >= 20){//这里模板参数一定要用unsigned char,否则就一直报错
//gray_diff.at<unsigned char>(i, j) = 255; //第一次相减阈值处理
diffent_pixel_sum += abs(gray_diff.at<unsigned char>(i, j));
}
//else gray_diff.at<unsigned char>(i, j) = 0;
//if (abs(gray_diff2.at<unsigned char>(i, j)) >= 20){//第二次相减阈值处理
// gray_diff2.at<unsigned char>(i, j) = 255;
// diffent_pixel_sum += abs(gray_diff.at<unsigned char>(i, j));
//}
//else gray_diff2.at<unsigned char>(i, j) = 0;
}
bitwise_and(gray_diff, gray_diff2, gray);
imshow("foreground", gray);
}
if (diffent_pixel_sum > 20000){//根据侦差判断视频内容变化情况。
if (time = 50) {//每50帧检测一下,提高效率。
detectAndDisplay(frame);
time = 0;
imshow("video", frame);
writer << frame;
waitKey(30);
diffent_pixel_sum = 0;
}
}
if (waitKey(30) == 27){
break;
}
}
writer.release();
}
效果:
<img src="https://img-blog.csdn.net/20160418213848028?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" width="150" height="200" alt="" />
haarcascade_frontalface_alt分类器下载地址
该程序存在一些不足,保存的视频,在播放速度方面存在问题,查了很多资料也没有解决,希望有大神可以指导改正。
百度云免费下链接:https://pan.baidu.com/s/1hDbhnj0fPIkG-cuKUDIoCQ 提取码:i07j 复制这段内容后打开百度网盘手机App,操作更方便哦