基于OpenCV_C++人脸检测打码技术
人脸检测并打码的关键,首先需要定位人脸区域,再修改人脸区域像素灰度值。
一 定义马赛克函数
定义生成马赛克函数 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++人脸检测打码技术相关推荐
- 人脸检测与美颜技术介绍(OpenCV)
人脸检测与美颜技术介绍 目录 人脸检测与美颜技术介绍 人工智能(AI) 人工智能.机器学习与深度学习的关系 机器学习与深度学习的区别 深度学习简介 深度学习模型 深度学习的历史 深度学习的工具 神经网 ...
- 测一测!中科视拓免费开放口罩人脸检测与识别技术
全民抗疫形势下,口罩已成为复工复产的标配.对于人脸识别技术厂商而言,两个应用需求应运而生: 1.检测人脸是否佩戴口罩: 2.在戴口罩的情况下依旧能够实现高精度人脸识别. 疫情初期,中科视拓紧急研发口罩 ...
- CNCC 2016 | 山世光:深度化的人脸检测与识别技术—进展与展望
雷锋网(公众号:雷锋网)按:本文根据山世光在 CNCC 2016 可视媒体计算论坛上所做的报告<深度化的人脸检测与识别技术:进展与问题>编辑整理而来,在未改变原意的基础上略有删减. 山世光 ...
- 人脸检测源码facedetection
人脸检测源码: using System; using System.Collections.Generic; using System.ComponentModel; using System.Da ...
- .NetCore——基于OpenCV人脸检测
.NetCore--基于OpenCV人脸检测 一.介绍 在.NetCore中,基于OpenCV实现对静态图片的人脸识别,检测人脸是否存在,且存在的数量.注: 不能自动学习人脸特征. 二.使用 首先引入 ...
- 【口罩人脸检测/识别】中科视拓免费开放口罩人脸检测与识别技术解读
原文:中科视拓免费开放口罩人脸检测与识别技术 思路 通过掺入了20%以上戴口罩的人脸识别数据集训练专门戴口罩识别模型,然后调整整个识别的Pipeline为先检测是否戴口罩,如果判断为带口罩则使用戴口罩 ...
- 《山世光:深度化的人脸检测与识别技术》读书笔记
原文链接:http://www.leiphone.com/news/201610/rZ2Mn9UFF3x8FaEt.html 人脸识别过程 人脸识别的本质是对比两个照片是否是同一个人.这个过程可以分为 ...
- 基于MATLAB人脸检测的汽车疲劳驾驶检测
课题介绍 疲劳驾驶导致汽车交通事故逐年增加,为了提升驾车的安全性,需对驾驶员疲劳状态实时监测并及时提醒. 为了提高疲劳驾驶判断效率及准确率,本文运用Viola-Jones 框架特征矩阵进行人脸预判断: ...
- 人脸识别 (5) 基于MCTNN人脸检测(Pytorch)
参考:FaceDetector/detect_step_by_step.ipynb at master · faciallab/FaceDetector · GitHub 中文翻译:从零开始搭建人脸识 ...
最新文章
- Android---如何返回上一Activity
- 【转载】关于阿里巴巴的问题
- 支援一波 《面试数十人有感》
- java语言程序设计教程翁恺第二版课后答案_《JAVA语言程序设计教程(第2版)/翁恺 肖少拥》翁恺,肖少拥著【摘要 书评 在线阅读】-苏宁易购图书...
- 量子计算机的核心元件简称,计算机文化基础复习题(含答案).doc
- 那些年,我写过的设置Windows系统变量的vbs脚本
- url上传参 用requestmapping接受_14 个 Spring MVC 顶级技巧,随时用随时爽,一直用一直爽...
- 上传文件时$_FILES为空,可能的原因及解决方法
- 结构体交换遇到指针问题和一些记录
- Linux nohup命令详解
- RS485收发的3种典型电路-重点-自动收发电路
- python 词云图
- 查看当前python环境_python-环境
- 源码分析学习记录(9)——PBR材质
- DSP快速复盘——时钟系统总结(基本知识+核心代码)基于TMS2802x处理器
- 黑龙江省扶贫电商平台“小康龙江”上线 传输绿色优质农产品
- C盘全面清理教程,彻底清理所有垃圾
- VSPD V9版(Virtual Serial Port Driver 9.0)
- html可以有多个h1,HTML5大纲和多个H1 SEO
- 一些网站...........
热门文章
- linux查看进程的信息失败,Linux查看端口、进程信息
- PyKivy入门教程:Kivy Python库的介绍、安装及使用方法详解
- Android开发岗还不会这些问题,面试建议
- Win11如何设置软件快捷方式?
- 词性标注_CodingPark编程公园
- 删除多余迅雷7插件,加快启动速度
- [转载]说说我今年买二手房被毁约的血泪史,各种坑爹心酸~
- 用树莓派搭建全功能NAS服务器(03):了解你的网络内网穿透
- 一群爱做“傻事”的技术宅 1
- 逃不出的循环,先有鸡还是先有蛋?object和type纠葛(python中的基类和元类)