实验目的
最小二乘法是一个很实用,也很基础的算法,应用的场景十分的广泛和普遍,最常用的地方就是机器学习了,通过最小二乘,来进行分类/回归,还有曲线拟合。
本文通过最小二乘法对图像像素点进行拟合,通过拟合曲线去去除图像中的椒盐噪声,实现还原照片的目的,并与中值滤波去除图像椒盐噪声做对比。
最小二乘法介绍
对于给定的数据
,在取定的假设空间H中,求解h(x)∈H,使得残差
的2-范数最小,即
从几何上讲,就是寻找与给定点
距离平方和最小的曲线y=h(x)。h(x)称为拟合函数或者最小二乘解,求解拟合函数h(x)的方法称为曲线拟合的最小二乘法。
在本文中,我们使用的拟合函数是一个线性函数,即:
当然,也可以是二次函数,或者更高维的函数,这里仅仅是作为求解简单,所以采用了最简单的线性函数
那么我们的目标就是找到这样的w,
这里令
为样本
的平方损失函数这里的Q(w)即为我们要进行最优化的风险函数。
学过微积分的同学应该比较清楚,这是一个典型的求解极值的问题,只需要分别对w1,w2求偏导数,然后令偏导数为0,即可求解出极值点,即:
接下来只需要求解这个方程组即可解出wi 的值
解题算法
首先,对于一张完整图片的每个像素点来说,其周围像素必定是一条平滑的曲线,而在出现椒盐噪声的图片中,某些噪声的像素点会与周围像素点偏差过大。利用这个思路,本文中选取了3X3的模板,也就是说,对于每一个像素点(x,y)我们选取和它相邻的八个点作为一个函数曲线,对于每一个所要求的像素点(x,y),我们设置其为中心原点坐标,即(0,0)点
(-1,-1) | (0,-1) | (1,-1) |
(-1,0) | (0,0) | (1,0) |
(-1,1) | (0,1) | (1,1) |
将9个像素点的像素值存到mask数组中,其代码如下:
#获取mask数值
for j in range(1,image.shape[0]-1):
for i in range(1,image.shape[1]-1):
for h in range(3):
for g in range(3):
y = j + h - 1
x = i + g - 1
mask[h*3+g]=image[x,y]
得到这一像素点自身以及周围的像素值后,将这9个像素值作为样本点,传入最小二乘法线性函数模型中,即公式
,其程序模型如下:
def fun(p,x): #回归模型函数
f = np.poly1d(p)
return f(x)
def error(p,x,y): #误差
regularization = 0.01
ret = LogicClass.fun(p,x)-y
ret = np.append(ret, np.sqrt(regularization) * p)
return ret
p0 = np.random.randn(2)# 随机初始化多项式参数
para = leastsq(LogicClass.error,p0,args=(X,mask))
k,b = para[0]
经过计算,得到该线性函数模型的参数k和b,即通过这9个像素值拟合而成的曲线为
,接着,通过对比9个像素点的像素值和拟合曲线得出的像素值的距离,找到距离拟合曲线最远的像素值是否为(0,0)点,若是,则替换像素点的像素值为拟合曲线的得出来的像素值。程序如下:
for n in range(9):
value.append(mask[n]-(k*n+b))
if np.argmax(np.absolute(value)) == 4:
image[i,j] = k*4+b
通过以上步骤,一个像素点经过最小二乘法拟合得到的像素值将会替换原有像素点的像素值,接着,只需要遍历图片的每一个像素点,都对这些像素点进行以上操作,便能实现将图片噪声去除的目的。
实验结果
由图可知,实验结果中,中值滤波和最小二乘滤波都能很好的去除图二中的椒盐噪声,但是,从实践中发现,最小二乘滤波算法执行的时间过长,并且此算法对于边界的像素点无法进行处理,故还需要优化
代码下载
下面是我这整个工程的完整python代码和实验报告,有需要的麻烦支持一下,谢谢!