Regional_growth

本文介绍了一个基于C/C++实现的连通域增长算法,该算法用于图像处理中的连通区域检测。通过指定起始点及连通域的颜色,算法能够识别并标记出与起始点颜色相同的连通区域。
int Move_detect::Regional_growth(IplImage* src,CvPoint start,int region_color,int change_color)//函数功能:对于二值图像src求连通阈
{
 uchar* srcdata=(uchar*)src->imageData;
 //8领域
 int Region8_x[]={-1,0,1,1,1,0,-1,-1};
 int Region8_y[]={-1,-1,-1,0,1,1,1,0};
 //4邻域
 //int Region8_x[]={0,1,0,-1};
 //int Region8_y[]={-1,0,1,0};
 long int temp1=0,temp2=0;
 int x,y;
 if (srcdata[start.y*src->widthStep+start.x]!=region_color)
 {
  return 0;
 }
 else
 {
  Region_x[temp2]=start.x;
  Region_y[temp2]=start.y;
  temp2++;
 }
 while(temp1<=(temp2-1)&&temp1<5600000&&temp2<=5600000)
 {
   //printf("temp1:%d\n",temp1);
   //printf("temp2:%d\n",temp2);
  for (int i=0;i<8;i++)
  {
   //Region_x和Region_y里存放连通域占集的坐标
   x=Region8_x[i]+Region_x[temp1];
   y=Region8_y[i]+Region_y[temp1];
   if (x>=0&&x<src->width&&y>=0&&y<src->height)
   {
    if (srcdata[y*src->widthStep+x]==region_color)
    {
     srcdata[y*src->widthStep+x]=change_color;
     Region_x[temp2]=x;
     Region_y[temp2]=y;
     temp2++;
    }
   }
  }
  temp1++;
 }
 return temp1;
}
import cv2 as cv import numpy as np import matplotlib.pyplot as plt from collections import deque ##########begin########## # 计算种子点和其领域的像素值之差 def getGrayDiff(gray, current_seed, tmp_seed): return abs(int( # 区域生长算法 def regional_growth(gray, seeds): # 八领域 connects = [(-1, -1), (0, -1), (1, -1), (1, 0), \ (1, 1), (0, 1), (-1, 1), (-1, 0)] seedMark = np.zeros((gray.shape)) height, width = gray.shape threshold = 6 seedque = deque() label = 255 seedque.extend(seeds) while seedque: # 队列具有先进先出的性质。所以要左删 current_seed = seedMark[ for i in range(8): tmpX = tmpY = # 处理边界情况 if continue grayDiff = getGrayDiff( if grayDiff < and = label: seedque. seedMark[ return seedMark ##########end########## def Region_Grow(img,seed): for i in seed: # 在图像上画出实心点位 cv.circle(img, center=(i[-1],i[0]), radius=5,color=(0, 0, 255), thickness=-1) # 进行区域生长分割 astronaut = cv.imread('imgs/astronaut.png', 1) seedMark = np.uint8(regional_growth(cv.cvtColor(astronaut, cv.COLOR_BGR2GRAY), seed)) # 绘制并保存 plt.figure(figsize=(16, 6)) plt.subplot(131), plt.imshow(cv.cvtColor(astronaut, cv.COLOR_BGR2RGB)) plt.axis('off'), plt.title(f'$input\_image$') plt.subplot(132), plt.imshow(cv.cvtColor(img, cv.COLOR_BGR2RGB)) plt.axis('off'), plt.title(f'$seeds\_image$') plt.subplot(133), plt.imshow(seedMark, cmap='gray', vmin=0, vmax=255) plt.axis('off'), plt.title(f'$segmented\_image$') plt.savefig('img_user/astronaut.png')任务描述 本关任务:学习并完成基于区域生长的图像分割算法。 相关知识 为了完成本关任务,你需要掌握:1.区域生长算法,2.如何实现区域生长算法。 区域生长算法 区域生长算法是一种基于像素相似性的图像分割算法,旨在将图像中相似的像素点组合成连通的区域。该算法从一个或多个种子点开始,逐步生长扩展,将与种子点相似的像素点归为同一个区域。 以下是区域生长算法的基本步骤: 选择种子点:从图像中选择一个或多个像素点作为种子点。通常情况下,种子点是根据特定的准则或用户交互选择的。 定义相似性准则:确定像素点之间的相似性度量标准。这通常是基于像素的灰度值、颜色值、纹理特征等。 定义生长准则:确定像素生长的条件。这个条件通常是基于像素之间的相似性度量和阈值。例如,当两个像素的相似性大于阈值时,它们被认为是同一个区域的一部分。 初始化标记图像:创建一个与原始图像大小相同的标记图像,用于记录每个像素点所属的区域。 开始生长扩展:从种子点开始,逐步扩展区域生长。一般情况下,使用队列或栈数据结构来管理待生长的像素点。 扩展过程:对于当前的生长像素点,根据生长准则和相似性度量,将其与相邻像素点进行比较。如果相邻像素点与当前像素点相似且尚未标记,则将其标记为同一区域,并加入待生长队列或栈中。 继续生长:重复步骤6,直到没有更多的待生长像素点。 输出结果:最终得到标记图像,每个像素点被分配一个唯一的标签,表示其所属的区域。 区域生长算法的优点是简单且易于实现,对于具有均匀纹理、明显边界或明显对比度的图像分割效果较好。然而,该算法对于光照变化、噪声或复杂背景的图像可能会产生较差的分割结果。因此,在实际应用中,可能需要结合其他算法或改进区域生长算法以适应不同的图像场景。 如何实现区域生长算法 区域生长的基本思想是将具有相似性质的像素集合起来构成区域。具体先对每个需要分割的区域找一个种子像素作为生长的起点,然后将种子像素周围邻域中与种子像素具有相同或相似性质的像素(根据某种事先确定的生长或相似准则来判定)合并到种子像素所在的区域中。将这些新像素当做新的种子像素继续进行上面的过程,直到再没有满足条件的像素可被包括进来,这样,一个区域就长成了。   区域生长的算法实现: 根据图像的不同应用选择一个或一组种子,它或者是最亮或最暗的点,或者是位于点簇中心的点,当然也可以手动选择种子点。 选择一个描述符(条件),常见的有基于区域灰度差、基于区域灰度分布统计性质。 从该种子开始向外扩张,首先把种子像素加入结果集合,然后不断将与集合中各个像素连通、且满足描述符的像素加入集合。 上一过程进行到不再有满足条件的新结点加入集合为止。 实现案例 # 计算种子点和其领域的像素值之差 def getGrayDiff(gray, current_seed, tmp_seed): return abs(int(gray[current_seed[0], current_seed[1]]) - int(gray[tmp_seed[0], tmp_seed[1]])) # 区域生长算法 def regional_growth(gray, seeds): # 八领域 connects = [(-1, -1), (0, -1), (1, -1), (1, 0), \ (1, 1), (0, 1), (-1, 1), (-1, 0)] seedMark = np.zeros((gray.shape)) height, width = gray.shape threshold = 6 seedque = deque() label = 255 seedque.extend(seeds) while seedque: # 队列具有先进先出的性质。所以要左删 current_seed = seedque.popleft() seedMark[current_seed[0], current_seed[1]] = label for i in range(8): tmpX = current_seed[0] + connects[i][0] tmpY = current_seed[1] + connects[i][1] # 处理边界情况 if tmpX < 0 or tmpY < 0 or tmpX >= height or tmpY >= width: continue grayDiff = getGrayDiff(gray, current_seed, (tmpX, tmpY)) if grayDiff < threshold and seedMark[tmpX, tmpY] != label: seedque.append((tmpX, tmpY)) seedMark[tmpX, tmpY] = label return seedMark getGrayDiff(gray, current_seed, tmp_seed): 这个函数用于计算当前种子点和其领域像素点之间的灰度值差异。它接收三个参数:gray 表示灰度图像,current_seed 表示当前种子点的坐标,tmp_seed 表示待比较的邻域像素点的坐标。函数内部通过索引访问灰度图像的对应像素值,并计算其差的绝对值。最后返回两个像素值之间的差异。 regional_growth(gray, seeds): 这个函数实现了区域生长算法。它接受以下参数: gray: 灰度图像,表示待处理的图像。 seeds: 种子点的坐标列表。 函数首先定义了八领域的连接关系,即每个像素点周围八个相邻像素的相对位置。然后,它创建一个与原始图像大小相同的标记图像 seedMark,用于记录每个像素点所属的区域。 接下来,函数初始化了一些变量,包括图像的高度和宽度、生长阈值、种子点队列等。然后,它开始对种子点进行生长扩展。 在生长过程中,函数使用队列 seedque 来管理待处理的像素点。它从队列中取出当前的种子点,将其标记为指定的标签,并遍历种子点的八个相邻像素。对于每个相邻像素,函数检查其是否满足生长条件:灰度差异小于阈值,并且未被标记为已处理。如果满足条件,邻域像素将被添加到队列中,并被标记为同一区域。 该过程重复进行,直到队列中没有更多待处理的像素点。最终,函数返回标记图像 seedMark,其中每个像素点被赋予一个唯一的标签,表示其所属的区域。 这两个函数共同实现了区域生长算法的关键步骤:计算像素差异并扩展区域生长。通过调用这两个函数,可以对图像进行区域生长分割,并得到分割后的结果。 编程要求 根据提示,补充代码,实现图像分割&mdash;&mdash;区域生长法。
最新发布
11-08
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhang11wu4

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值