Advertisement

图像分割 - 区域生长

阅读量:

目录

1. 介绍

2. 代码详解

3. 代码


1. 介绍

分割的目的是将图像分为多个区域

常见的图像分割技术主要建立在以下两个关键特性上:一是图像区域间的灰度不连续性(如Canny边缘检测等方法),二是同一区域内部的灰度一致性(如阈值法和区域生长法等)。

区域生长主要建立在统一区域内像素灰度特性的一致性基础之上,并遵循预先定义的增长准则逐步发展出更大的区域范围。具体来说, 该方法的核心在于将预设的像素点作为种子, 通过与周围像素进行比较分析, 满足灰度相似性条件(即灰度值差异较小)的新像素加入新的种子集合中, 从而扩展区域范围。

区域生长的步骤为:

1. 先定义一组种子

2. 识别每个种子周围的八个相邻像素区域,并对这些区域进行亮度评估;若发现有亮度接近的新区域,则将其划分作独立的新种子

3. 循环这个过程,直到种子全部遍历完

2. 代码详解

这里不同的地方在于传入的种子是一副图像。

对给定的图像执行二值化转换后,我们确定该二值化的图像数据输入到seeds变量中。接着利用np.where函数筛选出seeds中大于零的元素坐标,并将这些坐标存储于seed_list变量中作为最终的种子列表输出。

循环停止的条件是种子列表里面没有种子。

将每一个种子取出,然后将对应的位置作为区域分割的结果 dst[x,y] = 255 。

根据之前定义的connects 周围8个点的相对位置偏差,找到周围的 8邻域

如果 8邻域不在图像上的话,就跳过这次判断

在图像处理中进行操作时,请先对灰度值进行对比检查;同时需确定该区域是否已被处理过以避免无限循环。

假设存在两个相邻点AB,在A被选为初始种子的情况下(即称为源点),B位于A的领域范围内满足相似性条件,则会将B点加入到种子列表中进行后续处理(即标记为待扩展单元)。在检查B点时(即判断其领域),由于已经确定了其领域中的源点A已经完成扩展操作(即成为区域生长后的区域),因此该源点不会再次被选作新的待扩展单元。

如果都满足的话,保存到种子列表里面

3. 代码

复制代码
 import cv2

    
 import numpy as np
    
  
    
  
    
 # 区域生长算法
    
 def regional_growth(image, seeds, thresh=5):            # 这里的seeds是一副图像
    
     height, weight = image.shape[0], image.shape[1]     # 图像的 height和 width
    
     dst= np.zeros(image.shape, dtype=np.uint8)          # 处理的结果
    
     seed_list = []                                      # 种子列表
    
  
    
     x,y = np.where(seeds > 0)                           # 找到种子seeds里面的种子
    
     for i in range(len(x)):
    
     seed_list.append((x[i],y[i]))
    
  
    
     connects = [(-1, -1), (0, -1), (1, -1), (1, 0), (1, 1), (0, 1), (-1, 1), (-1, 0)]  # 8 邻域
    
  
    
     while len(seed_list) > 0:                           # 判断种子受否剩余
    
  
    
     point = seed_list.pop(0)                        # 取出第一个
    
     x, y = point[0],point[1]
    
     dst[x, y] = 255                                 # 将对应位置的点标记为 255
    
  
    
     for i in range(8):                              # 对种子周围的 8个点一次进行相似性判断
    
         connects_tmp = connects[i]                      # 8 邻域
    
         x_tmp= x+ connects_tmp[0]
    
         y_tmp= y+ connects_tmp[1]
    
  
    
         if (x_tmp < 0) or (y_tmp < 0) or (x_tmp >= height) or (y_tmp >= weight):  # 是否超出限定阈值
    
             continue
    
  
    
         gray_diff = np.abs(int(image[x, y]) - int(image[x_tmp, y_tmp]))     # 判断相似性
    
  
    
         if (gray_diff <= thresh) and (dst[x_tmp, y_tmp] == 0):              # 相似的话储存为新的种子
    
             dst[x_tmp,y_tmp] = 255
    
             seed_list.append((x_tmp,y_tmp))
    
     return dst
    
  
    
  
    
 # 区域生长 主程序
    
 img = cv2.imread("./img.tif", flags=0)
    
  
    
 _, img_bin = cv2.threshold(img, 254, 255, cv2.THRESH_BINARY)  # 阈值处理产生种子区域
    
 dst = regional_growth(img, img_bin)
    
 cv2.imshow('img', np.hstack((img,dst)))
    
  
    
 cv2.waitKey()
    
 cv2.destroyAllWindows()

处理结果:

这里阈值产生的种子图像为:

全部评论 (0)

还没有任何评论哟~