树莓派基于OpenCV的人脸检测和处理

一、Windows下使用opencv采集视频

  1. 属性配置与上一篇相同

  2. 代码

#include<opencv2\opencv.hpp>
using namespace cv;
//========================
//调用摄像头录像保存
//==========================

int main() {
	VideoCapture capture(0);
	// 设置摄像头的拍摄属性为 分辨率640x480,帧率30fps
	capture.set(CAP_PROP_FRAME_HEIGHT, 480);
	capture.set(CAP_PROP_FRAME_WIDTH, 640);
	capture.set(CAP_PROP_FPS, 30.0);
	// 设置保存视频的格式为AVI,编码为MJPG
	VideoWriter writer("chen.avi", VideoWriter::fourcc('M', 'J', 'P', 'G'), 30.0, Size(640, 480), true);
	Mat videoPlay;
	// 通过总帧数来控制拍摄时间,如果是10s的段视频的话,循环300次
	int count(300);
	namedWindow("VideoPlay", WINDOW_NORMAL);
	while (count--) {
		capture >> videoPlay;
		writer << videoPlay;
		imshow("VideoPlay", videoPlay);
		waitKey(1000 / 30);
	}
	// 释放相关对象
	writer.release();
	capture.release();
	destroyWindow("VideoPlay");
	return 0;
}
  1. 视频录制

在这里插入图片描述
在这里插入图片描述

二、基于opencv对视频中人脸进行检测

(一)Windows(VS2015)

1. 对图片中检测出的人脸画一个矩形框或圆圈

代码:

#include<opencv2/objdetect/objdetect.hpp>  
#include<opencv2/highgui/highgui.hpp>  
#include<opencv2/imgproc/imgproc.hpp>
#include <iostream>  
#include <stdio.h>

// 对图片进行人脸检测

using namespace cv;
using namespace std;
CascadeClassifier faceCascade;
int main()
{
faceCascade.load("D:/dasan/qianrushi/opencv/build/etc/haarcascades/haarcascade_frontalface_alt2.xml");
Mat img = imread("bo.jpg"); // 载入图片
Mat imgGray;
vector<Rect> faces;
if (img.empty()){
return 1;
}
if (img.channels() == 3){
cvtColor(img, imgGray, CV_RGB2GRAY); // RGB转化为灰度
}
else{
imgGray = img;  // 不转化
}
faceCascade.detectMultiScale(imgGray, faces, 1.2, 6, 0, Size(0, 0));// 检测人脸
if (faces.size() > 0){
for (int i = 0; i < faces.size(); i++){
rectangle(img, Point(faces[i].x, faces[i].y), Point(faces[i].x + faces[i].width, faces[i].y + faces[i].height), Scalar(0, 255, 0), 1, 8);    // 框出人脸
}
}
imshow("FacesOfPrettyGirl", img); // 显示图片
waitKey(0);
return 0;
}

执行结果:
在这里插入图片描述

2.对摄像头或视频中检测出的人脸画一个矩形框

代码:


//  对视频进行人脸检测
#include<opencv2/objdetect/objdetect.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;
CascadeClassifier faceCascade;
int main(){
faceCascade.load("D:/dasan/qianrushi/opencv/build/etc/haarcascades/haarcascade_frontalface_alt2.xml");
VideoCapture capture;
//	capture.open(0);   // 打开摄像头
//  capture.open("test.avi");    // 打开视频
capture.open("chen.mp4");    // 打开视频
if (!capture.isOpened()){
cout << "open camera failed. " << endl;
return -1;
}
Mat img, imgGray;
vector<Rect> faces;
while (1){
capture >> img;   // 读取图像至img
if (img.empty()){
continue;
}
if (img.channels() == 3){
cvtColor(img, imgGray, CV_RGB2GRAY);
}
else{
imgGray = img;
}
faceCascade.detectMultiScale(imgGray, faces, 1.2, 6, 0, Size(0, 0));   // 检测人脸
if (faces.size() > 0){
for (int i = 0; i < faces.size(); i++){
rectangle(img, Point(faces[i].x, faces[i].y), Point(faces[i].x + faces[i].width, faces[i].y + faces[i].height), Scalar(0, 255, 0), 1, 8);
}
}
imshow("CamerFace", img);// 显示
if (waitKey(1) > 0)		// delay ms 等待按键退出
{
break;
}
}
return 0;
}

执行结果:
调用视频:
在这里插入图片描述

调用摄像头:
在这里插入图片描述

3.对视频中检测出的人脸区域进行模糊处理

代码:

扫描二维码关注公众号,回复: 4528963 查看本文章
//   高斯模糊
#include <iostream>
#include <opencv2/core/core.hpp>  
#include <opencv2/highgui/highgui.hpp> 
#include "cv.h"
using namespace cv;
using namespace std;

int g_slider_position = 0, temp;
CvCapture *g_captrue = NULL;
void onTrackbarSlide(int pos){
	cvSetCaptureProperty(g_captrue, CV_CAP_PROP_POS_FRAMES,
		pos);
	temp = g_slider_position;
}

