从第一原理简单"模糊"表示python中图像的数组



我有一个图像,它由两个任意放置的1px黑色"斑点"组成,位于100px乘200px的白色画布上。我正试图通过将一些相邻像素(每个斑点的半径为10px)变黑来"模糊这些斑点"。我已经整理了以下代码,但不太确定下一步该怎么做。

import numpy as np
from PIL import Image 
from scipy import ndimage
from matplotlib import pyplot
from matplotlib import cm
from scipy.misc import imsave
im = Image.open("test.png")
pix = np.asarray(im)
new_pix = np.copy(pix[:,:,0]) # need this otherwise can't write to the pix array.
pix_to_enlarge = np.where(new_pix != 255)
pixels_to_enlarge_by = 10
i=0
for each_pixel in pix_to_enlarge[0]: # this cycles through each non-white pixel
    for y in range(len(new_pix)): # this looks across the length (down) the page
        for x in new_pix[y]: # this looks across the x-axis for each y step
            radius = pixels_to_enlarge_by**2

所以基本上我已经在变量pixels_to_enlarge_by中找到了非白色像素的位置。我正在尝试(但到目前为止没有成功)选择周围的像素(在10px以内),并将其更改为黑色。有什么想法吗?

以这样或那样的方式,您需要查看每个像素,然后计算出您希望将多少内容分配给图片中的每个像素,例如通过比较两者之间的距离。

以下是使用numpy的方法。如果你想手动完成,那么在任何情况下,这都可能是一个起点。它被称为卷积。使用python和numpy 的二维卷积

关于高斯模糊,这里有一个很好的起点:http://en.wikipedia.org/wiki/Gaussian_blur

但是,如果你只想产生开/关模糊效果,那么与(卷积核)卷积的函数只是关于源点和任何可能的相邻像素之间距离的if语句。当然,对于这种情况有一些优化:循环不需要为所有像素跨越所有像素,只需要使大小为R的圆适合所考虑的范围即可。

既然你想要第一原理,就在这里。它只适用于rgb黑白

from PIL import Image 
im = Image.open("cat2.png")
px=im.load()
im2 = im.copy()
px2=im2.load()
sx,sy=im.size
def turnpixel(Nix,Niy):
    for ix in range(sx):
        for iy in range(sy):
            r2=(Nix-ix)**2+(Niy-iy)**2
            if r2<5:
                if sum(px[ix,iy])>100: # rgb sum>100 is considered ON.
                    px2[Nix,Niy]=(255,255,255)                            
                    return
                    # we turned a pixel on, so we are done with it.
for Nix in range(sx):
    for Niy in range(sy):
        px2[Nix,Niy]=(0,0,0)
        turnpixel(Nix,Niy)
im.show()
im2.show()

如果你想要一个平滑是距离的函数,使用之类的东西

import math
def turnpixel(Nix,Niy):
    for ix in range(sx):
        for iy in range(sy):
            r=int(math.sqrt((Nix-ix)**2+(Niy-iy)**2))
            def convfunc(o,v):
                return o+int(v/(r*20+1))
            px2[Nix,Niy]=tuple(map(convfunc,px2[Nix,Niy],px[ix,iy]))
            if sum(px2[Nix,Niy])>=3*250:
                return

显然,如果你做这样的事情,你应该对浮点运算,而不是整数并使用numpy或一些图像处理模块。

高斯模糊将是(在上面的函数内)。现在整数是一个非常糟糕的主意btw:

        inv2sigma2=1.0/(2*3)
        r2=(Nix-ix)**2+(Niy-iy)**2
        fact=inv2sigma2/(math.pi)*math.exp(-r2*inv2sigma2)
        def convfunc(o,v):
            return o+int(v*fact)

实现这一点的标准方法是使用卷积。如果你想要全黑和全白,你需要在做卷积后应用一个阈值。

相关内容

  • 没有找到相关文章

最新更新