图像中区域生长算法的详解和实现

区域生长算法的基本思想是将有相似性质的像素点合并到一起。对每一个区域要先指定一个种子点作为生长的起点,然后将种子点周围领域的像素点和种子点进行对比,将具有相似性质的点合并起来继续向外生长,直到没有满足条件的像素被包括进来为止。这样一个区域的生长就完成了。这个过程中有几个关键的问题:

1 给定种子点(种子点如何选取?)

种子点的选取很多时候都采用人工交互的方法实现,也有用其他方式的,比如寻找物体并提取物体内部点或者利用其它算法找到的特征点作为种子点。

2 确定在生长过程中能将相邻像素包括进来的准则

这个准则很重要:例如包括灰度值的差值;彩色图像的颜色;梯度特征,包括梯度的方向和幅值特征。该点周围的区域特征,例如harr特征,也就是区域像素和特征。

举个例子:发在PAMI上的LSD直线检测算法中的关键一步就是找line support regions.这个区域的查找就是利用区域生长法则,生长的条件就是梯度的方向角度。

上图第一张图是原始图像,第二张图就是计算梯度角度,第三章图就是根据梯度角度区域生长的结果,相同颜色就是一个区域生长结果

这个是论文中区域生长的伪代码。

上图就是Harr特征,这个特征很有用,由于是区域特征,在图像干扰很大的时候,能对感兴趣的区域进行有效的提取。当然也可以作为生长的准则。

3 生长的停止条件

算法实现的步骤:

1>  创建一个空白的图像(全黑);

2> 将种子点存入vector(或者stack)中,vector中存储待生长的种子点;

3> 依次弹出种子点,一般从尾部弹出,也就是后进先出,并判断种子点如周围8领域的关系(生长规则),相似的点则作为下次生长的种子点;

4> vector中不存在种子点后就停止生长。

