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

五 运行效果

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/254835.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

Python可以解码吗,解码打码是如何实现的

前言 咳咳&#xff0c;进来的铁汁都是抱着学习的心态进来看的吧&#xff0c;咱今天不讲解解码&#xff0c;咱来说说python如何来实现打码功能~ 这一个个进来的 都是标题党吧哈哈哈 有兴趣的可以继续看看哦 最近重温了一档综艺节目 至于叫什么 这里就不细说了 老是看着看着就…

打码软件是真的吗

日前在各大社交网站上热传的“打码软件赚钱”帖子引发不少打码兼职人员的关注。“打码赚钱”到底出自何处&#xff1f;是否有充足的实例&#xff1f; 打码软件是什么&#xff1f; 打码软件是一些验证码识别平台推出来的一种通过任务的发放&#xff0c;让兼职者能够进行…

黑产揭秘:“打码平台”那点事儿

简介 互联网业务的飞速发展&#xff0c;日渐渗透人类的生活&#xff0c;对经济、文化、社会产生巨大的影响&#xff0c;同时互联网业务安全也日趋重要。如同网络通信的基础安全设施防火墙&#xff0c;互联网业务安全也有其基础安全设施&#xff0d;&#xff0d;图片验证码和短…

有没有自动打码的软件

验证码是一把双刃剑&#xff0c;对于有的人是好&#xff0c;但是对于有的人却是让人真心“香菇蓝瘦”。 场景一&#xff1a; A:两个小时就赚了几十块钱&#xff0c;买副眼镜都买不起&#xff0c;赚的钱都去了药店买眼药水了&#xff1b; B&#xff1a;是的啊&#xff0c;要是能…

chatgpt赋能python:Python中的逆序操作

Python 中的逆序操作 在 Python 中&#xff0c;逆序&#xff08;reverse&#xff09;操作指的是将一个序列的元素顺序反转&#xff0c;也即将序列中最后一个元素变成第一个&#xff0c;倒数第二个元素变成第二个&#xff0c;以此类推。逆序有很多实际用途&#xff0c;比如根据…

chatgpt赋能python:Python中的SEO

Python 中的 SEO 搜索引擎优化(SEO)是指通过改进网站的结构和内容&#xff0c;使其在搜索引擎中的排名更高&#xff0c;从而吸引更多的访问者。Python是一种流行的编程语言&#xff0c;其在SEO中也占有重要的地位。 Python 中的关键词密度 搜索引擎通常会关注网页中的关键词…

nginx修改监听端口号8080_解决Nginx启动失败

一、Nginx下载 http://nginx.org/en/download.html 二、Nginx启动失败原因 1、本人下载的是nginx-1.12.1(稳定版)&#xff0c;下载完解压后&#xff0c;进入路径中&#xff0c;start nginx&#xff0c;发现窗口闪过。但是查找不到nginx进程。 2、进入 nginx-1.12.1\logs 路径下…

nginx 启动前端包

项目是前后端分离&#xff1a;前端用vue开发&#xff0c;后端用的是springboot开发&#xff0c;用nginx启动代理&#xff0c;启动前端包 1、安装nginx&#xff08;此步骤就不细说了&#xff0c;如图&#xff09; 2、将前端包放入nginx文件夹下 注&#xff1a;我放在project文…

linux下nginx启动不了,Nginx启动失败的几种错误处理

nginx启动失败 启动nginx失败&#xff0c;报错信息如下: Starting nginx: nginx: [emerg] bind() to 0.0.0.0:**** failed (13: Permission denied) 这通常是因为开启了SELinux的原因&#xff0c;使用命令 getenforce 可以查看SELinux状态&#xff0c;如果输出为 enforcing …

NGINX启动报错,端口被占用

NGINX启动报错&#xff0c;端口被占用解决方案&#xff08;修改端口号&#xff09;   Nginx (engine x) 是一个高性能的HTTP和反向代理服务器&#xff0c;也是一个IMAP/POP3/SMTP服务器。Nginx是由伊戈尔赛索耶夫为俄罗斯访问量第二的Rambler.ru 站点&#xff08;俄文&#x…