int main(int argc, char **argv){
	cvNamedWindow("sample-out", CV_WINDOW_AUTOSIZE);
	//创建输出处理后视频的窗口
	cvNamedWindow("sample", CV_WINDOW_AUTOSIZE);
	//创建初始视频窗口
	g_captrue = cvCreateFileCapture("chen.mp4");
	//Cvcapture结构体赋值
	int frames = (int)cvGetCaptureProperty(g_captrue,
		CV_CAP_PROP_FRAME_COUNT);
	//获取视频总帧数
	if (frames != 0)///若视频存在即帧数不为0则创建滚动条
	{
		cvCreateTrackbar("Position", "sample",
			&g_slider_position, frames, onTrackbarSlide);
	}
	IplImage *frame;//创建图像指针
	while (1){
		frame = cvQueryFrame(g_captrue);//读取一帧
		if (!frame)//读完退出
			break;
		cvShowImage("sample", frame);//显示在sample窗口中
		IplImage* out = cvCreateImage(cvGetSize(frame),
			IPL_DEPTH_8U, 3);
		//创建视频地址并为其开辟空间。
		cvSmooth(frame, out, CV_GAUSSIAN, 7, 7);//对每一帧高斯模糊||数值越大越模糊
		cvShowImage("sample-out", out);//视频输出到sample-out窗口中
		char c = cvWaitKey(30);//每一帧间隔30ms
		cvSetTrackbarPos("Position", "sample", temp++);//滚动条随动
		if (c == 27)
			break;
	}
	cvReleaseCapture(&g_captrue);//释放指针
	cvDestroyWindow("sample");//删除sample初始视频窗口
	cvDestroyWindow("sample-out");//删除sample-out处理后的视频窗口
	return 0;
}

执行结果:
在这里插入图片描述

(二)树莓派

对此视频中检测出的人脸区域画框并进行模糊处理

将视频传至树莓派
新建cpp文件
代码:

#include "opencv2/objdetect.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
#include <stdio.h>
using namespace cv;
using namespace std;

void DetectAndDraw(Mat& img, CascadeClassifier& cascade, double scale);
int main(){
	CascadeClassifier faceCascade;
	double scale = 4;
	int		nRet = 0;
	VideoCapture capture;
	//capture.open(0);//此句为调用摄像头,下一句为调用视频
	capture.open("chen.mp4");//mp4文件需放在工程文件夹下
	if (!capture.isOpened()){
		cout << "open camera failed. " << endl;
		return -1;
	}
	cout << "open camera succeed. " << endl;

	/* 加载分类器 */
#ifdef VERSION_2_4	
	nRet = faceCascade.load("home/pi/opencv-3.4.1/data/haarcascades/haarcascade_frontalface_alt2.xml");
#else
	nRet = faceCascade.load("home/pi/opencv-3.4.1/data/haarcascades/haarcascade_frontalface_alt2.xml");
#endif
	if (!nRet){
		printf("load xml failed.\n");
		return -1;
	}
	Mat frame;
	vector<Rect> faces;
	while (1){
		capture >> frame;
		if (frame.empty()){
			continue;
		}
		Mat frame1 = frame.clone();
		DetectAndDraw(frame1, faceCascade, scale);
		if (waitKey(1) > 0){		// delay ms 等待按键退出
			break;
		}
	}return 0;
}
void DetectAndDraw(Mat& img, CascadeClassifier& cascade, double scale){
	double t = 0;
	vector<Rect> faces;
	Mat gray, smallImg;
	double fx = 1 / scale;
	cvtColor(img, gray, COLOR_BGR2GRAY);	// 将源图像转为灰度图
	/* 缩放图像 */
#ifdef VERSION_2_4	
	resize(gray, smallImg, Size(), fx, fx, INTER_LINEAR);
#else
	resize(gray, smallImg, Size(), fx, fx, INTER_LINEAR_EXACT);
#endif
	equalizeHist(smallImg, smallImg);	// 直方图均衡化,提高图像质量
	/* 检测目标 */
	t = (double)getTickCount();
	cascade.detectMultiScale(smallImg, faces,
		1.1, 2, 0
		//|CASCADE_FIND_BIGGEST_OBJECT
		//|CASCADE_DO_ROUGH_SEARCH
		| CASCADE_SCALE_IMAGE,
		Size(30, 30));
	t = (double)getTickCount() - t;
	printf("detection time = %g ms\n", t * 1000 / getTickFrequency());
	/* 画矩形框出目标 */
	for (size_t i = 0; i < faces.size(); i++) // faces.size():检测到的目标数量
	{
		Rect rectFace = faces[i];
		rectangle(img, Point(rectFace.x, rectFace.y) * scale,
			Point(rectFace.x + rectFace.width, rectFace.y + rectFace.height) * scale,
			Scalar(0, 255, 0), 2, 8);
	}
	imshow("FaceDetect", img);	// 显示
}

执行
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_42248864/article/details/84639106