我正在嘗試為尺寸為(256、320、4)的影像實作高斯濾波器。
我首先為它生成了一個高斯內核,然后在 4 個通道中的每個通道上單獨執行卷積,即在所有 256*320 灰度影像上。執行此操作后,我希望將影像組合成彩色影像。
但是,當我這樣做時,它似乎沒有按預期作業。期望看到原始影像的模糊版本,模糊取決于 sigma 的值。但是,當我運行代碼時,我只是得到一個白色影像,沒有任何模糊。
from PIL import Image
image = imageio.imread('graf_small.png')
print(image.shape)
def gaussian_filter(image, s):
probs = [np.exp(-z*z/(2*s*s))/np.sqrt(2*np.pi*s*s) for z in range(-3*s,3*s 1)]
kernel = np.outer(probs, probs)
channels = image.shape[2]
final_output = np.ndarray((image.shape[0],image.shape[1], image.shape[2]))
for i in range(4):
channels = image.shape[2]
im = np.ndarray((image.shape[0],image.shape[1]))
print(channels)
im[:,:] = image[:,:,i]
# generate a (2k 1)x(2k 1) gaussian kernel with mean=0 and sigma = s
probs = [np.exp(-z*z/(2*s*s))/np.sqrt(2*np.pi*s*s) for z in range(-3*s,3*s 1)]
kernel = np.outer(probs, probs)
# Cross Correlation
# Gather Shapes of Kernel Image Padding
xKernShape = kernel.shape[0]
yKernShape = kernel.shape[1]
xImgShape = im.shape[0]
yImgShape = im.shape[1]
strides= 1
padding= 6
# Shape of Output Convolution
xOutput = int(((xImgShape - xKernShape 2 * padding) / strides) 1)
yOutput = int(((yImgShape - yKernShape 2 * padding) / strides) 1)
output = np.zeros((xOutput, yOutput))
# Apply Equal Padding to All Sides
if padding != 0:
imagePadded = np.zeros((im.shape[0] padding*2, im.shape[1] padding*2))
imagePadded[int(padding):int(-1 * padding), int(padding):int(-1 * padding)] = im
#print(imagePadded)
else:
imagePadded = image
# Iterate through image
for y in range(image.shape[1]):
# Exit Convolution
if y > image.shape[1] - yKernShape:
break
# Only Convolve if y has gone down by the specified Strides
if y % strides == 0:
for x in range(image.shape[0]):
# Go to next row once kernel is out of bounds
if x > image.shape[0] - xKernShape:
break
try:
# Only Convolve if x has moved by the specified Strides
if x % strides == 0:
output[x, y] = (kernel * imagePadded[x: x xKernShape, y: y yKernShape]).sum()
except:
break
final_output[:,:,i] = output[:,:]
final_output =np.dstack((final_output[:,:,0],final_output[:,:,1],final_output[:,:,2],final_output[:,:,3]))
#print(merged.shape)
return final_output
為了測驗函式,呼叫了一個輔助函式 >
def plot_multiple(images, titles, colormap='gray', max_columns=np.inf, share_axes=True):
"""Plot multiple images as subplots on a grid."""
assert len(images) == len(titles)
n_images = len(images)
n_cols = min(max_columns, n_images)
n_rows = int(np.ceil(n_images / n_cols))
fig, axes = plt.subplots(
n_rows, n_cols, figsize=(n_cols * 4, n_rows * 4),
squeeze=False, sharex=share_axes, sharey=share_axes)
axes = axes.flat
# Hide subplots without content
for ax in axes[n_images:]:
ax.axis('off')
if not isinstance(colormap, (list,tuple)):
colormaps = [colormap]*n_images
else:
colormaps = colormap
for ax, image, title, cmap in zip(axes, images, titles, colormaps):
ax.imshow(image, cmap=cmap)
ax.set_title(title)
fig.tight_layout()
image = imageio.imread('graf_small.png')
sigmas = [2]
blurred_images = [gaussian_filter(image, s) for s in sigmas]
titles = [f'sigma={s}' for s in sigmas]
plot_multiple(blurred_images, titles)

