惯例先上结果:
在c++ opencv Chapter8 - Face Detection中介绍了人脸图片的标记,而视频其实是每一帧图片所组成,因此也能实现对视频的人脸识别,由于模型的劣势,实现的效果一般。
重点介绍写出视频函数:out.open(output_video_path, VideoWriter::fourcc('M', 'J', 'P', 'G'),fps, Size(680,480), true);
output_video_path:路径
VideoWriter::fourcc('M', 'J', 'P', 'G'):压缩格式
fps:帧率
Size(680,480):分辨率
true:彩色
需要定义写出视频路径,读入帧率要和写出视频帧率一样,视频分辨率也要相同,另外一个注意点是压缩视频格式,网上有很多方法获取视频格式,亲试,许多并不行,可能电脑问题,写出的视频无法播放,报错:This file isn't playable. That might be because the file type is unsupported, the file extension is incorrect, or the file is corrupt.
其实原因是压缩视频格式电脑无法读取,这边建议:
VideoWriter::fourcc('M', 'J', 'P', 'G')这种格式。
人脸识别可以参考我上篇:https ://blog.csdn.net/qq_50934329/article/details/138148565
直接上代码:
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/objdetect.hpp>
#include <iostream>Face Detection ///
using namespace std;
using namespace cv;int midpoint(Point2i ptA,Point2i ptB) {return ((ptA.x - ptB.x) * 0.5 + (ptA.y - ptB.y) * 0.5);
} int main() {string path = "Learn-OpenCV-cpp-in-4-Hours-main\\Resources\\4.26.mp4";string output_video_path = "text_save.avi";Mat fram,image, img;int x, y,width,height;Point a, b;VideoCapture cap(path);int fps = cap.get(CAP_PROP_FPS); //获取视频的帧率//获取视频的长宽width = int(cap.get(CAP_PROP_FRAME_WIDTH));height = int(cap.get(CAP_PROP_FRAME_HEIGHT));vector<Rect>faces;CascadeClassifier faceCascade;faceCascade.load("Learn-OpenCV-cpp-in-4-Hours-main\\Resources\\haarcascade_frontalface_default.xml");VideoWriter out;out.open(output_video_path, VideoWriter::fourcc('M', 'J', 'P', 'G'),fps, Size(680,480), true);if (!cap.isOpened()){cout << "Video load failed!" << endl;return -1;}if (faceCascade.empty()){cout << "XML file not loadeed" << endl;}/*1.1scaleFactor因为图像的像素有大有小,图像中的人脸因为远近不同也会有大有小,所以需要通过scaleFactor参数设置一个缩小的比例,对图像进行逐步缩小来检测,这个参数设置的越大,计算速度越快,但可能会错过了某个大小的人脸minNeighbors参数10,只有其“邻居”大于等于这个值的结果才认为是正确结果。*//*1.1,10而每次缩小1.1倍,所以导致识别出的结果较少。下面我让scaleFactor=1.1,minNeighbors=3,你会发现,当scaleFactor=1.03时,每个人脸被识别的次数都比上一组测试要多,因为每次缩小的比例小,迭代的次数就多了。看一下输出结果*/while (true) {cap>>image;if (image.empty()){cout << "Video process finished!" << endl;return 0;}resize(image, img, Size(680, 480));faceCascade.detectMultiScale(img, faces, 1.1, 2);for (int i = 0; i < faces.size(); i++){x = midpoint(faces[i].tl(), faces[i + 1].tl());y = midpoint(faces[i].br(), faces[i + 1].br());if ((10 <= x <= 20) && (10 <= y <= 20)) {a = faces[i].tl();b = faces[i].br();cout << a << endl;cout << b << endl;}rectangle(img, a, b, Scalar(255, 0, 255), 3);}namedWindow("Image", WINDOW_NORMAL);imshow("Image", img);out<<img;waitKey(1);}cap.release();out.release();destroyAllWindows();return 0;
}