中值滤波将图像的每个像素用邻域 (以当前像素为中心的正方形区域)像素的 中值 代替 。与邻域平均法类似,但计算的是中值
#用中值法
for y in xrange(1,myh-1):
for x in xrange(1,myw-1):
lbimg[y,x]=np.median(tmpimg[y-1:y+2,x-1:x+2]
下面调用opencv的函数
# -*- coding: utf-8 -*-
#code:[email protected]
#中值滤波
import cv2
import numpy as np
fn="test3.jpg"
myimg=cv2.imread(fn)
img=cv2.cvtColor(myimg,cv2.COLOR_BGR2GRAY)
#加上椒盐噪声
#灰阶范围
w=img.shape[1]
h=img.shape[0]
newimg=np.array(img)
#噪声点数量
noisecount=50000
for k in xrange(0,noisecount):
xi=int(np.random.uniform(0,newimg.shape[1]))
xj=int(np.random.uniform(0,newimg.shape[0]))
newimg[xj,xi]=255
#滤波去噪
lbimg=cv2.medianBlur(newimg,3)
cv2.imshow('src',newimg)
cv2.imshow('dst',lbimg)
cv2.waitKey()
cv2.destroyAllWindows()
中值滤波忽略了较高阶灰度和较低阶灰度,直接取中值,因此有效得过滤椒盐噪声。
对高斯噪声的滤波
用scipy.signal中值滤波
中值滤波技术能有效抑制噪声,通过把数字图像中一点的值用该点周围的各点值的中位数来代替,让这些值接近,以消除原图像中的噪声。
*模拟中值滤波
>>> import random
>>> import numpy as np
>>> import scipy.signal as signal
>>> x=np.arange(0,100,10)
>>> random.shuffle(x)
>>> x
array([70, 80, 30, 20, 10, 90, 0, 60, 40, 50])
>>> signal.medfilt(x,3) #一维中值滤波
array([ 70., 70., 30., 20., 20., 10., 60., 40., 50., 40.])
signal的medfilt()方法传入两个参数,第一个参数是要作中值滤波的信号,第二个参数是邻域的大小(奇数)。如邻域为3即是每个点自己和左右各一个点成为一个邻域。在每个位置的邻域中选取中位数替换这个位置的数,也就是该函数的返回值数组。如果邻域中出现没有元素的位置,那么以0补齐。
>>> x=np.random.randint(1,1000,(4,4))
>>> x
array([[ 31, 33, 745, 483],
[331, 469, 804, 479],
[235, 487, 244, 982],
[857, 114, 167, 174]])
>>> signal.medfilt(x,(3,3)) #二维中值滤波
array([[ 0., 33., 469., 0.],
[ 33., 331., 483., 479.],
[ 235., 331., 469., 174.],
[ 0., 167., 167., 0.]])
二维中值滤波还可以用signal.medfilt2d(),速度较快,但只支持int8,float32和float64。
*对图像中值滤波 (这个代码我还没试,如果出现问题可以怀疑是代码的问题)
import numpy as np
from PIL import Image
import scipy.signal as signal
im=Image.open('test.jpg') #读入图片并建立Image对象im
data=[] #存储图像中所有像素值的list(二维)
width,height=im.size #将图片尺寸记录下来
#读取图像像素的值
for h in range(height): #对每个行号h
row=[] #记录每一行像素
for w in range(width): #对每行的每个像素列位置w
value=im.getpixel((h,w)) #用getpixel读取这一点像素值
row.append(value)#把它加到这一行的list中去
data.append(row) #把记录好的每一行加到data的子list中去,就建立了模拟的二维list
data=signal.medfilt(data,kernel_size=3) #二维中值滤波
data=np.int32(data) #转换为int类型,以使用快速二维滤波
#创建并保存结果
for h in range(height): #对每一行
for w in range(width): #对该行的每一个列号
im.putpixel((h,w),tuple(data[h][w])) #将data中该位置的值存进图像,要求参数为tuple
im.save('result.jpg')#存储
reference
https://blog.csdn.net/myhaspl/article/details/37997977
https://blog.csdn.net/shu15121856/article/details/76273137