上代码:

  1 #include "stdafx.h"
  2 #include <opencv2/opencv.hpp>
  3 #include <vector>
  4 #include <stack>
  5
  6 using namespace std;
  7 using namespace cv;
  8
  9
 10
 11 void regiongrowth(IplImage* &inputimg,IplImage* &outputimg,CvPoint pt,int th)
 12 {
 13
 14   CvPoint ptGrowing;//待生长点的位置
 15   int nGrowLabel=0;//是否被标记
 16   int nScrValue=0;//生长起始点的灰度值
 17   int nCurValue=0;//当前生长点的灰度值
 18
 19   IplImage* Dstimg=cvCreateImage(cvGetSize(inputimg),8,1);
 20   if (Dstimg==NULL)
 21   {
 22       printf("image read error too");
 23       return;
 24   }
 25   cvZero(Dstimg);
 26
 27   int DIR[8][2]={{-1,-1}, {0,-1}, {1,-1}, {1,0}, {1,1}, {0,1}, {-1,1}, {-1,0}};
 28
 29   vector<CvPoint>vcGrowpt;//生长点的堆栈
 30   vcGrowpt.push_back(pt);//将初始生长点压入堆栈
 31
 32   //标记初始生长点
 33   Dstimg->imageData[pt.x+pt.y*Dstimg->widthStep]=255;
 34   nScrValue=inputimg->imageData[pt.x+pt.y*inputimg->widthStep];
 35
 36
 37   while(!vcGrowpt.empty())
 38   {
 39       CvPoint curpt=vcGrowpt.back();//在堆栈中取出一个生长点
 40       vcGrowpt.pop_back();
 41
 42       for(int i=0;i<8;i++)
 43       {
 44           ptGrowing.x=curpt.x+DIR[i][0];
 45           ptGrowing.y=curpt.y+DIR[i][1];
 46           //检查边缘点
 47           if(ptGrowing.x<0||ptGrowing.y<0||(ptGrowing.x>inputimg->width-1)||(ptGrowing.y>inputimg->height-1))
 48               continue;
 49           nGrowLabel=Dstimg->imageData[ptGrowing.x+ptGrowing.y*Dstimg->widthStep];
 50           if (nGrowLabel==0)//表示还未标记过
 51           {
 52               nCurValue=inputimg->imageData[ptGrowing.x+ptGrowing.y*inputimg->widthStep];
 53               if(abs(nCurValue-nScrValue)<=th)
 54               {
 55                   Dstimg->imageData[ptGrowing.x+ptGrowing.y*Dstimg->widthStep]=255;
 56                   vcGrowpt.push_back(ptGrowing);
 57
 58               }
 59           }
 60
 61       }
 62
 63
 64   }
 65   cvCopy(Dstimg,outputimg);
 66   cvReleaseImage(&Dstimg);
 67
 68 }
 69
 70
 71
 72 int _tmain(int argc, _TCHAR* argv[])
 73 {
 74
 75    IplImage* sourceimage=cvLoadImage("H:\\programm\\test.jpg",0);
 76
 77    if (sourceimage==NULL)
 78    {
 79        printf("image read error");
 80    }
 81
 82
 83
 84     IplImage* outputimg=cvCreateImage(cvGetSize(sourceimage),8,1);
 85     IplImage* resultimg=cvCreateImage(cvGetSize(sourceimage),8,1);
 86     cvZero(resultimg);
 87     cvCopy(sourceimage,outputimg);
 88     regiongrowth(sourceimage,outputimg,cvPoint(392,282),12);
 89     cvAdd(outputimg,resultimg,resultimg);
 90
 91     regiongrowth(sourceimage,outputimg,cvPoint(587,195),8);
 92     cvAdd(outputimg,resultimg,resultimg);
 93
 94     regiongrowth(sourceimage,outputimg,cvPoint(707,356),8);
 95     cvAdd(outputimg,resultimg,resultimg);
 96
 97     regiongrowth(sourceimage,outputimg,cvPoint(546,549),10);
 98     cvAdd(outputimg,resultimg,resultimg);
 99
100     regiongrowth(sourceimage,outputimg,cvPoint(310,435),10);
101     cvAdd(outputimg,resultimg,resultimg);
102
103     cvNamedWindow("source",0);
104     cvShowImage("source",sourceimage);
105
106     cvNamedWindow("result",0);
107     cvShowImage("result",resultimg);
108     cvWaitKey(0);
109
110     cvReleaseImage(&sourceimage);
111     cvReleaseImage(&outputimg);
112     cvReleaseImage(&resultimg);
113    system("pause");
114     return 0;
115 }

这个代码实现结果,就是提取下面左图中的5个区域,右边为提取结果,由于用的是灰度差作为生长条件,效果一般般。

参考文章:http://blog.csdn.net/robin__chou/article/details/50071313

时间: 2024-12-31 04:00:38

图像中区域生长算法的详解和实现的相关文章

快速傅立叶变换算法FFT——图像处理中的数学原理详解22

欢迎关注我的博客专栏"图像处理中的数学原理详解" 全文目录请见 图像处理中的数学原理详解(总纲) http://blog.csdn.net/baimafujinji/article/details/48467225 图像处理中的数学原理详解(已发布的部分链接整理) http://blog.csdn.net/baimafujinji/article/details/48751037 交流学习可加图像处理研究学习QQ群(529549320) 傅立叶变换以高等数学(微积分)中的傅立叶级数为基

图像处理中的数学原理详解21——PCA实例与图像编码

欢迎关注我的博客专栏"图像处理中的数学原理详解" 全文目录请见 图像处理中的数学原理详解(总纲) http://blog.csdn.net/baimafujinji/article/details/48467225 图像处理中的数学原理详解(已发布的部分链接整理) http://blog.csdn.net/baimafujinji/article/details/48751037 如果你对PCA的推导和概念还不是很清楚,建议阅读本文的前导文章 http://blog.csdn.net/

图像处理中的数学原理详解(Part7) ——哈密尔顿算子

