Python编码的图像锐化算法
Image Sharpening Algorithm coded in Python
我希望有人可以看看我使用 PILLOW 设计的锐化算法,并向我解释为什么它不能对图像产生理想的锐化效果。当应用于我的示例图像时,它真的看起来像垃圾。我已经为此工作了好几天,但在提高锐化效果的质量或算法本身的效率方面都没有取得太大进展。理想情况下,我正在寻找一种微妙的锐化效果或可以轻松缩放的效果。我非常感谢可以提供的任何帮助或见解。以下是我用来提出这个算法的来源:
http://lodev.org/cgtutor/filtering.html#Sharpen
http://www.foundalis.com/res/imgproc.htm
from PIL import *
from PIL import Image
import os
os.chdir(r"C:")
filter1=9
filter2=-1
def sharpen2(photo,height,width,filter1,filter2):
for y in range(1,height-1):
for x in range(1,width-1):
(r,g,b)=photo.getpixel((x,y))
r=int(r*filter1)
g=int(g*filter1)
b=int(b*filter1)
(r1,g1,b1)=photo.getpixel((x-1,y-1))
r1=int(r1*filter2)
g1=int(g1*filter2)
b1=int(b1*filter2)
(r2,g2,b2)=photo.getpixel((x,y-1))
r2=int(r2*filter2)
g2=int(g2*filter2)
b2=int(b2*filter2)
(r3,g3,b3)=photo.getpixel((x+1,y-1))
r3=int(r3*filter2)
g3=int(g3*filter2)
b3=int(b3*filter2)
(r4,g4,b4)=photo.getpixel((x-1,y))
r4=int(r4*filter2)
g4=int(g4*filter2)
b4=int(b4*filter2)
(r5,g5,b5)=photo.getpixel((x+1,y))
r5=int(r5*filter2)
g5=int(g5*filter2)
b5=int(b5*filter2)
(r6,g6,b6)=photo.getpixel((x-1,y+1))
r6=int(r6*filter2)
g6=int(g6*filter2)
b6=int(b6*filter2)
(r7,g7,b7)=photo.getpixel((x,y+1))
r7=int(r7*filter2)
g7=int(g7*filter2)
b7=int(b7*filter2)
(r8,g8,b8)=photo.getpixel((x+1,y+1))
r8=int(r8*filter2)
g8=int(g8*filter2)
b8=int(b8*filter2)
rfPixel=r+r1+r2+r3+r4+r5+r6+r7+r8
if rfPixel>255:
rfPixel=255
elif rfPixel<0:
rfPixel=0
gfPixel= g+g1+g2+g3+g4+g5+g6+g7+g8
if gfPixel>255:
gfPixel=255
elif gfPixel<0:
gfPixel=0
bfPixel=b+b1+b2+b3+b4+b5+b6+b7+b8
if bfPixel>255:
bfPixel=255
elif bfPixel<0:
bfPixel=0
photo.putpixel((x,y),(rfPixel,gfPixel,bfPixel))
return photo
photo=Image.open("someImage.jpg").convert("RGB")
photo2=photo.copy()
height=photo.height
width=photo.width
x=sharpen2(photo,height,width,filter1,filter2)
一个问题可能是您将结果保存到从中获取像素数据的同一图像中。当你到达一个像素时,它的一些邻居已经被过滤后的数据所取代,而有些则没有。一开始误差很小,但加起来。
修复:将结果保存到不同的图像,比如 filtered_photo.putpixel(...)。您必须先创建一个空白 filtered_photo。
另一个大问题(@Mark Ransom 提到)是您可能希望 filter1 = 1.1 和 filter2 = -0.1 或类似的东西。使用 9 和 -1 会使大多数值超出范围。
更好的实现:不要在 python 代码中遍历每个像素,使用 numpy 一次处理整个图像,它会更快(并且代码更短)。锐化的通常实现是将原始图像减去高斯滤波图像,这是使用numpy和ndimage(或skimage)的单线。
我希望有人可以看看我使用 PILLOW 设计的锐化算法,并向我解释为什么它不能对图像产生理想的锐化效果。当应用于我的示例图像时,它真的看起来像垃圾。我已经为此工作了好几天,但在提高锐化效果的质量或算法本身的效率方面都没有取得太大进展。理想情况下,我正在寻找一种微妙的锐化效果或可以轻松缩放的效果。我非常感谢可以提供的任何帮助或见解。以下是我用来提出这个算法的来源:
http://lodev.org/cgtutor/filtering.html#Sharpen
http://www.foundalis.com/res/imgproc.htm
from PIL import *
from PIL import Image
import os
os.chdir(r"C:")
filter1=9
filter2=-1
def sharpen2(photo,height,width,filter1,filter2):
for y in range(1,height-1):
for x in range(1,width-1):
(r,g,b)=photo.getpixel((x,y))
r=int(r*filter1)
g=int(g*filter1)
b=int(b*filter1)
(r1,g1,b1)=photo.getpixel((x-1,y-1))
r1=int(r1*filter2)
g1=int(g1*filter2)
b1=int(b1*filter2)
(r2,g2,b2)=photo.getpixel((x,y-1))
r2=int(r2*filter2)
g2=int(g2*filter2)
b2=int(b2*filter2)
(r3,g3,b3)=photo.getpixel((x+1,y-1))
r3=int(r3*filter2)
g3=int(g3*filter2)
b3=int(b3*filter2)
(r4,g4,b4)=photo.getpixel((x-1,y))
r4=int(r4*filter2)
g4=int(g4*filter2)
b4=int(b4*filter2)
(r5,g5,b5)=photo.getpixel((x+1,y))
r5=int(r5*filter2)
g5=int(g5*filter2)
b5=int(b5*filter2)
(r6,g6,b6)=photo.getpixel((x-1,y+1))
r6=int(r6*filter2)
g6=int(g6*filter2)
b6=int(b6*filter2)
(r7,g7,b7)=photo.getpixel((x,y+1))
r7=int(r7*filter2)
g7=int(g7*filter2)
b7=int(b7*filter2)
(r8,g8,b8)=photo.getpixel((x+1,y+1))
r8=int(r8*filter2)
g8=int(g8*filter2)
b8=int(b8*filter2)
rfPixel=r+r1+r2+r3+r4+r5+r6+r7+r8
if rfPixel>255:
rfPixel=255
elif rfPixel<0:
rfPixel=0
gfPixel= g+g1+g2+g3+g4+g5+g6+g7+g8
if gfPixel>255:
gfPixel=255
elif gfPixel<0:
gfPixel=0
bfPixel=b+b1+b2+b3+b4+b5+b6+b7+b8
if bfPixel>255:
bfPixel=255
elif bfPixel<0:
bfPixel=0
photo.putpixel((x,y),(rfPixel,gfPixel,bfPixel))
return photo
photo=Image.open("someImage.jpg").convert("RGB")
photo2=photo.copy()
height=photo.height
width=photo.width
x=sharpen2(photo,height,width,filter1,filter2)
一个问题可能是您将结果保存到从中获取像素数据的同一图像中。当你到达一个像素时,它的一些邻居已经被过滤后的数据所取代,而有些则没有。一开始误差很小,但加起来。
修复:将结果保存到不同的图像,比如 filtered_photo.putpixel(...)。您必须先创建一个空白 filtered_photo。
另一个大问题(@Mark Ransom 提到)是您可能希望 filter1 = 1.1 和 filter2 = -0.1 或类似的东西。使用 9 和 -1 会使大多数值超出范围。
更好的实现:不要在 python 代码中遍历每个像素,使用 numpy 一次处理整个图像,它会更快(并且代码更短)。锐化的通常实现是将原始图像减去高斯滤波图像,这是使用numpy和ndimage(或skimage)的单线。