【问题标题】:Error with image sharpening in PythonPython中的图像锐化错误
【发布时间】:2020-01-21 18:20:17
【问题描述】:
from PIL import Image
fp="C:\\lena.jpg"
img=Image.open(fp)
w,h=img.size
pixels=img.load()

imgsharp=Image.new(img.mode,img.size,color=0)
sharp=[0,-1,0,-1,8,-1,0,-1,0]

for i in range(w):
    for j in range(h):

        for k in range(3):
                for m in range(3):
                    l=pixels[i-k+1,j-m+1]*sharp[i]

        if l>255:
            l=255
        elif l<0:
            l=0
        imgsharp.putpixel((i,j),l)

imgsharp.show()

我想将具有 3x3 蒙版大小的高通(锐化)滤镜应用于灰度图像。但我收到一个错误:

Traceback (most recent call last):
File "C:\sharp.py", line 16, in <module>
l=pixels[i-k+1,j-m+1]*sharp[i]
IndexError: image index out of range

如何解决我的错误以及如何使图像锐化在此代码中起作用?

【问题讨论】:

    标签: python image image-processing filter python-imaging-library


    【解决方案1】:

    您提到的具体错误是因为您没有处理图像的边框。一个解决方案是pad the image 或处理宽度和高度限制。例如:将i-k+1j-m+1分别替换为max(0, min(w, i-k+1))max(0, min(h, j-m+1)))

    您的代码还有其他问题:

    • 您访问的过滤器元素不正确...您可能指的是sharp[3*m+k],您在其中写了sharp[i]
    • 您使用的是彩色图像还是灰度图像?对于彩色图像,l 具有 3 个维度,不能直接与单个数字(0 或 255)进行比较。
    • 此外,l 值和 putpixel 调用的剪辑应位于最内层循环内。
    • 您的内核看起来有点奇怪。那8应该是5吗?或者也许 9 和 0 变成 -1?看看kernelsthis example
    • 这种具有多个嵌套循环的实现效率不高。

    我为您的问题推荐以下解决方案。

    如果你想锐化图像,仅此而已,你可以使用PIL.Image.filter

    from PIL import Image, ImageFilter
    
    
    img = Image.open('lena.png')
    img_sharp = img.filter(ImageFilter.SHARPEN)
    img_sharp.show()
    

    如果您确实想指定内核,请使用scipy 尝试以下操作。一定要看看convolve documentation

    from PIL import Image
    
    from scipy import ndimage, misc
    import numpy as np
    
    
    img = misc.imread('lena.png').astype(np.float)  # read as float
    kernel = np.array([0, -1, 0, -1, 5, -1, 0, -1, 0]).reshape((3, 3, 1))
    
    # here we do the convolution with the kernel
    imgsharp = ndimage.convolve(img, kernel, mode='nearest')
    # then we clip (0 to 255) and convert to unsigned int
    imgsharp = np.clip(imgsharp, 0, 255).astype(np.uint8)
    
    Image.fromarray(imgsharp).show()  # display
    

    另一种方法是使用 OpenCV。看看this article。它将澄清许多实现细节。

    【讨论】:

    • 多么有用的答案。我希望我能投票两次。
    【解决方案2】:

    我们也可以使用scipy.convolve2d 锐化RGB 图像。我们必须为每个图像通道分别应用卷积。以下代码对 lena 图像显示相同

    from scipy import misc, signal
    import numpy as np
    
    im = misc.imread('../images/lena.jpg')/255. # scale pixel values in [0,1] for each channel
    
    print(np.max(im))
    # 1.0
    print(im.shape)
    # (220, 220, 3)
    
    sharpen_kernel = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]])
    im_sharpened = np.ones(im.shape)
    for i in range(3):
        im_sharpened[...,i] = np.clip(signal.convolve2d(im[...,i], sharpen_kernel, mode='same', boundary="symm"),0,1)
    
    fig, ax = plt.subplots(nrows=2, figsize=(10, 20))
    ax[0].imshow(im)
    ax[0].set_title('Original Image', size=20)
    ax[1].imshow(im_sharpened)
    ax[1].set_title('Sharpened Image', size=20)
    plt.show()
    

    我们可以先用高斯核对图像进行模糊处理,然后从原始图像中减去,也可以得到一个锐化的图像,如下代码所示:

    from scipy import misc, ndimage
    
    im = misc.imread('../images/lena.jpg') / 255 # scale pixel values in [0,1] for each channel    
    
    # First a 1-D  Gaussian
    t = np.linspace(-10, 10, 30)
    bump = np.exp(-0.1*t**2)
    bump /= np.trapz(bump) # normalize the integral to 1
    
    # make a 2-D kernel out of it
    kernel = bump[:, np.newaxis] * bump[np.newaxis, :]
    
    im_blur = ndimage.convolve(im, kernel.reshape(30,30,1))
    
    im_sharp = np.clip(2*im - im_blur, 0, 1)
    
    fig, ax = plt.subplots(nrows=2, figsize=(10, 20))
    
    ax[0].imshow(im)
    ax[0].set_title('Original Image', size=20)
    
    ax[1].imshow(im_sharp)
    ax[1].set_title('Sharpened Image', size=20)
    
    plt.show()
    

    【讨论】:

      猜你喜欢
      • 2015-02-27
      • 2011-11-09
      • 2020-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-26
      • 2011-10-22
      • 2013-11-22
      相关资源
      最近更新 更多