图像分割_区域生长

2024-09-05 10:48
文章标签 图像 分割 区域 生长

本文主要是介绍图像分割_区域生长,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

区域增长方法是根据同一物体区域内象素的相似性质来聚集象素点的方法,从初始区域(如小邻域或甚至于每个象素)开始,将相邻的具有同样性质的象素或其它区域归并到目前的区域中从而逐步增长区域,直至没有可以归并的点或其它小区域为止。区域内象素的相似性度量可以包括平均灰度值、纹理、颜色等信息。

     区域增长方法是一种比较普遍的方法,在没有先验知识可以利用时,可以取得最佳的性能,可以用来分割比较复杂的图象,如自然景物。但是,区域增长方法是一种迭代的方法,空间和时间开销都比较大。

 

区域生长是一种串行区域分割的图像分割方法。区域生长是指从某个像素出发,按照一定的准则,逐步加入邻近像素,当满足一定的条件时,区域生长终止。区域生长的好坏决定于1.初始点(种子点)的选取。2.生长准则。3.终止条件。区域生长是从某个或者某些像素点出发,最后得到整个区域,进而实现目标的提取。

区域生长的原理

区域生长的基本思想是将具有相似性质的像素集合起来构成区域。具体先对每个需要分割的区域找一个种子像素作为生长起点,然后将种子像素和周围邻域中与种子像素有相同或相似性质的像素(根据某种事先确定的生长或相似准则来判定)合并到种子像素所在的区域中。将这些新像素当作新的种子继续上面的过程,直到没有满足条件的像素可被包括进来。这样一个区域就生长成了。

 图1给出已知种子点进行区域生长的一个示例。图1(a)给出需要分割的图像,设已知两个种子像素(标为深浅不同的灰色方块),现要进行区域生长。设这里采用的判定准则是:如果考虑的像素与种子像素灰度值差的绝对值小于某个门限T,则将该像素包括进种子像素所在的区域。图1(b)给出了T=3时的区域生长结果,整幅图被较好地分成2个区域;图1(c)给出了T=1时的区域生长结果,有些像素无法判定;图1(c)给出了T=6时的区域生长的结果,整幅图都被分在一个区域中了。由此可见门限的选择是很重要的

 

区域生长是一种古老的图像分割方法,最早的区域生长图像分割方法是由Levine等人提出的。该方法一般有两种方式,一种是先给定图像中要分割的目标物体内的一个小块或者说种子区域(seed point),再在种子区域基础上不断将其周围的像素点以一定的规则加入其中,达到最终将代表该物体的所有像素点结合成一个区域的目的;另一种是先将图像分割成很多的一致性较强,如区域内像素灰度值相同的小区域,再按一定的规则将小区域融合成大区域,达到分割图像的目的,典型的区域生长法如T. C. Pong等人提出的基于小面(facet)模型的区域生长法,区域生长法固有的缺点是往往会造成过度分割,即将图像分割成过多的区域

 

 

区域生长实现的步骤如下:

1. 对图像顺序扫描!找到第1个还没有归属的像素, 设该像素为(x0, y0);

2. 以(x0, y0)为中心, 考虑(x0, y0)的4邻域像素(x, y)如果(x0, y0)满足生长准则, (x, y)(x0, y0)合并(在同一区域内), 同时将(x, y)压入堆栈;

3. 从堆栈中取出一个像素, 把它当作(x0, y0)返回到步骤2;

4. 当堆栈为空时!返回到步骤1;

5. 重复步骤1 - 4直到图像中的每个点都有归属时。生长结束。

 

 

代码:

/*************************************************************************

 *

 * /函数名称:

 *   RegionGrow()

 *

 * /输入参数:

 *   CDib * pDib                     - 指向CDib类的指针,含有原始图象信息

 *   unsigned char * pUnRegion       - 指向区域生长结果的指针

 *

 * /返回值:

 *   

 *

 * /说明:

 *   pUnRegion指针指向的数据区存储了区域生长的结果,其中(逻辑)表示

 *   对应象素为生长区域,表示为非生长区域

 *   区域生长一般包含三个比较重要的问题:

 *       1. 种子点的选取

 *       2. 生长准则

 *       3. 终止条件

 *   可以认为,这三个问题需要具体分析,而且每个问题解决的好坏直接关系到

 *   区域生长的结果。

 *   本函数的种子点选取为图像的中心,生长准则是相邻象素的象素值小于

 *   nThreshold, ()终止条件是一直进行到再没有满足生长准则需要的象素时为止

 *   

 *************************************************************************

 */

