python - 用于模糊图像的低通滤波器
问题描述
我试图通过传递我创建的低通滤波器来使用 fft 模糊图像,但输出会产生一个充满灰色噪声的图像。我只是想遵循这里的基础知识,但我的实现似乎有问题:
from scipy import fftpack
import numpy as np
import imageio
from PIL import Image, ImageDraw
image1 = imageio.imread('image.jpg',as_gray=True)
#convert image to numpy array
image1_np=np.array(image)
#fft of image
fft1 = fftpack.fftshift(fftpack.fft2(image1_np))
#Create a low pass filter image
x,y = image1_np.shape[0],image1_np.shape[1]
#size of circle
e_x,e_y=50,50
#create a box
bbox=((x/2)-(e_x/2),(y/2)-(e_y/2),(x/2)+(e_x/2),(y/2)+(e_y/2))
low_pass=Image.new("L",(image1_np.shape[0],image1_np.shape[1]),color=0)
draw1=ImageDraw.Draw(low_pass)
draw1.ellipse(bbox, fill=255)
low_pass_np=np.array(low_pass)
low_pass_fft=fftpack.fftshift(fftpack.fft2(low_pass))
#multiply both the images
filtered=np.multiply(fft1,low_pass_fft)
#inverse fft
ifft2 = abs(fftpack.ifft2(fftpack.ifftshift(filtered)))
#save the image
imageio.imsave('fft-then-ifft.png', ifft2.astype(np .uint8))
解决方案
正如Cris Luengo的评论中提到的,有一些事情需要纠正:
- 为低通滤波器提供的椭圆形状在频域中是有意义的,因此您不应该计算它的 FFT。
过滤器大小
255
将结果缩放相同的量。当您存储如此大的值时,uint8
类型会环绕以仅保留 8 个最低有效位,从而导致看起来像噪声的东西。这可以通过简单地更改过滤器的值来解决:draw1.ellipse(bbox, fill=1)
重新调整缩放比例后,在图像的某些区域中,计算
filtered
结果可能仍会略微超出所需的 0-255 范围。这会产生环绕点(由白色像素包围的区域中的黑色区域,由黑色像素包围的区域中的白色区域,甚至是图像从白色到黑色再到白色的渐变带)。为避免这种情况,通常使用以下内容将值剪辑到 0-255 范围内:ifft2 = np.real(fftpack.ifft2(fftpack.ifftshift(filtered))) ifft2 = np.maximum(0, np.minimum(ifft2, 255))
进行这些更正后,您应该具有以下代码:
from scipy import fftpack
import numpy as np
import imageio
from PIL import Image, ImageDraw
image1 = imageio.imread('image.jpg',as_gray=True)
#convert image to numpy array
image1_np=np.array(image1)
#fft of image
fft1 = fftpack.fftshift(fftpack.fft2(image1_np))
#Create a low pass filter image
x,y = image1_np.shape[0],image1_np.shape[1]
#size of circle
e_x,e_y=50,50
#create a box
bbox=((x/2)-(e_x/2),(y/2)-(e_y/2),(x/2)+(e_x/2),(y/2)+(e_y/2))
low_pass=Image.new("L",(image1_np.shape[0],image1_np.shape[1]),color=0)
draw1=ImageDraw.Draw(low_pass)
draw1.ellipse(bbox, fill=1)
low_pass_np=np.array(low_pass)
#multiply both the images
filtered=np.multiply(fft1,low_pass_np)
#inverse fft
ifft2 = np.real(fftpack.ifft2(fftpack.ifftshift(filtered)))
ifft2 = np.maximum(0, np.minimum(ifft2, 255))
#save the image
imageio.imsave('fft-then-ifft.png', ifft2.astype(np .uint8))
以及以下过滤后的图像:
推荐阅读
- express - Fastify 和 Express 可以一起运行吗?
- php - Laravel SQL Query 相似词搜索
- java - 如何告诉 Android Studio 方法不返回
- angular - Observable rxjs/Observable 的导入不起作用
- python - 我应该如何每五年增加一个值并将这些值放入 Python 中的列表中?
- angularjs - 将 curl 与 AngularJS 和 bash 一起使用
- php - 我需要在 Laravel 中创建 .Zip 文件,但我的代码不起作用
- javascript - 将数据表原始 ID 获取到另一个数据表
- java - 为什么这会产生意想不到的返回值?
- python - DBSCAN 标签数量与预测标签不匹配