uj5u.com熱心網友回復:
似乎所有問題都在于您獲取影像float64但matplot需要uint8顯示它。
imageio將其保存在檔案中作為正確的影像,但有警告"Lossy conversion from float64 to uint8"
這兩個問題都可以解決轉換為uint8
return final_output.astype(np.uint8)
完整的作業代碼,幾乎沒有小改動
- 我洗掉了 dstack
- 我需要
size = output.shape[:2]并且final_output[:size[0],:size[1],i] = output[:,:]
import imageio
import numpy as np
import matplotlib.pyplot as plt
def gaussian_filter(image, s):
probs = [np.exp(-z*z/(2*s*s))/np.sqrt(2*np.pi*s*s) for z in range(-3*s,3*s 1)]
kernel = np.outer(probs, probs)
channels = image.shape[2]
print('channels:', channels)
final_output = np.ndarray((image.shape[0],image.shape[1], image.shape[2]))
for i in range(channels):
im = image[:,:,i]
# generate a (2k 1)x(2k 1) gaussian kernel with mean=0 and sigma = s
probs = [np.exp(-z*z/(2*s*s))/np.sqrt(2*np.pi*s*s) for z in range(-3*s,3*s 1)]
kernel = np.outer(probs, probs)
# Cross Correlation
# Gather Shapes of Kernel Image Padding
xKernShape = kernel.shape[0]
yKernShape = kernel.shape[1]
xImgShape = im.shape[0]
yImgShape = im.shape[1]
strides= 1
padding= 6
# Shape of Output Convolution
xOutput = int(((xImgShape - xKernShape 2 * padding) / strides) 1)
yOutput = int(((yImgShape - yKernShape 2 * padding) / strides) 1)
output = np.zeros((xOutput, yOutput))
# Apply Equal Padding to All Sides
if padding != 0:
imagePadded = np.zeros((im.shape[0] padding*2, im.shape[1] padding*2))
imagePadded[int(padding):int(-1 * padding), int(padding):int(-1 * padding)] = im
#print(imagePadded)
else:
imagePadded = image
# Iterate through image
for y in range(image.shape[1]):
# Exit Convolution
if y > image.shape[1] - yKernShape:
break
# Only Convolve if y has gone down by the specified Strides
if y % strides == 0:
for x in range(image.shape[0]):
# Go to next row once kernel is out of bounds
if x > image.shape[0] - xKernShape:
break
try:
# Only Convolve if x has moved by the specified Strides
if x % strides == 0:
output[x, y] = (kernel * imagePadded[x: x xKernShape, y: y yKernShape]).sum()
except:
break
size = output.shape[:2]
final_output[:size[0],:size[1],i] = output[:,:]
return final_output.astype(np.uint8)
def plot_multiple(images, titles, colormap='gray', max_columns=np.inf, share_axes=True):
"""Plot multiple images as subplots on a grid."""
assert len(images) == len(titles)
n_images = len(images)
n_cols = min(max_columns, n_images)
n_rows = int(np.ceil(n_images / n_cols))
fig, axes = plt.subplots(
n_rows, n_cols, figsize=(n_cols * 4, n_rows * 4),
squeeze=False, sharex=share_axes, sharey=share_axes)
axes = axes.flat
# Hide subplots without content
for ax in axes[n_images:]:
ax.axis('off')
if not isinstance(colormap, (list,tuple)):
colormaps = [colormap]*n_images
else:
colormaps = colormap
for ax, image, title, cmap in zip(axes, images, titles, colormaps):
ax.imshow(image, cmap=cmap)
ax.set_title(title)
fig.tight_layout()
plt.show()
# --- main --
image = imageio.imread('test/lenna.png')
print('shape:', image.shape)
sigmas = [2, 3, 5]
blurred_images = [gaussian_filter(image, s) for s in sigmas]
titles = [f'sigma={s}' for s in sigmas]
plot_multiple(blurred_images, titles)
for number, image in enumerate(blurred_images, 1):
imageio.imsave(f'output-{number}.png', image)
來自維基百科的原始影像
結果:

轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/468341.html
標籤:Python matplotlib 图像处理 python成像库 python-imageio
上一篇:Liquibase僅與H2導致“無法準備陳述句;SQL”
下一篇:Numpy中的像素操作
