我的图像由两个任意放置的黑色1px“斑点”组成,在白色画布上100px乘200px。我试图通过将一些相邻像素(每个blob的半径10px内)转为黑色来模糊这些斑点。我已经将以下代码放在一起,但我不确定下一步.. < / p>
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内)并将它们也改为黑色。有什么想法吗?
答案 0 :(得分:5)
在某种方式中,您需要查看每个像素,然后确定要将多少内容分发到图片中的每个其他像素,例如通过比较两者之间的距离。
以下是numpy的完成方式。如果你想手动完成,那么在任何情况下都可以作为起点。它被称为卷积。 2d convolution using python and 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)
答案 1 :(得分:3)
执行此操作的标准方法是使用convolution。如果你想要所有黑色和白色,你需要在进行卷积后应用一个阈值。