// 在这个代码中,它认为这张图片就是一个区域,选取了中间点为种子点。

void RegionGrow(CDib * pDib, unsigned char * pUnRegion, int nThreshold)

{

     static int nDx[]={-1,0,1,0};

     static int nDy[]={0,1,0,-1};

 

     nThreshold = 20;

 

     // 遍历图象的纵坐标

//   int y;

 

     // 遍历图象的横坐标

//   int x;

 

     // 图象的长宽大小

     CSize sizeImage        = pDib->GetDimensions();

     int nWidth             = sizeImage.cx         ;

     int nHeight            = sizeImage.cy         ;

 

     // 图像在计算机在存储中的实际大小

     CSize sizeImageSave    = pDib->GetDibSaveDim();

 

     // 图像在内存中每一行象素占用的实际空间

     int nSaveWidth = sizeImageSave.cx;

 

     // 初始化

     memset(pUnRegion,0,sizeof(unsigned char)*nWidth*nHeight);

 

     // 种子点

     int nSeedX, nSeedY;

 

     // 设置种子点为图像的中心

     nSeedX = nWidth /2 ;

     nSeedY = nHeight/2 ;

 

     // 定义堆栈,存储坐标

     int * pnGrowQueX ;

     int * pnGrowQueY ;

    

     // 分配空间

     pnGrowQueX = new int [nWidth*nHeight];

     pnGrowQueY = new int [nWidth*nHeight];

 

     // 图像数据的指针

     unsigned char *  pUnchInput =(unsigned char * )pDib->m_lpImage;

    

     // 定义堆栈的起点和终点

     // 当nStart=nEnd, 表示堆栈中只有一个点

     int nStart ;

     int nEnd   ;

 

     //初始化

     nStart = 0 ;

     nEnd   = 0 ;

 

     // 把种子点的坐标压入栈

     pnGrowQueX[nEnd] = nSeedX;

     pnGrowQueY[nEnd] = nSeedY;

 

     // 当前正在处理的象素

     int nCurrX ;

     int nCurrY ;

 

     // 循环控制变量

     int k ;

 

     // 图象的横纵坐标,用来对当前象素的邻域进行遍历

     int xx;

     int yy;

 

     while (nStart<=nEnd)

     {

         // 当前种子点的坐标

         nCurrX = pnGrowQueX[nStart];

         nCurrY = pnGrowQueY[nStart];

 

         // 对当前点的邻域进行遍历

         for (k=0; k<4; k++)   

         {   

              // 4邻域象素的坐标

              xx = nCurrX + nDx[k];

              yy = nCurrY + nDy[k];

             

              // 判断象素(xx,yy) 是否在图像内部

              // 判断象素(xx,yy) 是否已经处理过

              // pUnRegion[yy*nWidth+xx]==0 表示还没有处理

 

              // 生长条件:判断象素(xx,yy)和当前象素(nCurrX,nCurrY) 象素值差的绝对值

              if ( (xx < nWidth) && (xx>=0) && (yy<nHeight) && (yy>=0)

                       && (pUnRegion[yy*nWidth+xx]==0)

                       && abs(pUnchInput[yy*nSaveWidth+xx] - pUnchInput[nCurrY*nSaveWidth+nCurrX])<nThreshold )

              {

                   // 堆栈的尾部指针后移一位

                   nEnd++;

 

                   // 象素(xx,yy) 压入栈

                   pnGrowQueX[nEnd] = xx;

                   pnGrowQueY[nEnd] = yy;

 

                   // 把象素(xx,yy)设置成逻辑()

                   // 同时也表明该象素处理过

                   pUnRegion[yy*nWidth+xx] = 255 ;

              }

         }

         nStart++;

     }

 

     // 释放内存

     delete []pnGrowQueX;

     delete []pnGrowQueY;

    pnGrowQueX = NULL ;

     pnGrowQueY = NULL ;

}

 

