OpenCV实现照片自动红眼去除
点击上方“小白学视觉”,选择加"星标"或“置顶”
重磅干货,第一时间送达
OpenCV实现照片自动红眼去除
使用闪光照相机拍照,在光线条件不足的情况,如果眼睛盯着相机镜头很容易造成拍出的照片中人眼球变成红色,虽然现在相机从系统和镜头上做了大量改进工作,防止这种情况发生,但是还是会出现这样的情况。这些照片后期可以通过PS手段进行修复,去除红眼得到正常照片显示。而做图像处理开发者可以借助OpenCV提供API功能轻松实现自动红眼去除修复。首先看一下效果吧图像
有红眼照片
修复之后的照片
实现步骤
眼睛检测
基于OpenCV自带的HAAR眼睛级联分类器特征数据(haarcascade_eye.xml),通过调用级联分类器实现眼睛检测,对检测到的眼睛用红色矩形框标注,如第一张图所示。
实现代码如下:
vector<Rect> eyes;
cvtColor(src, gray, COLOR_BGR2GRAY);
equalizeHist(gray, gray);
eye_detector.detectMultiScale(gray, eyes, 1.1, 3, 0, Size(100, 100));
提取红色眼球区域
根据红眼颜色特征可以看出这种情况下,对每个像素点来说在RGB三通道中红色通道的分量明显要大于其它两个通道的值,所以通过三个通道分离,对每个像素红色通道来说值大于150(R>150)而且R >(G+B)时候我们把它保留作为眼球区域。最终对两个眼睛提取区域图像如下:
代码实现如下:
for (size_t t = 0; t < eyes.size(); t++) {// 通道分离Mat eye = src(eyes[t]);vector<Mat>bgr(3);split(eye, bgr);// 基于像素模型的红眼区域检测Mat mask = (bgr[2] > 150) & (bgr[2] > (bgr[1] + bgr[0]));
}
逻辑操作与形态学处理
上述的白色区域就是红色眼球所在的区域,但是这样的情况下白色区域内部还有一些黑色小块,我们可以通过漫水填充与逻辑操作完整填充整个内部区域,然后通过形态的膨胀操作,让红色眼球进一步扩展,这样就会让整个处理之后的边界处看上去比较自然圆润一点。处理之后的效果如下:
代码实现如下:
// 区域填充与提取
Mat mask_floodfill = mask.clone();
floodFill(mask_floodfill, cv::Point(0, 0), Scalar(255));
Mat mask2;
bitwise_not(mask_floodfill, mask2);
mask = (mask2 | mask);
dilate(mask, mask, Mat(), Point(-1, -1), 3, 1, 1);
红眼修复
对上面得到白色区域即为红眼区域,通过把上面结果作为遮罩,对检测到人眼区域进行修复即可。一般情况下人的眼球都是黑色,越中心地方越黑色越暗,对白色区域内的每个像素点,取它的B和G两个通道的平均值作为修复处理之后的R,G,B三通道的值,这样就得到修复之后的眼球区域,然后用修复之后的眼球区域替代原来的红眼区域即可得到修复之后的图像:
代码实现如下:
// 修复
Mat mean = (bgr[0] + bgr[1]) / 2;
mean.copyTo(bgr[0], mask);
mean.copyTo(bgr[1], mask);
mean.copyTo(bgr[2], mask);
// 回填
Mat eyeOut;
merge(bgr, eyeOut);
eyeOut.copyTo(imgOut(eyes[t]));
完整代码如下
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
String filename = "D:/opencv3.1/opencv/build/etc/haarcascades/haarcascade_eye.xml";
CascadeClassifier eye_detector;
int main(int argc, char** argv) {Mat src = imread("D:/23-01.jpg");if (src.empty()) {printf("could not load image...\n");return -1;}if (!eye_detector.load(filename)) {printf("could not load data file...\n");return -1;}Mat imgOut = src.clone();Mat gray;vector<Rect> eyes;cvtColor(src, gray, COLOR_BGR2GRAY);equalizeHist(gray, gray);eye_detector.detectMultiScale(gray, eyes, 1.1, 3, 0, Size(100, 100));for (size_t t = 0; t < eyes.size(); t++) {// 通道分离Mat eye = src(eyes[t]);vector<Mat>bgr(3);split(eye, bgr);// 基于像素模型的红眼区域检测Mat mask = (bgr[2] > 150) & (bgr[2] > (bgr[1] + bgr[0]));// 区域填充与提取Mat mask_floodfill = mask.clone();floodFill(mask_floodfill, cv::Point(0, 0), Scalar(255));Mat mask2;bitwise_not(mask_floodfill, mask2);mask = (mask2 | mask);dilate(mask, mask, Mat(), Point(-1, -1), 3, 1, 1);if (t == 1) {imshow("mask", mask);}// 修复Mat mean = (bgr[0] + bgr[1]) / 2;mean.copyTo(bgr[0], mask);mean.copyTo(bgr[1], mask);mean.copyTo(bgr[2], mask);// 回填Mat eyeOut;merge(bgr, eyeOut);eyeOut.copyTo(imgOut(eyes[t]));rectangle(src, eyes[t], Scalar(0, 0, 255), 2, 8, 0);}imshow("input", src);imshow("output", imgOut);waitKey(0);return 0;
}
总结:
整个处理就是考察使用OpenCV图像处理的基本操作能力、以及像素操作ROI区域与MASK的巧妙运用。基于OpenCV3.1.0完成全部代码调试。
好消息!
小白学视觉知识星球
开始面向外开放啦
OpenCV实现照片自动红眼去除相关推荐
- 如何使用OpenCV的去除自动红眼
在本教程中,我们将学习如何完全自动消除照片中的红眼. 仅仅考虑消除红眼的问题,就会带回我小时候的记忆.小时候拥有一台傻瓜相机" Hotshot".它可能是我们家庭中唯一的便携式电子 ...
- learn opencv-使用OpenCV的自动红眼删除
参考:https://github.com/spmallick/learnopencv 使用OpenCV的自动红眼删除(C ++ / Python) 在本教程中,我们将学习如何完全自动地从照片中删除红 ...
- 基于QT+Opencv的红眼去除
** 基于QT+Opencv的红眼去除 ** 最近老师布置了一个讨论专题,是关于红眼去除,对于我一个初学者来说,当然是一脸懵了,不过还好百度上有一些资源可以 参考,在几天的了解下,也是成功完成了. 我 ...
- PS进阶篇——如何PS软件给人物照片红眼去除(八)
所谓照片红眼,拍照出现红眼的情况大多数是在使用闪光灯之后.当我们处在比较暗的场景下,摄影师一般会打开闪光灯来进行补光,而在黑暗条件下,人的瞳孔为了看清楚周围的事物会放大很多.此时打开闪光灯拍照,突如其 ...
- python换照片底色_Python 利用OpenCV给照片换底色的示例代码
OpenCV的全称是:Open Source Computer Vision Library.OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,可以运行在Linux.Windows和M ...
- 基于OpenCv的照片美化工具的设计与实现
随着我们对美好事物的向往,追求更美的自己,尤其是在手机拍照时,更能体现,现在不同的手机拍出的效果截然不同,像华为手机拍照拍出的就特别的清晰,opp手机拍出的效果就非常的柔和,像小米手机拍出的效果就非常 ...
- 人脸照片自动生成游戏角色_ICCV2019论文解析
人脸照片自动生成游戏角色_ICCV2019论文解析 Face-to-Parameter Translation for Game Character Auto-Creation 论文链接: http: ...
- 使用Python,OpenCV缩放照片(忽略宽高比,保持宽高比)
使用Python,OpenCV缩放照片(忽略宽高比,保持宽高比) 1. 效果图 1.1 保持宽高比效果图 1.2 忽略宽高比效果图 1.3 opencv各插值效果图 2. 原理 3. 源码 参考 这篇 ...
- 文件夹里面照片自动分成子文件夹_Windows居然自带这个功能,自动整理你硬盘里的照片...
今天主要是想跟大家来聊聊本地照片的管理这个话题,当然了,至于你要管理什么照片,任君随意. 不管是手机拍照,还是相机拍照,最终相信大家还是会把照片导入到电脑的本地硬盘来存储. 只是照片多了,想要找照片的 ...
最新文章
- Docker+Jenkins持续集成环境(3)集成PMD、FindBugs、Checkstyle静态代码检查工具并邮件发送检查结果...
- tableView下沉
- SAP ABAP实用技巧介绍系列之 如何调试后台作业
- 部署好网站,同局域网中电脑无法访问的问题的解决方案
- oracle 索引监控
- 为什么python打不开_anaconda为什么打不开
- 【转载】C#, VB.NET如何将Excel转换为PDF
- c语言二级考试程序设计题怎么运行,2017计算机二级C语言上机考试技巧
- RK3399 Android7.1 AP6212蓝牙可发文件,但收不到文件
- 记第一次阿里数据研发工程师面试
- 信息安全数学基础自学笔记1——群
- 【考研英语语法】形容词练习题
- 【Excel VBA】批量新建并重命名工作表
- noip2003 侦探推理 (字符串处理)
- Libgdx粒子效果介绍与使用心得
- VisionMaster 4.0.0 的Modbus通信
- 如何将多台物理机整合成一台
- spss数据处理—数据输入
- ##安利几个很好的网站和软件##
- 2个Android蓝牙无法连接的原因和解决方法
热门文章
- Dithering(Dithering pixel studio)
- 创建oracle数据库到达梦数据库的dblink
- 2013 ACM-ICPC南京赛区全国邀请赛
- 圆形与矩形碰撞算法分析
- 各大公司Java面试题超详细总结
- 在office2010的ppt中加入音乐
- 吐血推荐30个高质量但免费的自学网站,错过了就是亏大了!!!
- Classification 分类学习
- meda中的一些小事项
- transact sql mysql_MySQL与Transact SQL(MS SQL Server)的SQL语句区别点滴(C++)