人脸检测并打码的关键,首先需要定位人脸区域,再修改人脸区域像素灰度值。

一 定义马赛克函数

定义生成马赛克函数 Generate_Mosaic,对图形 Mat& src 做操作,将需要操作的块(faces)存入数组 vector<Rect>& faces 中(<Rect>表示用矩形区域描述)。

src:代表马赛克效果的图片;        faces:显示马赛克的区域;        Rect:矩形区域(x,y,w,h)

马赛克函数思想过程:定义马赛克大小为10像素,int step = 10。for (int t = 0; t < faces.size(); t++) 对每一张脸进行马赛克操作。再确定 faces 所在区域(x, y, w, h),然后针对 faces 所在进行马赛克处理。10像素的矩形遍历人脸矩形框区域像素,再将矩形框细分成若干个小方块,依次修改每个方块的像素,相同方块赋予相同灰度值。

src.at<Vec3b> (k, m)[c] (<Vec3b>原图的颜色, 位置(k, m),[C]颜色值)

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;
}

二 单张图片做打码处理

定义单张图片打码函数  Picture_Demo,将图片 Mat src 传入函数。首先加载人脸检测配置文件。在 OpenCV 中,人脸检测用的是 harr 或 LBP 特征,分类算法用的是 adaboost 算法。这种算法需要提前训练大量的图片,非常耗时,因此 OpenCV 已经训练好了,把训练结果存放在一些 xml 文件里面。然后创建人脸检测器并存储人脸检测的结果,人脸检测主要用到的是 CascadeClassifier 这个类,以及该类下的 detectMultiScale 函数。

detector.detectMultiScale(src, faces, 1.1, 5),src 检测的图片,faces 存储的结果,1.1 缩放尺寸

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;
}

三 视频打码操作

视频主要涉及视频的读取以及视频的保存

//把视频转图像操作
void VideoToImg()
{VideoCapture cap = VideoCapture("视频路径");   //创建一个对象cap,打开一个视频,若参数设为0则为打开默认摄像头if(!cap.isOpened()){cout << "打开失败。。。" << endl;return;}
// 如果成功开打,视频的每一帧都在对象cap中Mat img;  //定义图片int i = 1;while (true)    //用流的方式将图片导出来{cap >> img;  //拿出一帧if (img.empty())break;imshow("img", img);   //显示图片string URL = "data/img" + to_string(i) + ".jpg";   //定义图片存储路径 data/img0.jpgimwrite(URL, img);         //把图片写入文件waitKey(30); //延迟30msi++;}return;
}

打开摄像头,获取每一帧图片并显示在窗口上。

//打开摄像头
void VideoToImg()
{VideoCapture cap = VideoCapture(0);   //创建一个对象cap,打开一个视频,若参数设为0则为打开默认摄像头if (!cap.isOpened()){cout << "打开失败。。。" << endl;return;}// 如果成功开打,视频的每一帧都在对象cap中Mat img;  //定义图片while (true)    //用流的方式将图片导出来{cap >> img;  //拿出一帧if (img.empty())break;imshow("img", img);   //显示图片char userKey = waitKey(10);if (userKey == 27)      //如果userkey为esc键,退出循环break;}return;
}

将摄像头捕获的视频分成每一帧,将每帧保存为一张图片,再使用马赛克函数完成打码操作。

其中加载人脸检测配置文件、创建人脸检测器及保存人脸检测结果与单张图片做马赛克相同。

flip(frame, frame, 1) 用filp切割视频,一帧一帧的拿出来

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;
}

四 源码

#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;
}/*
void TestMosaic(Mat& src)
{vector<Rect> faces;faces.push_back(Rect(100, 100, 200, 200));faces.push_back(Rect(300, 300, 200, 200));Generate_Mosaic(src, faces);
}
*///对单张图片打马赛克
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;
}//把视频转图像操作
void VideoToImg()
{VideoCapture cap = VideoCapture("视频路径");   //创建一个对象cap,打开一个视频,若参数设为0则为打开默认摄像头if(!cap.isOpened()){cout << "打开失败。。。" << endl;return;}
// 如果成功开打,视频的每一帧都在对象cap中Mat img;  //定义图片int i = 1;while (true)    //用流的方式将图片导出来{cap >> img;  //拿出一帧if (img.empty())break;imshow("img", img);   //显示图片string URL = "data/img" + to_string(i) + ".jpg";   //定义图片存储路径 data/img0.jpgimwrite(URL, img);         //把图片写入文件waitKey(30); //延迟30msi++;}return;
}
/*
//打开摄像头,并在窗口上显示每一帧图片
void VideoToImg()
{VideoCapture cap = VideoCapture(0);   //创建一个对象cap,打开一个视频,若参数设为0则为打开默认摄像头if (!cap.isOpened()){cout << "打开失败。。。" << endl;return;}// 如果成功开打,视频的每一帧都在对象cap中Mat img;  //定义图片while (true)    //用流的方式将图片导出来{cap >> img;  //拿出一帧if (img.empty())break;imshow("img", img);   //显示图片char userKey = waitKey(10);if (userKey == 27)      //如果userkey为esc键,退出循环break;}return;
}
*///对视频打马赛克
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("图片路径");if (src.empty()){cout << "No Image!" << endl;system("pause");return -1;}//TestMosaic(src);Picture_Demo(src);//Video_Demo();system("pause");return 0;
}