该代码的效果不是很好,大概是选择的生长点不是很好吧。

这篇关于图像分割_区域生长的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1138746

相关文章

Python中OpenCV与Matplotlib的图像操作入门指南

《Python中OpenCV与Matplotlib的图像操作入门指南》:本文主要介绍Python中OpenCV与Matplotlib的图像操作指南,本文通过实例代码给大家介绍的非常详细,对大家的学... 目录一、环境准备二、图像的基本操作1. 图像读取、显示与保存 使用OpenCV操作2. 像素级操作3.

C/C++的OpenCV 进行图像梯度提取的几种实现

《C/C++的OpenCV进行图像梯度提取的几种实现》本文主要介绍了C/C++的OpenCV进行图像梯度提取的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录预www.chinasem.cn备知识1. 图像加载与预处理2. Sobel 算子计算 X 和 Y

c/c++的opencv图像金字塔缩放实现

《c/c++的opencv图像金字塔缩放实现》本文主要介绍了c/c++的opencv图像金字塔缩放实现,通过对原始图像进行连续的下采样或上采样操作,生成一系列不同分辨率的图像,具有一定的参考价值,感兴... 目录图像金字塔简介图像下采样 (cv::pyrDown)图像上采样 (cv::pyrUp)C++ O

Java内存区域与内存溢出异常的详细探讨

《Java内存区域与内存溢出异常的详细探讨》:本文主要介绍Java内存区域与内存溢出异常的相关资料,分析异常原因并提供解决策略,如参数调整、代码优化等,帮助开发者排查内存问题,需要的朋友可以参考下... 目录一、引言二、Java 运行时数据区域(一)程序计数器(二)Java 虚拟机栈(三)本地方法栈(四)J

Python+wxPython构建图像编辑器

《Python+wxPython构建图像编辑器》图像编辑应用是学习GUI编程和图像处理的绝佳项目,本教程中,我们将使用wxPython,一个跨平台的PythonGUI工具包,构建一个简单的... 目录引言环境设置创建主窗口加载和显示图像实现绘制工具矩形绘制箭头绘制文字绘制临时绘制处理缩放和旋转缩放旋转保存编

python+OpenCV反投影图像的实现示例详解

《python+OpenCV反投影图像的实现示例详解》:本文主要介绍python+OpenCV反投影图像的实现示例详解,本文通过实例代码图文并茂的形式给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录一、前言二、什么是反投影图像三、反投影图像的概念四、反向投影的工作原理一、利用反向投影backproj

Python实现图片分割的多种方法总结

《Python实现图片分割的多种方法总结》图片分割是图像处理中的一个重要任务,它的目标是将图像划分为多个区域或者对象,本文为大家整理了一些常用的分割方法,大家可以根据需求自行选择... 目录1. 基于传统图像处理的分割方法(1) 使用固定阈值分割图片(2) 自适应阈值分割(3) 使用图像边缘检测分割(4)

使用Python实现图像LBP特征提取的操作方法

《使用Python实现图像LBP特征提取的操作方法》LBP特征叫做局部二值模式,常用于纹理特征提取,并在纹理分类中具有较强的区分能力,本文给大家介绍了如何使用Python实现图像LBP特征提取的操作方... 目录一、LBP特征介绍二、LBP特征描述三、一些改进版本的LBP1.圆形LBP算子2.旋转不变的LB

Python如何将大TXT文件分割成4KB小文件

《Python如何将大TXT文件分割成4KB小文件》处理大文本文件是程序员经常遇到的挑战,特别是当我们需要把一个几百MB甚至几个GB的TXT文件分割成小块时,下面我们来聊聊如何用Python自动完成这... 目录为什么需要分割TXT文件基础版:按行分割进阶版:精确控制文件大小完美解决方案:支持UTF-8编码

OpenCV图像形态学的实现

《OpenCV图像形态学的实现》本文主要介绍了OpenCV图像形态学的实现,包括腐蚀、膨胀、开运算、闭运算、梯度运算、顶帽运算和黑帽运算,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起... 目录一、图像形态学简介二、腐蚀(Erosion)1. 原理2. OpenCV 实现三、膨胀China编程(