数码图像中自动祛除红眼方法探讨

原创 2003年10月09日 17:08:00

数码图像中祛除红眼已经不是问题,对于我们来说,红眼自动祛除才是真正的关键,作者也是模式识别方面的初学者,本文意在抛砖引玉,希望各位高手能够不吝赐教,提出更好的方法。

在阐述红眼的自动祛除前,我先花少量篇幅说一点我所知的关于的红眼知识。

红眼现在普遍认为是由于有生命物体被闪光灯照射后瞳孔突然收缩反光所造成的,而且需要注意的是,红眼现象的产生和个体本身有关。因此,现在的数码相机普遍采用预闪的方式,能够较有效的杜绝红眼现象的产生。

红眼现象一旦产生后,现在普遍采用的方法是用颜色替代红色,这样的效果非常明显,而且可以避免由于红眼反光所造成的眼睛中间亮,两边黑的不正常现象。

可是,这样祛除红眼的方法显然是有缺陷的,很大一部分原因就是这样的祛除方法没有和周围挂钩,所以看起来不太自然。这里,我采用的方法和普通方法有所不同,利用灰度运算的一个变形来近似求得红色通道:(G * 59 + B * 11) div 70。这样的运算基本上能够求得正确的红色通道。但是,这样的运算完全忽略了那个错误的红色通道的作用,显然还不够完美,于是,我加入了红色通道的作用:R + (R - Max(G, B)) / 112 * ((G * 59 + B * 11) div 70 - R)。这样的运算使用了常数112591170,但是作用是非常明显的,使用了红色通道后使得误差降到了最低。

以上是关于红眼的一些基础知识。下面,我们将进入正题,如何自动祛除红眼。

下面是一幅红眼图片,我们将以这幅红眼图片做为讲解的例图。

<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

通过分析例图,很容易得知:红眼是红的,因此,可以首先提取红色区域来大致获得红眼区域而避免讨论其他部分造成的额外开销,当然,这样的选择也有意外,那就是对红眼很不明显的图片会忽略不计。

如何提取红色区域呢?有几种方法,一种是取灰度和红色的差,一种是取红色和其他两种颜色中的最小值的差,而我使用的是通过取红色和其他两种颜色中最大值的差来实现的,这样提取出来的轮廓很不明显,所以,可以乘一个常数来提高红色的亮度。这样,例图就可以转换为下面的红色蒙版区域。

在红色蒙版区域中提取眼睛就容易多了。

现在,我们分析眼睛的特征。可以发现,眼睛的一个重要特征就是眼睛中间有黑眼珠、旁边有白眼仁。现在,就利用这个特征来进行眼睛的第一步筛选。对每个颜色偏红的点左右进行循环搜索(插叙:眼睛根据常识可知道上、下、左、右都有白眼仁,为了判断正确,只要左右任意一方有白眼仁即可)。判断是否泛白我采用的方法是首先判断灰度是否大于128,然后判断其他颜色和这个灰度的差值是否在一个常数以内,如果在的话就是白眼仁了。这样进行判断后可以大致确定是眼睛了,然后进入下一步,确定眼睛边界。因为红眼一般只出现在黑眼珠的中间部分,所以这里的确定眼睛边界其实是确定要祛除红眼的边界。这个确定方法就简单了,仍然循环搜索左右有没有颜色不太红的点,这个点就是边缘了。

下一步比较关键了,确定这一点是否是红眼。前面的过程再繁琐也不过只是进行下筛选,将有可能 是红眼的点筛选出来。尝试过用圆形度来进行判断,因为眼睛的非常非常重要的特征就是黑眼珠是圆的。不过很遗憾的是,我尝试这样方法的效果并不好,于是改用原始的办法,进行模式对比。简单言只,在这个以刚刚搜索的眼睛边界为边缘的矩形空间内和图片红眼进行匹配运算,看是否匹配,这样说来很抽象,看下图就清楚多了。

如果统计差值在一定的常数范围内的话,我们就近似的将这个图像看成是圆形的,这样判断的方法比圆形度在此高效的原因是很大一部分的眼睛圆部在红色蒙版区域上是和其他部位相连的,这样就容易被判断不圆,而采用这样的方法的话就完全没有这样的顾虑。

判断出了红眼的区域,就可以很方便的使用上面介绍的R + (R - Max(G, B)) / 112 * ((G * 59 + B * 11) div 70 - R)公式进行去红眼操作。

