区域生长法:
通俗的讲就是利用初始种子点,通过邻域判断,获取更多的种子点,以达到生长的目的。
有点像是核聚变的链式反应,一个点找到更多的种子点,然后新的种子点再找到更多的,最后生长结束,种子点库也就清空了。
目前主要使用的是四领域和八领域:
四邻域 (左) 和八邻域 (右) 的示意图:
区域生长的流程图:
以下是部分代码(参考:结合python与遥感图像的区域生长算法实现 - 知乎):
class Point(object):
def __init__(self, x, y):
self.x = x
self.y = y
def getX(self):
return self.x
def getY(self):
return self.y
def toString(self):
return '[' + str(self.x) + ',' + str(self.y) + ']'
def selectConnects(p):
if p != 0:
connects = [Point(-1, -1), Point(0, -1), Point(1, -1), Point(1, 0), Point(1, 1),
Point(0, 1), Point(-1, 1), Point(-1, 0)]
else:
connects = [Point(0, -1), Point(1, 0), Point(0, 1), Point(-1, 0)]
return connects
def getGrayDiff(img, currentPoint, tmpPoint):
return abs(int(img[currentPoint.x, currentPoint.y]) - int(img[tmpPoint.x, tmpPoint.y]))
def regionGrow(img, seeds, thresh, p=1):
height, weight = img.shape
seedMark = np.zeros(img.shape)
seedList = []
for seed in seeds:
if seed is not None:
seedList.append(seed)
label1 = 255
connects = selectConnects(p)
while len(seedList) > 0:
currentPoint = seedList.pop(0)
seedMark[currentPoint.y, currentPoint.x] = label1
for i in range(0, 8):
tmpX = currentPoint.x + connects[i].x
tmpY = currentPoint.y + connects[i].y
if tmpX < 0 or tmpY < 0 or tmpX >= height or tmpY >= weight:
continue
grayDiff = getGrayDiff(img, Point(currentPoint.y, currentPoint.x), Point(tmpY, tmpX))
if grayDiff < thresh and seedMark[tmpY, tmpX] == 0:
seedMark[tmpY, tmpX] = label1
seedList.append(Point(tmpX, tmpY))
return seedMark
def on_EVENT_LBUTTONDOWN(event, x, y, flags, param):
global num
if event == cv2.EVENT_LBUTTONDOWN:
if num < 5:
num = num + 1
seeds[num] = Point(x, y)
else:
print("已勾选五个点")
结合以上代码和流程图进行分析:
这是一个灰度值图像的区域生长,通过鼠标左键选取五个种子点,在seeds这个数组中我们传入初始的种子点。假设我们从中拿出一个种子点,将其对应位置设置为白色,以这个种子点作为中心实行八邻域生长。判断周围点的灰度值与它的误差是否小于thresh,如果满足条件我们将这个点加入种子点列表,在种子点列表为空时结束循环。
总结:
写这篇文章的目的主要是记录学习内容,代码部分不知道是不是自己的操作问题,但就运行结果来讲原知乎上代码存在坐标颠倒的问题,坐标(x,y)的 x 与 y 应当对于数组 a[ i , j ] 的 j 和 i ,具体表现为选取左下的点,实际却是以右上对称点进行生长。在这里我进行了修改,所以部分代码显示为x,y部分却是y,x。
后续我会基于这个方法对一些医学图像进行一些切割,来获取深度学习的样本,这里做一些进度的记录和学习内容的笔记。如果有什么想法或是问题,欢迎一起讨论。