五 运行效果

基于OpenCV_C++人脸检测打码技术相关推荐

  1. 人脸检测与美颜技术介绍(OpenCV)

    人脸检测与美颜技术介绍 目录 人脸检测与美颜技术介绍 人工智能(AI) 人工智能.机器学习与深度学习的关系 机器学习与深度学习的区别 深度学习简介 深度学习模型 深度学习的历史 深度学习的工具 神经网 ...

  2. 测一测!中科视拓免费开放口罩人脸检测与识别技术

    全民抗疫形势下,口罩已成为复工复产的标配.对于人脸识别技术厂商而言,两个应用需求应运而生: 1.检测人脸是否佩戴口罩: 2.在戴口罩的情况下依旧能够实现高精度人脸识别. 疫情初期,中科视拓紧急研发口罩 ...

  3. CNCC 2016 | 山世光:深度化的人脸检测与识别技术—进展与展望

    雷锋网(公众号:雷锋网)按:本文根据山世光在 CNCC 2016 可视媒体计算论坛上所做的报告<深度化的人脸检测与识别技术:进展与问题>编辑整理而来,在未改变原意的基础上略有删减. 山世光 ...

  4. 人脸检测源码facedetection

    人脸检测源码: using System; using System.Collections.Generic; using System.ComponentModel; using System.Da ...

  5. .NetCore——基于OpenCV人脸检测

    .NetCore--基于OpenCV人脸检测 一.介绍 在.NetCore中,基于OpenCV实现对静态图片的人脸识别,检测人脸是否存在,且存在的数量.注: 不能自动学习人脸特征. 二.使用 首先引入 ...

  6. 【口罩人脸检测/识别】中科视拓免费开放口罩人脸检测与识别技术解读

    原文:中科视拓免费开放口罩人脸检测与识别技术 思路 通过掺入了20%以上戴口罩的人脸识别数据集训练专门戴口罩识别模型,然后调整整个识别的Pipeline为先检测是否戴口罩,如果判断为带口罩则使用戴口罩 ...

  7. 《山世光:深度化的人脸检测与识别技术》读书笔记

    原文链接:http://www.leiphone.com/news/201610/rZ2Mn9UFF3x8FaEt.html 人脸识别过程 人脸识别的本质是对比两个照片是否是同一个人.这个过程可以分为 ...

  8. 基于MATLAB人脸检测的汽车疲劳驾驶检测

    课题介绍 疲劳驾驶导致汽车交通事故逐年增加,为了提升驾车的安全性,需对驾驶员疲劳状态实时监测并及时提醒. 为了提高疲劳驾驶判断效率及准确率,本文运用Viola-Jones 框架特征矩阵进行人脸预判断: ...

  9. 人脸识别 (5) 基于MCTNN人脸检测(Pytorch)

    参考:FaceDetector/detect_step_by_step.ipynb at master · faciallab/FaceDetector · GitHub 中文翻译:从零开始搭建人脸识 ...

最新文章

  1. Android---如何返回上一Activity
  2. 【转载】关于阿里巴巴的问题
  3. 支援一波 《面试数十人有感》
  4. java语言程序设计教程翁恺第二版课后答案_《JAVA语言程序设计教程(第2版)/翁恺 肖少拥》翁恺,肖少拥著【摘要 书评 在线阅读】-苏宁易购图书...
  5. 量子计算机的核心元件简称,计算机文化基础复习题(含答案).doc
  6. 那些年,我写过的设置Windows系统变量的vbs脚本
  7. url上传参 用requestmapping接受_14 个 Spring MVC 顶级技巧,随时用随时爽,一直用一直爽...
  8. 上传文件时$_FILES为空,可能的原因及解决方法
  9. 结构体交换遇到指针问题和一些记录
  10. Linux nohup命令详解
  11. RS485收发的3种典型电路-重点-自动收发电路
  12. python 词云图
  13. 查看当前python环境_python-环境
  14. 源码分析学习记录(9)——PBR材质
  15. DSP快速复盘——时钟系统总结(基本知识+核心代码)基于TMS2802x处理器
  16. 黑龙江省扶贫电商平台“小康龙江”上线 传输绿色优质农产品
  17. C盘全面清理教程,彻底清理所有垃圾
  18. VSPD V9版(Virtual Serial Port Driver 9.0)
  19. html可以有多个h1,HTML5大纲和多个H1 SEO
  20. 一些网站...........

热门文章

  1. linux查看进程的信息失败,Linux查看端口、进程信息
  2. PyKivy入门教程:Kivy Python库的介绍、安装及使用方法详解
  3. Android开发岗还不会这些问题,面试建议
  4. Win11如何设置软件快捷方式?
  5. 词性标注_CodingPark编程公园
  6. 删除多余迅雷7插件,加快启动速度
  7. [转载]说说我今年买二手房被毁约的血泪史,各种坑爹心酸~
  8. 用树莓派搭建全功能NAS服务器(03):了解你的网络内网穿透
  9. 一群爱做“傻事”的技术宅 1
  10. 逃不出的循环,先有鸡还是先有蛋?object和type纠葛(python中的基类和元类)