为了能够提高识别率,原则上应该对图片进行预处理。分析可以发现,有部分红眼图片的红眼中部不呈红色,这样对后期处理产生了一定的麻烦,解决方法是通过一个卷积模糊变形实现的,这个卷积公式是:
[1,2,1]
[2,0,2]
[1,2,1]

这个公式忽略了卷积的中部一点,能够有效的避免上面所说的问题。

另外,还可以用饱和度调整的方法,来提供红色区域和其他区域的差别。

更有甚者,我曾经尝试过利用图像色彩均衡后的图像来进行红眼识别,也一定程度上提高了识别率。自动图像色彩平衡的办法有兴趣的读者可以自行探究。

事实上,以上的方法可以达到识别率80%以上,下面是一些对比图片,很能够说明问题。

->

->

事实说明,上面介绍的方法在一定程度上还是有用的,当然,也希望大家能够研究出更完善的自动祛除红眼方法。

learn opencv-使用OpenCV的自动红眼删除

参考:https://github.com/spmallick/learnopencv使用OpenCV的自动红眼删除(C ++ / Python)在本教程中,我们将学习如何完全自动地从照片中删除红眼。...
  • wc781708249
  • wc781708249
  • 2017年11月13日 11:44
  • 135

BFS和A*算法分别解决N-数码问题

数码问题求解,分别使用BFS和启发式搜索实现。 BFS:求解指定3*3拼图(8-数码问题)的最优解。     1,isCompleted记录求解完成状态;     2,closeLi...
  • august717
  • august717
  • 2015年05月28日 11:22
  • 280

Win8 Metro(C#)数字图像处理--2.47人脸红眼去除算法

 [函数名称]   红眼去除     RedeyeRemoveProcess(WriteableBitmap src) /// /// Redeye...
  • Trent1985
  • Trent1985
  • 2015年04月17日 13:29
  • 1599

Android平台Camera实时滤镜实现方法探讨(四)--以Hefe滤镜为例

上文讲到如何将YUV转换成RGB,之后就可以根据自己的设计,制作自己需要的滤镜了,例如将红色变的更红,增加亮度等 滤镜的制作,基本上采用图层+曲线,结合一些其他属性的调节,例如这篇文章讲解了如何用PS...
  • oShunz
  • oShunz
  • 2015年11月27日 13:12
  • 4912

图像自动标注 Automatic image annotation

翻译自https://en.wikipedia.org/wiki/Automatic_image_annotation。 见https://zh.wikipedia.org/wiki/图像自动标注。...
  • LiJiancheng0614
  • LiJiancheng0614
  • 2016年02月17日 23:28
  • 2443

多种方法求解八数码问题

AI的实验报告,改了改发上来。希望路过的大牛指教。很是纳闷我的ida*怎么还没有双搜快。还有发现基于不在位启发的A*和Ida*都挺慢。尤其是ida* 搜索31步的居然要十几秒。是我写的代码有问题吗?忘...
  • ouxijv
  • ouxijv
  • 2012年01月15日 20:33
  • 28406

算法练习-NOJ-1045-六数码问题

时限:1000ms 内存限制:10000K 总时限:3000ms描述 现有一两行三列的表格如下:A B C D E F把1、2、3、4、5、6六个数字分别填入A、B、C、D、E、...
  • cbq826111126
  • cbq826111126
  • 2016年04月06日 17:25
  • 778

2007.05.22 打造检测率最高的去红眼算法

我们的去红眼算法一共有3个版本,一个是打印机版本,检测率偏低,但是支持逐行输入,使用的内存核ROM size最小. 一个是数码相机版本,检测率中等,内核和打印机版本是一样的,内存使用比打印机的稍多,速...
  • fire_woods
  • fire_woods
  • 2007年05月22日 17:29
  • 915

图像数码基础知识

图像数码基础知识   一、光和颜色   1  光和颜色       可见光 是波长在 380nm ~ 780nm 之间的电磁波, 我们看到的大多数光不是一种波长的光, ...
  • yuyin86
  • yuyin86
  • 2014年02月13日 00:39
  • 560

基于分块技术的图像分割方法

谱聚类时间复杂度和空间复杂度分别是 O(n3)和 O(n2)
  • fandoudou123
  • fandoudou123
  • 2014年10月24日 09:03
  • 1643
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:数码图像中自动祛除红眼方法探讨
举报原因:
原因补充:

(最多只允许输入30个字)