Python 区域生长蟒蛇
我正在用python实现区域增长算法。但当我在输出上运行这段代码时,我得到了没有错误的黑色图像。对输入图像使用CV阈值函数,对于种子值,我使用鼠标单击将x、y值存储在元组中Python 区域生长蟒蛇,python,opencv,Python,Opencv,我正在用python实现区域增长算法。但当我在输出上运行这段代码时,我得到了没有错误的黑色图像。对输入图像使用CV阈值函数,对于种子值,我使用鼠标单击将x、y值存储在元组中 def get8n(x, y, shape): out = [] if y-1 > 0 and x-1 > 0: out.append( (y-1, x-1) ) if y-1 > 0 : out.append( (y-1, x)) if y-
def get8n(x, y, shape):
out = []
if y-1 > 0 and x-1 > 0:
out.append( (y-1, x-1) )
if y-1 > 0 :
out.append( (y-1, x))
if y-1 > 0 and x+1 < shape[1]:
out.append( (y-1, x+1))
if x-1 > 0:
out.append( (y, x-1))
if x+1 < shape[1]:
out.append( (y, x+1))
if y+1 < shape[0] and x-1 > 0:
out.append( ( y+1, x-1))
if y+1 < shape[0] :
out.append( (y+1, x))
if y+1 < shape[0] and x+1 < shape[1]:
out.append( (y+1, x+1))
return out
def region_growing(img, seed):
list = []
outimg = np.zeros_like(img)
list.append((seed[0], seed[1]))
while(len(list)):
pix = list[0]
outimg[pix[0], pix[1]] = 255
for coord in get8n(pix[0], pix[1], img.shape):
if img[coord[0], coord[1]] > 0:
outimg[coord[0], coord[1]] = 255
list.append((coord[0], coord[1]))
list.pop(0)
return outimg
def on_mouse(event, x, y, flags, params):
if event == cv2.EVENT_LBUTTONDOWN:
print 'Seed: ' + str(x) + ', ' + str(y)
clicks.append((y,x))
clicks = []
image = cv2.imread('lena.jpg', 0)
ret, img = cv2.threshold(image, 200, 255, cv2.THRESH_BINARY)
cv2.namedWindow('Input')
cv2.setMouseCallback('Input', on_mouse, 0, )
cv2.imshow('Input', img)
cv2.waitKey()
seed = clicks[-1]
cv2.imshow('Region Growing', region_growing(img, seed))
cv2.waitKey()
cv2.destroyAllWindows()
def get8n(x,y,形状):
out=[]
如果y-1>0和x-1>0:
out.append((y-1,x-1))
如果y-1>0:
out.append((y-1,x))
如果y-1>0且x+1<形状[1]:
out.append((y-1,x+1))
如果x-1>0:
out.append((y,x-1))
如果x+1<形状[1]:
out.append((y,x+1))
如果y+1<形状[0]和x-1>0:
out.append((y+1,x-1))
如果y+1<形状[0]:
out.append((y+1,x))
如果y+1<形状[0]和x+1<形状[1]:
out.append((y+1,x+1))
返回
def区域_生长(img,种子):
列表=[]
outimg=np.类零(img)
list.append((种子[0],种子[1]))
while(len(list)):
pix=列表[0]
outimg[pix[0],pix[1]]=255
对于get8n中的坐标(pix[0],pix[1],img.shape):
如果img[coord[0],coord[1]]>0:
outimg[coord[0],coord[1]]=255
list.append((坐标[0],坐标[1]))
list.pop(0)
返回
鼠标上的def(事件、x、y、标志、参数):
如果event==cv2.event\u LBUTTONDOWN:
打印“种子:'+str(x)+','+str(y)
单击。追加((y,x))
点击次数=[]
image=cv2.imread('lena.jpg',0)
ret,img=cv2.threshold(图像,200255,cv2.THRESH_二进制)
cv2.namedWindow(“输入”)
cv2.setMouseCallback('Input',在鼠标上,0,)
cv2.imshow(“输入”,img)
cv2.waitKey()
种子=点击次数[-1]
cv2.imshow(“区域增长”,区域增长(img,种子))
cv2.waitKey()
cv2.destroyAllWindows()
我在使用get8n()函数时遇到了一些问题,所以我重写了它。我相信下面的代码符合您的要求。region_growing()函数中有两行被注释掉了。如果取消注释,它们将显示处理过程中发生的动画。这是一种可视化代码的好方法,可以让您了解失败的地方 另外,在代码中,您可以将已经处理过的像素添加到“待处理”列表中。这导致了一个无限循环。我添加了一个检查,防止已处理的像素被添加回列表中
import cv2
import numpy as np
def get8n(x, y, shape):
out = []
maxx = shape[1]-1
maxy = shape[0]-1
#top left
outx = min(max(x-1,0),maxx)
outy = min(max(y-1,0),maxy)
out.append((outx,outy))
#top center
outx = x
outy = min(max(y-1,0),maxy)
out.append((outx,outy))
#top right
outx = min(max(x+1,0),maxx)
outy = min(max(y-1,0),maxy)
out.append((outx,outy))
#left
outx = min(max(x-1,0),maxx)
outy = y
out.append((outx,outy))
#right
outx = min(max(x+1,0),maxx)
outy = y
out.append((outx,outy))
#bottom left
outx = min(max(x-1,0),maxx)
outy = min(max(y+1,0),maxy)
out.append((outx,outy))
#bottom center
outx = x
outy = min(max(y+1,0),maxy)
out.append((outx,outy))
#bottom right
outx = min(max(x+1,0),maxx)
outy = min(max(y+1,0),maxy)
out.append((outx,outy))
return out
def region_growing(img, seed):
seed_points = []
outimg = np.zeros_like(img)
seed_points.append((seed[0], seed[1]))
processed = []
while(len(seed_points) > 0):
pix = seed_points[0]
outimg[pix[0], pix[1]] = 255
for coord in get8n(pix[0], pix[1], img.shape):
if img[coord[0], coord[1]] != 0:
outimg[coord[0], coord[1]] = 255
if not coord in processed:
seed_points.append(coord)
processed.append(coord)
seed_points.pop(0)
#cv2.imshow("progress",outimg)
#cv2.waitKey(1)
return outimg
def on_mouse(event, x, y, flags, params):
if event == cv2.EVENT_LBUTTONDOWN:
print 'Seed: ' + str(x) + ', ' + str(y), img[y,x]
clicks.append((y,x))
clicks = []
image = cv2.imread('lena.bmp', 0)
ret, img = cv2.threshold(image, 128, 255, cv2.THRESH_BINARY)
cv2.namedWindow('Input')
cv2.setMouseCallback('Input', on_mouse, 0, )
cv2.imshow('Input', img)
cv2.waitKey()
seed = clicks[-1]
out = region_growing(img, seed)
cv2.imshow('Region Growing', out)
cv2.waitKey()
cv2.destroyAllWindows()
以下是单击她帽子左侧时的结果:
Add()用于Python3.x like:print(“Some things”)上述解决方案在概念上是正确的,但从数值角度来看,它们包含一些严重的问题,使它们在像素数量上的顺序为N^2。如果可以将信息存储在提供随机访问的数组中,则无需搜索列表中的像素,还可以对连接功能进行cythonized。另外,如果能够提供您自己的相似性函数也会很好 因此,我建议在Jupyter noteboook中运行一个改进的、肯定更快的版本: 导入的第一个单元格:
import numpy as np
import cv2
%pylab inline
%load_ext Cython
第二个单元格(不合并第一个单元格):
可以使用与前面相同的逻辑从另一个单元调用它:
def on_mouse(event, x, y, flags, params):
if event == cv2.EVENT_LBUTTONDOWN:
print( 'Seed: ' + str(x) + ', ' + str(y), img[y,x])
clicks.append((int(y), int(x)))
clicks = []
image = cv2.imread('lena.bmp', 0)
ret, img = cv2.threshold(image, 128, 255, cv2.THRESH_BINARY)
cv2.namedWindow('Input')
cv2.setMouseCallback('Input', on_mouse, 0, )
cv2.imshow('Input', img)
cv2.waitKey()
cv2.destroyAllWindows()
seed = clicks
out = region_growing(img, seed)
cv2.imshow('Region Growing', out)
cv2.waitKey()
cv2.destroyAllWindows()
有一些小的功能差异。输出中的区域由种子处原始图像的值或可选颜色贴图中的值标记。colormap需要指定给定als无符号8位整数的RGB颜色。也可以通过定制的测试功能,替换:
test = lambda seed_x, seed_y, x, y, img, outimg : img[x,y] != 0
例如:
test = lambda seed_x, seed_y, x, y, img, outimg : abs(img[x,y] - img[seed_x, seed_y]) < 4
由于您询问的是读取和显示图像的问题,您能否包括读取/操作输入图像和显示输出图像的代码?在鼠标上有输入图像
def的所有代码(事件、x、y、标志、参数):如果event==cv2.event\u LBUTTONDOWN:print'Seed:'+str(x)+','+str y)clicks.append((y,x))点击=[]图像=cv2.imread('lenna.jpg',0)ret,img=cv2.threshold(图像,200255,cv2.THRESH_BINARY)cv2.namedWindow('Input')cv2.setMouseCallback('Input',on_mouse,0,)cv2.imshow('Input',img)cv2.waitKey()seed=点击[-1]cv2.imshow('Region growth',Region_growth(img,seed))cv2.waitKey()
通过正确的格式将代码添加到问题中-这是不可读的。您希望您的代码做什么?现在,它似乎在您上次单击的位置绘制了一个带有白色像素的空白图像。如果您单击输入的白色区域,它将进入无限循环。另一方面,这意味着输出图像不是b缺少,但只有一个白色像素。我想通过种子像素的所有相邻像素(单击)将值大于0的像素设置为255。如果相邻像素大于0,则继续此操作。并将它们指定给将作为输出图像的区域谢谢您的帮助。我复制了您编写的代码,得到了与上面相同的结果,在单击的位置有白色像素。您可以显示您的输出结果吗?可能我做错了。添加了一个结果图像。如果您仍然有问题,我建议您在种子位置打印图像值,以确保您没有混淆x和y坐标。这些结果来自我发布的确切代码。为什么“img[coord[0],coord[1]!=0”包含或其功能是什么?或者为什么像素不能为黑色?区域生长函数在已设置阈值的图像上运行,这意味着值为0或255。因此,如果img[coord[0],coord[1]==255,则该行可能为。如果img[coord[0],coord[1]==255,则为>0
。只是检查像素是否为黑色,因为这是本例中的边界条件。我认为最好不要为候选种子点列表重载内置的list
函数。我将建议进行编辑
test = lambda seed_x, seed_y, x, y, img, outimg : img[x,y] != 0
test = lambda seed_x, seed_y, x, y, img, outimg : abs(img[x,y] - img[seed_x, seed_y]) < 4
def get_8_connected(x, y, shape):
xmax = shape[0]-1
ymax = shape[1]-1
connected_pixels = list()
for dx in range(3):
for dy in range(3):
connected_pixel_x = x + dx - 1
connected_pixel_y = y + dy - 1
if connected_pixel_x < 0 or connected_pixel_x > xmax or \
connected_pixel_y < 0 or connected_pixel_y > ymax or \
(connected_pixel_x == x and connected_pixel_y == y):
pass
else:
connected_pixels.append((connected_pixel_x,connected_pixel_y))
return connected_pixels```