# Opencv之区域生长和分裂

### 区域生长

#### 1.基本原理

（1）一个合适的像素或者小区域作为开始的生长点
（2）生长准则，也就是通过什么标准你才能拉他入伙
（3）停止生长的条件 什么时候停止扩充

#### 3.代码

``````import cv2
import numpy as np

####################################################################################

#######################################################################################
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

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)
]

#####################################################################################
# 计算两个点间的欧式距离
def get_dist(seed_location1, seed_location2):
l1 = im[seed_location1.x, seed_location1.y]
l2 = im[seed_location2.x, seed_location2.y]
count = np.sqrt(np.sum(np.square(l1 - l2)))
return count

# import Image
cv2.imshow('src', im)
im_shape = im.shape
height = im_shape[0]
width = im_shape[1]

print('the shape of image :', im_shape)

# 标记，判断种子是否已经生长
img_mark = np.zeros([height, width])
cv2.imshow('img_mark', img_mark)

# 建立空的图像数组,作为一类
img_re = im.copy()
for i in range(height):
for j in range(width):
img_re[i, j][0] = 0
img_re[i, j][1] = 0
img_re[i, j][2] = 0
cv2.imshow('img_re', img_re)

# 取一点作为种子点
seed_list = []
seed_list.append(Point(15, 15))
T = 7  # 阈值
class_k = 1  # 类别
# 生长一个类
while (len(seed_list) > 0):
seed_tmp = seed_list[0]
# 将以生长的点从一个类的种子点列表中删除
seed_list.pop(0)

img_mark[seed_tmp.x, seed_tmp.y] = class_k

# 遍历8邻域
for i in range(8):
tmpX = seed_tmp.x + connects[i].x
tmpY = seed_tmp.y + connects[i].y

if (tmpX < 0 or tmpY < 0 or tmpX >= height or tmpY >= width):
continue
dist = get_dist(seed_tmp, Point(tmpX, tmpY))
# 在种子集合中满足条件的点进行生长
if (dist < T and img_mark[tmpX, tmpY] == 0):
img_re[tmpX, tmpY][0] = im[tmpX, tmpY][0]
img_re[tmpX, tmpY][1] = im[tmpX, tmpY][1]
img_re[tmpX, tmpY][2] = im[tmpX, tmpY][2]
img_mark[tmpX, tmpY] = class_k
seed_list.append(Point(tmpX, tmpY))

########################################################################################
# 输出图像
cv2.imshow('OUTIMAGE', img_re)
cv2.waitKey(0)
``````

区域生长法的优点是计算简单，对于较均匀的连通目标有较好的分割效果。

### 区域分裂和聚合

#### 代码

``````import cv2 as cv
import numpy as np

class region_div:

def __init__(self, img):
self.img = img
self.res = np.zeros(img.shape)

def region_div_group(self, range1, range2):
if range1[1] - range1[0] == 0 or range2[1] - range2[0] == 0:
return

mean = self.img[range1[0]:range1[1], range2[0]:range2[1]].mean()
var = self.img[range1[0]:range1[1], range2[0]:range2[1]].var()
# print(self.img[range1[0]:range1[1],range2[0]:range2[1]])
# print(range1, range2, var)
if var < 10:
self.res[range1[0]:range1[1], range2[0]:range2[1]] = 255
else:
if range1[1] - range1[0] >= 2 and range2[1] - range2[0] >= 2:
self.region_div_group(
[range1[0], (range1[0] + range1[1]) // 2],
[range2[0], (range2[0] + range2[1]) // 2])
self.region_div_group(
[(range1[0] + range1[1]) // 2, range1[1]],
[range2[0], (range2[0] + range2[1]) // 2])
self.region_div_group(
[range1[0], (range1[0] + range1[1]) // 2],
[(range2[0] + range2[1]) // 2, range2[1]])
self.region_div_group(
[(range1[0] + range1[1]) // 2, range1[1]],
[(range2[0] + range2[1]) // 2, range2[1]])

gray = cv.cvtColor(image, cv.COLOR_RGB2GRAY)
# print(gray.shape)
# print(gray[0:1, 5:11])
res = np.zeros(gray.shape)
rd = region_div(gray)
rd.region_div_group([0, gray.shape[0]], [0, gray.shape[1]])

res = rd.res
cv.namedWindow("gray")
cv.imshow("gray", gray)
cv.waitKey(0)

cv.namedWindow("res")
cv.imshow("res", res)
cv.waitKey(0)
``````

THE END