Python 线性模糊图像

Python 线性模糊图像,python,numpy,image-processing,linear-algebra,Python,Numpy,Image Processing,Linear Algebra,我试图通过将每个像素映射到图像右侧(同一行)N个像素的平均值来模糊图像。我的迭代解产生了良好的输出,但我的线性代数解产生了不良的输出 通过测试,我相信我的内核矩阵是正确的;而且,我知道最后N行不会变得模糊,但现在可以了。如果有任何提示或解决方案,我将不胜感激 迭代解输出(良好),线性代数输出(不良) 原始图像;下面是失败的线性代数代码: def blur(orig_img): # turn image-mat into a vector flattened_img = or

我试图通过将每个像素映射到图像右侧(同一行)N个像素的平均值来模糊图像。我的迭代解产生了良好的输出,但我的线性代数解产生了不良的输出

通过测试,我相信我的内核矩阵是正确的;而且,我知道最后N行不会变得模糊,但现在可以了。如果有任何提示或解决方案,我将不胜感激

迭代解输出(良好),线性代数输出(不良)

原始图像;下面是失败的线性代数代码:

def blur(orig_img):
    # turn image-mat into a vector
    flattened_img = orig_img.flatten()
    L = flattened_img.shape[0]
    N = 3

    # kernel
    kernel = np.zeros((L, L))
    for r, row in enumerate(kernel[0:-N]):
        row[r:r+N] = [round(1/N, 3)]*N
    print(kernel)

    # blurr the img
    print('starting blurring')
    blurred_img = np.matmul(kernel, flattened_img)
    blurred_img = blurred_img.reshape(orig_img.shape)
    return blurred_img
我建模的方程是:


一种选择可能是只使用内核和卷积

例如,如果我们加载灰度图像,如下所示:

import numpy as np
import matplotlib.pyplot as plt

from PIL import Image
from scipy import ndimage

# load a hackinsh grayscale image
image = np.asarray(Image.open('cup.jpg')).mean(axis=2)
plt.imshow(image)
plt.title('Gray scale image')
plt.show()

现在可以使用内核和卷积。例如,要创建只过滤一行的过滤器,并将中心像素的值计算为左右像素之间的差值,可以执行以下操作:

# Create a kernel that takes the difference between neighbors horizontal pixes
k = np.array([[-1,0,1]])
plt.subplot(121)
plt.title('Kernel')
plt.imshow(k)
plt.subplot(122)
plt.title('Output')
plt.imshow(ndimage.convolve(image, k, mode='constant', cval=0.0))
plt.show()

因此,通过创建适当的内核,可以将每个像素映射到图像右侧N个像素的平均值,从而使图像变得模糊

# Create a kernel that takes the average of N pixels to the right
n=10
k = np.zeros(n*2);k[n:]=1/n
k = k[np.newaxis,...]
plt.subplot(121)
plt.title('Kernel')
plt.imshow(k)
plt.subplot(122)
plt.title('Output')

plt.imshow(ndimage.convolve(image, k, mode='constant', cval=0.0))
plt.show()

问题是在显示输出图像时不正确使用了
cv2.imshow()
。它期望浮点像素值为[0,1];在下面的代码中完成(接近底部):

电流输出


感谢@CrisLuengo发现问题。

您如何显示图像?如果
orig\u img
是整数类型,而
fuzzle\u img
是浮点类型,则后者的值可能太大,无法显示。许多显示工具假定浮点图像在0-1范围内。感谢insight@CrisLuengo。我使用的是
cv2.imshow()
,将像素值规格化为0-1范围后,输出与预期一致。
def blur(orig_img):
    flattened_img = orig_img.flatten()
    L = flattened_img.shape[0]
    N = int(round(0.1 * orig_img.shape[0], 0))

    # mask (A)
    mask = np.zeros((L, L))
    for r, row in enumerate(mask[0:-N]):
        row[r:r+N] = [round(1/N, 2)]*N

    # blurred img = A * flattened_img
    print('starting blurring')
    blurred_img = np.matmul(mask, flattened_img)
    blurred_img = blurred_img.reshape(orig_img.shape)
    cv2.imwrite('blurred_img.png', blurred_img)

    # normalize img to [0,1]
    blurred_img = (
        blurred_img - blurred_img.min()) / (blurred_img.max()-blurred_img.min())
    return blurred_img