前言
本文将使用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、对人脸区域进行像素灰度值修改。