Nginx启动问题解决

妈的。nginx访问不了。。。就是浏览器打开看不到nginx的标准界面。 我的是centos 7.6 解决&#xff1a; 1.前提&#xff1a;root权限 2. 检查防火墙 并centos 7对外开启80端口&#xff1a; 查看状态&#xff1a;systemctl status firewalld 开启防火墙&#xff1a;systemctl…

nginx启动web项目

1、服务器任何路径新建存放项目文件夹 例如&#xff1a;/home/www/xtzl_platform_web 将web项目的压缩包存放到xtzl_platform_web目录下并解压 3、修改nginx配置文件nginx.conf cd /usr/local/nginx/conf ,修改nginx.conf文件 添加新路径 &#xff08;1&#xff09;al…

nginx 启动、停止、关闭

1&#xff0c;nginx 指定配置文件 /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf -c 参数 指定了要加载的nginx配置文件路径 1,从容停止Nginx&#xff1a; kill -QUIT 主进程号 2,快速停止Nginx&#xff1a; kill -TERM 主进程号 3,强制停止Nginx&am…

nginx 启动报错

systemctl start nginx 启动报错 报错内容如下&#xff1a; Job for nginx.service failed because the control process exited with error code. See “systemctl status nginx.service” and “journalctl -xe” for details. nginx -t 检查没有问题 systemctl status n…

解决nginx启动闪退

1.首先我们先了解一下nginx&#xff0c;&#xff08;以下来自百度文献&#xff09; Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器 [13] &#xff0c;同时也提供了IMAP/POP3/SMTP服务。Nginx是由伊戈尔赛索耶夫为俄罗斯访问量第二的Rambler.ru站点&#xff08;俄文…

MySQL数据库 1.概述

数据库相关概念&#xff1a; 数据库(Database)&#xff1a;数据库是指一组有组织的数据的集合&#xff0c;通过计算机程序进行管理和访问。数据库管理系统&#xff1a;操纵和管理数据库的大型软件SQL&#xff1a;操作关系型数据库的编程语言&#xff0c;定义了一套操作关系型数…

CV学习笔记 | CV综述 [2020.10.01]

文章目录 0. 概述&#xff08;整理完后随时修改&#xff09;1. 人工神经网络1.1. 人工神经网络发展历程1.2. 一些神经元节点的工作原理1.2.1. 基本神经元1.2.2. 卷积神经元(Convolutional cells)1.2.3. 解卷积神经元1.2.4. 池化神经元和插值神经元(Pooling and Interpolating c…

家·谱——人脸识别家谱系统

家谱——人脸识别家谱系统 家谱——智能家谱录入查询是一款基于人脸识别与图像标签的在线家谱查询录入系统&#xff0c;提供从人脸录入、识别到家谱构建展示的一站式服务。使用djangopythonpaddlehubBaiduAPI。 支持使用paddlehub或者face_recognition两种本地库路线。 目前…

OSChina 周日乱弹 ——我18岁了都没睡过男人

2019独角兽企业重金招聘Python工程师标准>>> Dragonite : 昨天打羽毛球&#xff0c;现在的手脚还有点酸&#xff0c;果然太久没运动了啊。 运动之前&#xff0c;先热身不容易受伤。 运动之后&#xff0c;去放松肌肉不酸痛。 来首周日适合运动的歌曲。 yoyoso : 很多…

长焦拍照对比:小米10至尊纪念版和一加8 Pro、vivo X50 Pro+~~~~

&#xff08;百度云盘资源&#xff1a;https://www.rrdyw.cc/&#xff09; 现在的旗舰&#xff0c;仿佛不上潜望式超长焦都配不上“旗舰”二字。除了常见的2倍长焦&#xff0c;大部分顶级旗舰都已经具备5倍左右的超长焦镜头。 而超广角那边&#xff0c;虽然更加实用&#xff0…