OpenCV C++案例实战十三《人脸打马赛克》

OpenCV C++案例实战十三《人脸打马赛克》


前言

本文将使用OpenCV C++ 对人脸部位打上马赛克。实现步骤其实很简单。
1、人脸检测。
2、图像像素修改

一、人脸检测

请添加图片描述

原图如图所示。本案例的需求是将人脸部位打上马赛克。所以,第一步我们首先需要检测出人脸的位置。OpenCV提供harr级联检测器检测人脸。

	//人脸检测配置文件
	string harr_file = "haarcascade_frontalface_default.xml";

	//创建人脸检测器
	CascadeClassifier detector;
	detector.load(harr_file);

	//人脸检测
	vector<Rect>faces;
	detector.detectMultiScale(src, faces, 1.1, 5);

请添加图片描述

如图所示,我们已经定位到了人脸所在位置。接下来为了实现马赛克效果,仅需要将人脸区域像素值进行修改就可以了。

二、马赛克效果

具体原理请看源码注释。

	int step = 10;//步长

	for (int t = 0; t < faces.size(); t++)
	{
    
    
		int x = faces[t].tl().x; //人脸矩形框起点x坐标
		int y = faces[t].tl().y;//人脸矩形框起点y坐标
		int width = faces[t].width;//人脸矩形框宽
		int height = faces[t].height;//人脸矩形框高

		//仅对人脸区域进行像素修改。遍历人脸矩形框区域像素,并对其进行修改
		for (int i = y; i < (y + height); i += step)
		{
    
    
			for (int j = x; j < (x + width); j += step)
			{
    
    
				//将人脸矩形框再细分为若干个小方块,依次对每个方块修改像素(相同方块赋予相同灰度值)
				for (int k = i; k < (step + i); k++)
				{
    
    
					for (int m = j; m < (step + j); m++)
					{
    
    
						//对矩形区域像素值进行修改,rgb三通道
						for (int c = 0; c < 3; c++)
						{
    
    
							src.at<Vec3b>(k, m)[c] = src.at<Vec3b>(i, j)[c];
						}
					}
				}
			}
		}
	}

三、效果显示

请添加图片描述

四、源码

#include<iostream>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;

bool Generate_Mosaic(Mat &src,vector<Rect>&faces)
{
    
    
	if (faces.empty())return false;

	int step = 10;//步长

	for (int t = 0; t < faces.size(); t++)
	{
    
    
		int x = faces[t].tl().x; //人脸矩形框起点x坐标
		int y = faces[t].tl().y;//人脸矩形框起点y坐标
		int width = faces[t].width;//人脸矩形框宽
		int height = faces[t].height;//人脸矩形框高

		//仅对人脸区域进行像素修改。遍历人脸矩形框区域像素,并对其进行修改
		for (int i = y; i < (y + height); i += step)
		{
    
    
			for (int j = x; j < (x + width); j += step)
			{
    
    
				//将人脸矩形框再细分为若干个小方块,依次对每个方块修改像素(相同方块赋予相同灰度值)
				for (int k = i; k < (step + i); k++)
				{
    
    
					for (int m = j; m < (step + j); m++)
					{
    
    
						//对矩形区域像素值进行修改,rgb三通道
						for (int c = 0; c < 3; c++)
						{
    
    
							src.at<Vec3b>(k, m)[c] = src.at<Vec3b>(i, j)[c];
						}
					}
				}
			}
		}
	}

	return true;
}


//对单张图片打马赛克
bool Picture_Demo(Mat src)
{
    
    
	//人脸检测配置文件
	string harr_file = "haarcascade_frontalface_default.xml";

	//创建人脸检测器
	CascadeClassifier detector;
	detector.load(harr_file);

	//人脸检测
	vector<Rect>faces;
	detector.detectMultiScale(src, faces, 1.1, 5);

	if (!Generate_Mosaic(src, faces))return false;
	
	imshow("test", src);
	waitKey(0);
	return true;
}


//对视频打马赛克
bool Video_Demo()
{
    
    
	//人脸检测配置文件
	string harr_file = "haarcascade_frontalface_default.xml";

	//创建人脸检测器
	CascadeClassifier detector;
	detector.load(harr_file);

	VideoCapture cap;
	cap.open(0);
	if (!cap.isOpened())
	{
    
    
		cout << "can not open the camera!" << endl;
	}

	Mat frame;
	while (cap.read(frame))
	{
    
    
		flip(frame, frame, 1);

		//人脸检测
		vector<Rect>faces;
		detector.detectMultiScale(frame, faces, 1.1, 5);

		if (Generate_Mosaic(frame, faces))
		{
    
    
			imshow("Demo", frame);
		}
		char key = waitKey(10);
		if (key == 27)break;
	}

	cap.release();

	return true;
}


int main()
{
    
    
	Mat src = imread("person.jpg");
	if (src.empty())
	{
    
    
		cout << "No Image!" << endl;
		system("pause");
		return -1;
	}

	//Picture_Demo(src);
	
	Video_Demo();

	system("pause");
	return 0;
}


总结

本文使用OpenCV C++对人脸部位进行打码,关键步骤有以下几点。
1、人脸检测。首先需要定位人脸区域。
2、对人脸区域进行像素灰度值修改。

猜你喜欢

转载自blog.csdn.net/Zero___Chen/article/details/122370513