人工智能应用实例:图片降噪
场景设置
对白色背景、黑色前景的黑白图片进行降噪处理,可以假定背景部分多于前景。
图1 从左往右:原图、噪声图、降噪图
降噪模型
我们可以对图片建立这样一个两层的二维模型,底层表示原图,顶层表示任意的噪声图,xi为原图第i个像素,yi为噪声图第i个像素,xi、yi的取值只有1和-1,1表示白色,-1表示黑色。
图2 图片模型
显然,我们对噪声图任取的一个像素yi可以有以下3个推测:
1、这个像素更加可能是白色,因为白色背景多于黑色前景。
2、这个像素应该和它周围的几个像素颜色一致。
3、如果不能确定这个像素在原图到底是白色还是黑色,那么更有可能原图就是现在噪声图的这个颜色,因为毕竟噪声像素是少量的,大部分像素维持了原图的颜色。
基于此,可以对噪声图定义一个能量公式:
注意:这里的xi、yi颠倒过来了,xi为噪声图,yi为原图。
公式中三个参数都是正实数,第一项表示对噪声图每个像素的值求和,第二项表示对噪声图每个像素与之周围像素差异的求和,第三项表示噪声图像素与原图像素的差异求和。显然基于我们以上的3点推测,越接近原图,噪声图的能量值应该越低。
降噪过程
有了这样一个图片模型和噪声图能量公式,我们就可以对图片降噪了。图片降噪基于一个很简单的想法,我们对整个噪声图的每个像素扫描一次(也可以扫描多遍),看看每次改变该像素点的颜色能否使整个噪声图的能量值降低,如果能量值降低了,我们就接受这一次改动,否则,该像素颜色保持不变。
不过,这里还存在一个问题,我们不可能取得能量公式中原图每个像素yi的值!其实这也无妨,可以简单地用每次降噪处理(一次只处理一个像素)得到的新的降噪图去逼近原图,而一开始采用的就是噪声图。因此,每次降噪处理都要计算两个能量值,一个是当前已经得到的降噪图(被用来逼近原图,即xi、yi都是自身)的能量值,另一个是改变一个像素颜色得到的图片(xi为自身,yi为前面得到的降噪图)的能量值。
Java代码实现
由于某些限制,代码实现中图片读写使用了十分复杂的手段,实际上可以通过Java的imageio包进行简化。