数码图像中祛除红眼已经不是问题,对于我们来说,红眼自动祛除才是真正的关键,作者也是模式识别方面的初学者,本文意在抛砖引玉,希望各位高手能够不吝赐教,提出更好的方法。
在阐述红眼的自动祛除前,我先花少量篇幅说一点我所知的关于的红眼知识。
红眼现在普遍认为是由于有生命物体被闪光灯照射后瞳孔突然收缩反光所造成的,而且需要注意的是,红眼现象的产生和个体本身有关。因此,现在的数码相机普遍采用预闪的方式,能够较有效的杜绝红眼现象的产生。
红眼现象一旦产生后,现在普遍采用的方法是用颜色替代红色,这样的效果非常明显,而且可以避免由于红眼反光所造成的眼睛中间亮,两边黑的不正常现象。
可是,这样祛除红眼的方法显然是有缺陷的,很大一部分原因就是这样的祛除方法没有和周围挂钩,所以看起来不太自然。这里,我采用的方法和普通方法有所不同,利用灰度运算的一个变形来近似求得红色通道:(G * 59 + B * 11) div 70。这样的运算基本上能够求得正确的红色通道。但是,这样的运算完全忽略了那个错误的红色通道的作用,显然还不够完美,于是,我加入了红色通道的作用:R + (R - Max(G, B)) / 112 * ((G * 59 + B * 11) div 70 - R)。这样的运算使用了常数112、59、11、70,但是作用是非常明显的,使用了红色通道后使得误差降到了最低。
以上是关于红眼的一些基础知识。下面,我们将进入正题,如何自动祛除红眼。
下面是一幅红眼图片,我们将以这幅红眼图片做为讲解的例图。
通过分析例图,很容易得知:红眼是红的,因此,可以首先提取红色区域来大致获得红眼区域而避免讨论其他部分造成的额外开销,当然,这样的选择也有意外,那就是对红眼很不明显的图片会忽略不计。
如何提取红色区域呢?有几种方法,一种是取灰度和红色的差,一种是取红色和其他两种颜色中的最小值的差,而我使用的是通过取红色和其他两种颜色中最大值的差来实现的,这样提取出来的轮廓很不明显,所以,可以乘一个常数来提高红色的亮度。这样,例图就可以转换为下面的红色蒙版区域。
在红色蒙版区域中提取眼睛就容易多了。
现在,我们分析眼睛的特征。可以发现,眼睛的一个重要特征就是眼睛中间有黑眼珠、旁边有白眼仁。现在,就利用这个特征来进行眼睛的第一步筛选。对每个颜色偏红的点左右进行循环搜索(插叙:眼睛根据常识可知道上、下、左、右都有白眼仁,为了判断正确,只要左右任意一方有白眼仁即可)。判断是否泛白我采用的方法是首先判断灰度是否大于128,然后判断其他颜色和这个灰度的差值是否在一个常数以内,如果在的话就是白眼仁了。这样进行判断后可以大致确定是眼睛了,然后进入下一步,确定眼睛边界。因为红眼一般只出现在黑眼珠的中间部分,所以这里的确定眼睛边界其实是确定要祛除红眼的边界。这个确定方法就简单了,仍然循环搜索左右有没有颜色不太红的点,这个点就是边缘了。
下一步比较关键了,确定这一点是否是红眼。前面的过程再繁琐也不过只是进行下筛选,将有可能 是红眼的点筛选出来。尝试过用圆形度来进行判断,因为眼睛的非常非常重要的特征就是黑眼珠是圆的。不过很遗憾的是,我尝试这样方法的效果并不好,于是改用原始的办法,进行模式对比。简单言只,在这个以刚刚搜索的眼睛边界为边缘的矩形空间内和图片红眼进行匹配运算,看是否匹配,这样说来很抽象,看下图就清楚多了。
如果统计差值在一定的常数范围内的话,我们就近似的将这个图像看成是圆形的,这样判断的方法比圆形度在此高效的原因是很大一部分的眼睛圆部在红色蒙版区域上是和其他部位相连的,这样就容易被判断不圆,而采用这样的方法的话就完全没有这样的顾虑。
判断出了红眼的区域,就可以很方便的使用上面介绍的R + (R - Max(G, B)) / 112 * ((G * 59 + B * 11) div 70 - R)公式进行去红眼操作。
为了能够提高识别率,原则上应该对图片进行预处理。分析可以发现,有部分红眼图片的红眼中部不呈红色,这样对后期处理产生了一定的麻烦,解决方法是通过一个卷积模糊变形实现的,这个卷积公式是:
[1,2,1]
[2,0,2]
[1,2,1]
这个公式忽略了卷积的中部一点,能够有效的避免上面所说的问题。
另外,还可以用饱和度调整的方法,来提供红色区域和其他区域的差别。
更有甚者,我曾经尝试过利用图像色彩均衡后的图像来进行红眼识别,也一定程度上提高了识别率。自动图像色彩平衡的办法有兴趣的读者可以自行探究。
事实上,以上的方法可以达到识别率80%以上,下面是一些对比图片,很能够说明问题。
->->事实说明,上面介绍的方法在一定程度上还是有用的,当然,也希望大家能够研究出更完善的自动祛除红眼方法。