簡體   English   中英

Python 中的圖像銳化錯誤

[英]Error with image sharpening in Python

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

如何修復我的錯誤以及如何在此代碼中進行圖像銳化?

您提到的具體錯誤是因為您沒有處理圖像的邊界。 解決方案是填充圖像或處理寬度和高度限制。 例如:分別用max(0, min(w, i-k+1))max(0, min(h, j-m+1)))代替i-k+1j-m+1

您的代碼還有其他問題:

  • 您正在訪問的過濾器元素不正確......您可能指的是sharp[3*m+k]在您寫sharp[i]
  • 您使用的是彩色還是灰度圖像? 對於彩色圖像, l有 3 個維度,不能直接與單個數字(0 或 255)進行比較。
  • 此外, l值的剪輯和putpixel調用應該在最內層循環內。
  • 你的內核看起來有點奇怪。 那8應該是5嗎? 或者 9 和 0 變成 -1? 看看內核這個例子
  • 這種具有多個嵌套循環的實現不是很有效。

我建議您使用以下解決方案來解決您的問題。

如果你想銳化圖像,僅此PIL.Image.filter ,你可以使用PIL.Image.filter

from PIL import Image, ImageFilter


img = Image.open('lena.png')
img_sharp = img.filter(ImageFilter.SHARPEN)
img_sharp.show()

如果您確實想指定內核,請使用scipy嘗試以下scipy 請務必查看卷積文檔

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。 看看這篇文章 它將澄清有關許多實現細節的事情。

我們也可以使用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()

在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM