opencv-python图像高通滤波与低通滤波
一、高通滤波
高通滤波原理
高通滤波意思就是让频率高的部分通过,衍生到图像上面来理解,一张图片的像素一般来说,在轮廓的地方频率高,而在其他部分频率低。
对于傅里叶变换而言,它将一张图像高频部分显示在外围,而低频部分显示在中间;因此,高通滤波就是将傅里叶变换之后的频谱图的中间部分过滤;过滤方法就是将中间部分区域的低频对应的像素值给设置为0,设置为黑色。如图所示:
这个黑色区域就是需要我们构造的区域,尺寸是通过我们自定义的。
具体代码描述
1.构造高通滤波范围。
def highPassFiltering(img,size):#传递参数为傅里叶变换后的频谱图和滤波尺寸
h, w = img.shape[0:2]#获取图像属性
h1,w1 = int(h/2), int(w/2)#找到傅里叶频谱图的中心点
img[h1-int(size/2):h1+int(size/2), w1-int(size/2):w1+int(size/2)] = 0#中心点加减滤波尺寸的一半,刚好形成一个定义尺寸的滤波大小,然后设置为0
return img
2.现将一张灰度图进行傅里叶变换,获取该图片的频谱图,然后再调用高通滤波函数进行滤波,最后再通过傅里叶逆变换查看结果。
def cv2_imread(file_path, flag=1):
# 读取图片数据
return cv2.imdecode(np.fromfile(file_path, dtype=np.uint8), flag)
gray = cv2_imread("C://Users//小白二号//Desktop//dd.png", 1)
gray = cv2.cvtColor(gray, cv2.COLOR_BGR2GRAY)
gray = cv2.resize(gray, (640, 420))
# 傅里叶变换
img_dft = np.fft.fft2(gray)
dft_shift = np.fft.fftshift(img_dft) # 将频域从左上角移动到中间
#高通滤波
dft_shift=highPassFiltering(dft_shift,200)
res = np.log(np.abs(dft_shift))
# 傅里叶逆变换
idft_shift = np.fft.ifftshift(dft_shift) #将频域从中间移动到左上角
ifimg = np.fft.ifft2(idft_shift) # 傅里叶库函数调用
ifimg = np.abs(ifimg)
cv2.imshow("ifimg",np.int8(ifimg))
cv2.imshow("gray",gray)
# 绘制图片
plt.subplot(131), plt.imshow(gray, 'gray'), plt.title('原图像')
plt.axis('off')
plt.subplot(132), plt.imshow(res, 'gray'), plt.title('高通滤波')
plt.axis('off')
plt.subplot(133), plt.imshow(np.int8(ifimg), 'gray'), plt.title('滤波后效果')
plt.axis('off')
plt.show()
cv2.waitKey(0)
cv2.destroyAllWindows()
运行效果:
二、低通滤波
低通滤波原理
低通滤波顾名思义就是低频可以通过,过滤掉高频部分,而对于图像的噪声,包括椒盐噪声和高斯噪声,他们的频率都是比较高的例如像素值为255,那么低通滤波就会将这些噪声过滤,但低通滤波并没有识别功能,图像中有些区域的像素同样为255,同理,低通滤波也会将其完全过滤,因此我们可以简单认为,低通滤波其实就是将频域图中心部分保留,将外围部分过滤,衍生到图像中就是将高频区域对应的像素值设置为0(黑色)。
其实现方式大致思路如下图:
具体代码实例
1.构造低通滤波范围
def lowPassFiltering(img,size):#传递参数为傅里叶变换后的频谱图和滤波尺寸
h, w = img.shape[0:2]#获取图像属性
h1,w1 = int(h/2), int(w/2)#找到傅里叶频谱图的中心点
img2 = np.zeros((h, w), np.uint8)#定义空白黑色图像,和傅里叶变换传递的图尺寸一致
img2[h1-int(size/2):h1+int(size/2), w1-int(size/2):w1+int(size/2)] = 1#中心点加减滤波尺寸的一半,刚好形成一个定义尺寸的滤波大小,然后设置为1,保留低频部分
img3=img2*img #将定义的低通滤波与传入的傅里叶频谱图一一对应相乘,得到低通滤波
return img3
2.读取图像添加噪声并灰度化,进行傅里叶变换后调用低通滤波函数,然后通过傅里叶逆变换还原观察图像变化
def cv2_imread(file_path, flag=1):
# 读取图片数据
return cv2.imdecode(np.fromfile(file_path, dtype=np.uint8), flag)
gray = cv2_imread("C://Users//小白二号//Desktop//dd.png", 1)
gray = cv2.cvtColor(gray, cv2.COLOR_BGR2GRAY)
gray = cv2.resize(gray, (1280, 720))
h,w =gray.shape
for i in range(3000): #添加3000个噪声点
x = np.random.randint(0, h)
y = np.random.randint(0, w)
gray[x,y] = 255
# 傅里叶变换
img_dft = np.fft.fft2(gray)
dft_shift = np.fft.fftshift(img_dft) # 将频域从左上角移动到中间
# 低通滤波
dft_shift = lowPassFiltering(dft_shift, 200)
res = np.log(np.abs(dft_shift))
# 傅里叶逆变换
idft_shift = np.fft.ifftshift(dft_shift) # 将频域从中间移动到左上角
ifimg = np.fft.ifft2(idft_shift) # 傅里叶库函数调用
ifimg = np.abs(ifimg)
cv2.imshow("ifimg", np.int8(ifimg))
cv2.imshow("gray", gray)
# 绘制图片
plt.subplot(131), plt.imshow(gray, 'gray'), plt.title('原图像')
plt.axis('off')
plt.subplot(132), plt.imshow(res, 'gray'), plt.title('低通滤波')
plt.axis('off')
plt.subplot(133), plt.imshow(np.int8(ifimg), 'gray'), plt.title('滤波后效果')
plt.axis('off')
plt.show()
cv2.waitKey(0)
cv2.destroyAllWindows()
运行效果:
图像的噪声基本去掉,也就是说,低通滤波消除噪声的强度取决于你构造低通滤波的尺寸大小,尺寸越大,消除越不好,图像越清晰;尺寸越小,消除越好,图像越模糊