什么';这个python图像模糊函数有什么问题?

什么';这个python图像模糊函数有什么问题?,python,image-processing,blur,gaussian,Python,Image Processing,Blur,Gaussian,编辑:多亏了Howard,我已经更正了这里的代码,现在似乎可以正常工作了 EDIT2:我已更新代码,使其包含最初预期的垂直模糊。具有各种设置的结果示例输出: 模糊操作的另一个参考(Java): 原职: 我试图学习基本的图像处理,并在python中复制这个简单的函数(“重用结果”下的第二个函数)。我知道在PIL中已经有了模糊功能,但我想自己尝试一下基本的像素操作 此函数应获取源图像,然后根据特定半径平均RGB像素值,并将处理后的图像写入新文件。我的问题是,我得到了很多像素的平均值完全错误(例如,

编辑:多亏了Howard,我已经更正了这里的代码,现在似乎可以正常工作了

EDIT2:我已更新代码,使其包含最初预期的垂直模糊。具有各种设置的结果示例输出:

模糊操作的另一个参考(Java):


原职:

我试图学习基本的图像处理,并在python中复制这个简单的函数(“重用结果”下的第二个函数)。我知道在PIL中已经有了模糊功能,但我想自己尝试一下基本的像素操作

此函数应获取源图像,然后根据特定半径平均RGB像素值,并将处理后的图像写入新文件。我的问题是,我得到了很多像素的平均值完全错误(例如,在某些区域,亮绿线而不是红色)

模糊半径为2时,平均法将以输入像素为中心的5个像素的RGB值相加。它使用一个“滑动窗口”来保持一个运行总数,减去输出像素(左侧)并添加新的输入像素(窗口右侧)

样本:

知道我哪里出错了吗?我不知道为什么图像的某些部分会清晰地模糊,而其他区域则充满了与周围区域完全无关的颜色

谢谢你的帮助

固定工作代码(谢谢Howard)

导入图像、numpy、图像过滤器
img=Image.open('testimage.jpg')
imgArr=numpy.asarray(img)#只读
#模糊半径(像素)
半径=2
#模糊窗口长度(像素)
窗长=半径*2+1
#列(x)以像素为单位的图像宽度
imgWidth=imgArr.shape[1]
#行(y)图像高度(像素)
imgHeight=imgArr.shape[0]
#简单框/窗口模糊
def doblur(imgArr):
#基于输入图像尺寸为已处理图像创建数组
imgB=numpy.zero((imgHeight,imgWidth,3),numpy.uint8)
imgC=numpy.zero((imgHeight,imgWidth,3),numpy.uint8)
#一行一行地模糊水平线
对于范围内的ro(仪表灯):
#RGB颜色值
totalR=0
总g=0
totalB=0
#计算每行第一个像素的模糊值
对于范围内的雷达(-radius,radius+1):
如果(rads)>=0且(rads)=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
如果(co+半径)=0且(rads)=0:
totalR-=imgB[ro-radius-1,co][0]/windowLen
总G-=imgB[ro-radius-1,co][1]/windowLen
totalB-=imgB[ro-radius-1,co][2]/windowLen

如果(ro+radius)我想你的线路有问题

for rads in range(-radius, radius):
仅延伸至半径-1(范围不包括最后一个)。在第二个范围参数中添加一个

更新:线路中还有一个小isue

if (co-radius-1) > 0:
应该是哪一个

if (co-radius-1) >= 0:

我只是对你的代码做了一点修改/重构,我想和大家分享一下。我需要做一些自定义模糊处理:1)处理数据数组,2)仅水平缠绕,而不是垂直缠绕。正如TODO所指出的,我正在考虑进一步重构,这样它就可以进行部分像素混合(即0.5)。希望这对某人有所帮助:

def blur_image(image_data, blur_horizontal=True, blur_vertical=True, height=256, width=256, radius=1):
    #TODO: Modify to support partial pixel blending

    # blur window length in pixels
    blur_window = radius*2+1

    out_image_data = image_data

    # blur horizontal row by row, and wrap around edges
    if blur_horizontal:
        for row in range(height):
            for column in range(0, width):
                total_red = 0
                total_green = 0
                total_blue = 0

                for rads in range(-radius, radius+1):
                    pixel = (row*width) + ((column+rads) % width)
                    total_red += image_data[pixel][0]/blur_window
                    total_green += image_data[pixel][1]/blur_window
                    total_blue += image_data[pixel][2]/blur_window

                out_image_data[row*width + column] = (total_red, total_green, total_blue, 255)
        image_data = out_image_data

    # blur vertical, but no wrapping
    if blur_vertical:
        for column in range(width):
            for row in range(0, height):
                total_red = 0
                total_green = 0
                total_blue = 0

                blur_window = 0
                for rads in range(-radius, radius+1):
                    if rads in range(0, height):
                        blur_window += 1

                for rads in range(-radius, radius+1):
                    row_mod = row+rads
                    if row_mod in range(0, height):
                        pixel = (row_mod*width) + column
                        total_red += image_data[pixel][0]/blur_window
                        total_green += image_data[pixel][1]/blur_window
                        total_blue += image_data[pixel][2]/blur_window

                out_image_data[row*width + column] = (total_red, total_green, total_blue, 255)
        image_data = out_image_data

    return image_data
当您已经获得RGBA像素阵列中的图像时,可以使用它,然后运行:

image_data = blur_image(image_data, height=height, width=width, radius=2)

im = Image.new('RGB', (width, height))
im.putdata(image_data)

你能发布一些输入/输出示例吗?当我看到
a-b-c
时,我总是很担心。在任何语言中,我都记不清运算符的关联性,因此不知道在我使用过的每种语言中,它是被解释为
a-(b-c)
还是
(a-b)-c
,加法、减法、乘法和除法是从左到右关联的,就像在数学中一样。求幂运算是唯一常见的从右向左的运算。示例:只是好奇:它快吗?有一种方法可以用一些简单的技巧以更有效的方式重写“for r in rows:for c in columns:…”循环?我认为python代码应该避免计算速度问题的长for循环。谢谢所有的评论。我尝试了霍华德的建议,并改为以下行:
适用于射程内的雷达(-radius,radius+1)
:但我肯定还有其他问题。这是一个示例图像,显示图像前后。第二个图像是由我的原始代码处理的。第三幅图像是在霍华德做了改动后处理的@moski还有一个小问题:if(co-radius-1)>0:应该是if(co-radius-1)>=0。非常感谢!我认为这两个改变已经纠正了我的错误。我倾向于忽略所有的小事情,>对>=和+1,-1来解释从0对1开始的计数。谢谢你的第二双眼睛。我将尝试一些不同的图片,而不是发布更新。再次感谢。我测试了多个图像,它们都按预期进行了处理。为了完成完全模糊,我添加了一个垂直窗口模糊计算。仅水平、水平+垂直、不同半径和多次通过的示例图像:@moski,“我倾向于错过所有的小事情”,你会惊讶于有多少安全漏洞正是这个小问题……)干得好,霍华德,接得好。
image_data = blur_image(image_data, height=height, width=width, radius=2)

im = Image.new('RGB', (width, height))
im.putdata(image_data)