编辑: 感谢Howard的帮助,我已经纠正了代码,并且现在看起来它可以工作了。
编辑2: 我已经更新了代码,以包括最初想要的垂直模糊。各种设置下的结果样本输出: 模糊比较图像.jpg
另一个关于模糊操作的参考(Java): 初学者的模糊处理
原始帖子:
我正在尝试学习基本的图像处理,并在python中复制这个简单的模糊方法 (在“重用结果”下的第二个函数BlurHorizontal)。我知道PIL中已经有了模糊函数,但是我想自己尝试基本的像素操作。
这个函数应该接收一个源图像,然后根据一定的半径平均RGB像素值,并将处理后的图像写入一个新文件。我的问题是,我得到了很多像素完全错误的平均值(例如,在某些区域,亮绿色线条而不是红色)。
使用模糊半径为2时,平均方法会将中心在输入像素上的5个像素的RGB值相加。它使用“滑动窗口”来保持运行总数,减去传出像素(左侧)并添加新的传入像素(窗口右侧)。在这里解释模糊方法
样本: 模糊测试图像输出.jpg
有什么想法我哪里做错了吗?我不确定为什么图像的某些部分可以清晰地模糊,而其他区域则充满了与周围区域完全无关的颜色。
感谢您的帮助。
修复后的可工作代码 (感谢Howard)
import Image, numpy, ImageFilter
img = Image.open('testimage.jpg')
imgArr = numpy.asarray(img) # readonly
# blur radius in pixels
radius = 2
# blur window length in pixels
windowLen = radius*2+1
# columns (x) image width in pixels
imgWidth = imgArr.shape[1]
# rows (y) image height in pixels
imgHeight = imgArr.shape[0]
#simple box/window blur
def doblur(imgArr):
# create array for processed image based on input image dimensions
imgB = numpy.zeros((imgHeight,imgWidth,3),numpy.uint8)
imgC = numpy.zeros((imgHeight,imgWidth,3),numpy.uint8)
# blur horizontal row by row
for ro in range(imgHeight):
# RGB color values
totalR = 0
totalG = 0
totalB = 0
# calculate blurred value of first pixel in each row
for rads in range(-radius, radius+1):
if (rads) >= 0 and (rads) <= imgWidth-1:
totalR += imgArr[ro,rads][0]/windowLen
totalG += imgArr[ro,rads][1]/windowLen
totalB += imgArr[ro,rads][2]/windowLen
imgB[ro,0] = [totalR,totalG,totalB]
# calculate blurred value of the rest of the row based on
# unweighted average of surrounding pixels within blur radius
# using sliding window totals (add incoming, subtract outgoing pixels)
for co in range(1,imgWidth):
if (co-radius-1) >= 0:
totalR -= imgArr[ro,co-radius-1][0]/windowLen
totalG -= imgArr[ro,co-radius-1][1]/windowLen
totalB -= imgArr[ro,co-radius-1][2]/windowLen
if (co+radius) <= imgWidth-1:
totalR += imgArr[ro,co+radius][0]/windowLen
totalG += imgArr[ro,co+radius][1]/windowLen
totalB += imgArr[ro,co+radius][2]/windowLen
# put average color value into imgB pixel
imgB[ro,co] = [totalR,totalG,totalB]
# blur vertical
for co in range(imgWidth):
totalR = 0
totalG = 0
totalB = 0
for rads in range(-radius, radius+1):
if (rads) >= 0 and (rads) <= imgHeight-1:
totalR += imgB[rads,co][0]/windowLen
totalG += imgB[rads,co][1]/windowLen
totalB += imgB[rads,co][2]/windowLen
imgC[0,co] = [totalR,totalG,totalB]
for ro in range(1,imgHeight):
if (ro-radius-1) >= 0:
totalR -= imgB[ro-radius-1,co][0]/windowLen
totalG -= imgB[ro-radius-1,co][1]/windowLen
totalB -= imgB[ro-radius-1,co][2]/windowLen
if (ro+radius) <= imgHeight-1:
totalR += imgB[ro+radius,co][0]/windowLen
totalG += imgB[ro+radius,co][1]/windowLen
totalB += imgB[ro+radius,co][2]/windowLen
imgC[ro,co] = [totalR,totalG,totalB]
return imgC
# number of times to run blur operation
blurPasses = 3
# temporary image array for multiple passes
imgTmp = imgArr
for k in range(blurPasses):
imgTmp = doblur(imgTmp)
print "pass #",k,"done."
imgOut = Image.fromarray(numpy.uint8(imgTmp))
imgOut.save('testimage-processed.png', 'PNG')
a-b-c
时,我总是感到担忧。我从未记住过任何语言中运算符的结合性,无法确定它是被解释为a-(b-c)
还是(a-b)-c
。 - sarnold10-(5-1) -> 6. (10-5)-1 -> 4.
来吧,试试看。:) 我_曾经_见过一些语言以两种方式解析a-b-c
,所以我总是更喜欢在分组周围加上括号,以防我忘记特定语言的结合规则。 - sarnold