1. 程式人生 > >樹莓派基於OpenCV的人臉檢測和處理

樹莓派基於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.對視訊中檢測出的人臉區域進行模糊處理

程式碼:

//   高斯模糊
#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);	// 顯示
}

執行
在這裡插入圖片描述
在這裡插入圖片描述