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
如何解决我的错误?如何让图像锐化在此代码中工作?
答案 0 :(得分:5)
您提到的具体错误是因为您没有处理图像的边框。解决方案是pad the image或处理宽度和高度限制。例如:分别按i-k+1
和j-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
调用的剪辑应该在最近的循环中。我建议您解决以下问题。
如果您想要锐化图像,那就可以使用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。它将清除许多实现细节的内容。
答案 1 :(得分:0)
我们也可以使用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()