建网站怎么弄,网站开发费如何入账,浙江省网站备案时间,linux服务器怎么做网站OpenCV与图像处理学习十——区域生长算法#xff08;含代码#xff09;一、区域生长算法概要二、区域生长算法原理三、代码应用一、区域生长算法概要
区域生长是一种串行区域分割的图像分割方法。区域生长是指从某个像素出发#xff0c;按照一定的准则#xff0c;逐步加入…
OpenCV与图像处理学习十——区域生长算法含代码一、区域生长算法概要二、区域生长算法原理三、代码应用一、区域生长算法概要
区域生长是一种串行区域分割的图像分割方法。区域生长是指从某个像素出发按照一定的准则逐步加入邻近像素当满足一定的条件时区域生长终止。
区域生长的好坏决定于
初始点种子点的选取。生长准则。终止条件。
区域生长是从某个或者某些像素点出发最后得到整个区域进而实现目标的提取。
二、区域生长算法原理
基本思想将具有相似性质的像素集合起来构成区域。
步骤
对图像顺序扫描找到第1个还没有归属的像素, 设该像素为(x0, y0);以(x0, y0)为中心, 考虑(x0, y0)的4邻域像素(x, y)如果(x0,y0)满足生长准则, 将(x, y)与(x0, y0)合并(在同一区域内), 同时将(x, y)压入堆栈即满足条件被判定为和(x0, y0)属于一个区域后面需要再从这些点往外继续生长所以需要保存从堆栈中取出一个像素, 把它当作(x0, y0)返回到步骤2继续往外生长当堆栈为空时返回到步骤1有像素可能不属于前面的区域重复步骤1 - 4直到图像中的每个点都有归属时生长结束。
三、代码应用
这里为简单起见我们只设置了一个区域即上述步骤中的第四步改为当堆栈为空时生长结束。
我们需要分割的图像如下所示 我们将生长准则设置为像素值之间的欧式距离小于某个阈值也就是说相邻像素值的差异较小时归类为一个区域代码如下所示
# -*- coding:utf-8 -*-
import cv2
import numpy as np
###########################################################################################################################################################################
class Point(object):def __init__(self, x, y):self.x xself.y ydef getX(self):return self.xdef 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
im cv2.imread(./image/222.jpg)
cv2.imshow(src, im)
cv2.waitKey(0)
cv2.destroyAllWindows()
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)
cv2.waitKey(0)
cv2.destroyAllWindows()# 建立空的图像数组,作为一类
img_re im.copy()
for i in range(height):for j in range(width):img_re[i, j][0] 0img_re[i, j][1] 0img_re[i, j][2] 0
cv2.imshow(img_re, img_re)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 取一点作为种子点
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].xtmpY seed_tmp.y connects[i].yif (tmpX 0 or tmpY 0 or tmpX height or tmpY width):continuedist 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_kseed_list.append(Point(tmpX, tmpY))########################################################################################
# 输出图像
cv2.imshow(OUTIMAGE, img_re)
cv2.waitKey(0)
cv2.destroyAllWindows()分割得到的结果如下所示 很显然天空的像素值较为接近所以被生长为一片区域而房屋的像素与天空的差异较大当天空的区域生长结束之后因为这里只设置了分割一块区域所以下面的房屋部分没有遍历到。