全文目录请见 图像处理中的数学原理详解(Part1 总纲) http://blog.csdn.net/baimafujinji/article/details/48467225 在前面的部分中我们已经完整地给出了梯度和散度这些数学概念的意义,这些生涩的定义在最初学习的时候很少有人会注意到它们跟图像能有什么联系.然而,随着学习的深入,当真正接触到图像处理算法时,你又不得不承认,梯度.散度这些东西几乎是无处不在的.本节所介绍的内容就是这些概念在图像处理中的最最简单应用之范例.这部分内容与边缘检测技术

关于开设“图像处理中的数学原理详解”博客专栏的说明

近期,我在CSDN开设了一个博客专栏"图像处理中的数学原理详解",专门用于发布这个系列的文章.. 全文目录请见 图像处理中的数学原理详解(总纲) http://blog.csdn.net/baimafujinji/article/details/48467225 我整理了图像处理中可能用到的一些数学基础,将其分成了6个章节(全文目录见上方链接).如果你对其中的某一小节特别感兴趣,但是它还没有被发布,你可以在博客下方留言,我会据此调整发布顺序.但是请务必精确地指出章节标号(例如1.3.7

word2vec 中的数学原理详解

word2vec 中的数学原理详解 word2vec 是 Google 于 2013 年开源推出的一个用于获取 word vector 的工具包,它简单.高效,因此引起了很多人的关注.由于 word2vec 的作者 Tomas Mikolov 在两篇相关的论文 [3,4] 中并没有谈及太多算法细节,因而在一定程度上增加了这个工具包的神秘感.一些按捺不住的人于是选择了通过解剖源代码的方式来一窥究竟. 第一次接触 word2vec 是 2013 年的 10 月份,当时读了复旦大学郑骁庆老师发表的论文

Mahout推荐算法API详解

前言 用Mahout来构建推荐系统,是一件既简单又困难的事情.简单是因为Mahout完整地封装了“协同过滤”算法,并实现了并行化,提供非常简单的API接口:困难是因为我们不了解算法细节,很难去根据业务的场景进行算法配置和调优. 本文将深入算法API去解释Mahout推荐算法底层的一些事. 1. Mahout推荐算法介绍 Mahoutt推荐算法,从数据处理能力上,可以划分为2类: 单机内存算法实现 基于Hadoop的分步式算法实现 1). 单机内存算法实现 单机内存算法实现:就是在单机下运行的算法

各大公司广泛使用的在线学习算法FTRL详解

各大公司广泛使用的在线学习算法FTRL详解 现在做在线学习和CTR常常会用到逻辑回归( Logistic Regression),而传统的批量(batch)算法无法有效地处理超大规模的数据集和在线数据流,google先后三年时间(2010年-2013年)从理论研究到实际工程化实现的FTRL(Follow-the-regularized-Leader)算法,在处理诸如逻辑回归之类的带非光滑正则化项(例如1范数,做模型复杂度控制和稀疏化)的凸优化问题上性能非常出色,据闻国内各大互联网公司都第一时间应

图像处理中的数学原理详解9——索伯列夫空间

全文目录请见 图像处理中的数学原理详解(Part1 总纲) http://blog.csdn.net/baimafujinji/article/details/48467225 在泛函分析中,索伯列夫空间并不像 巴拿赫空间或者希尔伯特空间那么引入注意.但是在图像处理中,索伯列夫空间在介绍BV空间(有界变差函数空间)时,会被提到.而BV函数空间对于理解TV算法(偏微分方程在图像处理中的重要内容)至关重要!所以我特别在"图像处理中的数学原理详解"系列文章中留出一个小节来对索伯列夫空间进行必

IOS问题汇总:2015-1-9 IOS之NSArray 中调用的方法详解(转)

IOS之NSArray 中调用的方法详解 下面的例子以 NSArray *array = [NSArray arrayWithObjects:@“wendy”,@“andy”,@“tom”,@“jonery”,@“stany”, nil];1.获取数组中总共有多少个对象. -(NSUInteger)count; NSLog(@“%d”,[array count]); 2 2.获取数组中下标对应的元素对象.(下标是从0开始) -(id)objectAtIndex:(NSUInteger)index