图像中区域生长算法的详解和实现
2016-01-27 21:27
417 查看
区域生长算法的基本思想是将有相似性质的像素点合并到一起。对每一个区域要先指定一个种子点作为生长的起点,然后将种子点周围领域的像素点和种子点进行对比,将具有相似性质的点合并起来继续向外生长,直到没有满足条件的像素被包括进来为止。这样一个区域的生长就完成了。这个过程中有几个关键的问题:
1 给定种子点(种子点如何选取?)种子点的选取很多时候都采用人工交互的方法实现,也有用其他方式的,比如寻找物体并提取物体内部点或者利用其它算法找到的特征点作为种子点。
2 确定在生长过程中能将相邻像素包括进来的准则
这个准则很重要:例如包括灰度值的差值;彩色图像的颜色;梯度特征,包括梯度的方向和幅值特征。该点周围的区域特征,例如harr特征,也就是区域像素和特征。
举个例子:发在PAMI上的LSD直线检测算法中的关键一步就是找line support regions.这个区域的查找就是利用区域生长法则,生长的条件就是梯度的方向角度。
#include "stdafx.h" #include <opencv2/opencv.hpp> #include <vector> #include <stack> using namespace std; using namespace cv; void regiongrowth(IplImage* &inputimg,IplImage* &outputimg,CvPoint pt,int th) { CvPoint ptGrowing;//待生长点的位置 int nGrowLabel=0;//是否被标记 int nScrValue=0;//生长起始点的灰度值 int nCurValue=0;//当前生长点的灰度值 IplImage* Dstimg=cvCreateImage(cvGetSize(inputimg),8,1); if (Dstimg==NULL) { printf("image read error too"); return; } cvZero(Dstimg); int DIR[8][2]={{-1,-1}, {0,-1}, {1,-1}, {1,0}, {1,1}, {0,1}, {-1,1}, {-1,0}}; vector<CvPoint>vcGrowpt;//生长点的堆栈 vcGrowpt.push_back(pt);//将初始生长点压入堆栈 //标记初始生长点 Dstimg->imageData[pt.x+pt.y*Dstimg->widthStep]=255; nScrValue=inputimg->imageData[pt.x+pt.y*inputimg->widthStep]; while(!vcGrowpt.empty()) { CvPoint curpt=vcGrowpt.back();//在堆栈中取出一个生长点 vcGrowpt.pop_back(); for(int i=0;i<8;i++) { ptGrowing.x=curpt.x+DIR[i][0]; ptGrowing.y=curpt.y+DIR[i][1]; //检查边缘点 if(ptGrowing.x<0||ptGrowing.y<0||(ptGrowing.x>inputimg->width-1)||(ptGrowing.y>inputimg->height-1)) continue; nGrowLabel=Dstimg->imageData[ptGrowing.x+ptGrowing.y*Dstimg->widthStep]; if (nGrowLabel==0)//表示还未标记过 { nCurValue=inputimg->imageData[ptGrowing.x+ptGrowing.y*inputimg->widthStep]; if(abs(nCurValue-nScrValue)<=th) { Dstimg->imageData[ptGrowing.x+ptGrowing.y*Dstimg->widthStep]=255; vcGrowpt.push_back(ptGrowing); } } } } cvCopy(Dstimg,outputimg); cvReleaseImage(&Dstimg); } int _tmain(int argc, _TCHAR* argv[]) { IplImage* sourceimage=cvLoadImage("H:\\programm\\test.jpg",0); if (sourceimage==NULL) { printf("image read error"); } IplImage* outputimg=cvCreateImage(cvGetSize(sourceimage),8,1); IplImage* resultimg=cvCreateImage(cvGetSize(sourceimage),8,1); cvZero(resultimg); cvCopy(sourceimage,outputimg); regiongrowth(sourceimage,outputimg,cvPoint(392,282),12); cvAdd(outputimg,resultimg,resultimg); regiongrowth(sourceimage,outputimg,cvPoint(587,195),8); cvAdd(outputimg,resultimg,resultimg); regiongrowth(sourceimage,outputimg,cvPoint(707,356),8); cvAdd(outputimg,resultimg,resultimg); regiongrowth(sourceimage,outputimg,cvPoint(546,549),10); cvAdd(outputimg,resultimg,resultimg); regiongrowth(sourceimage,outputimg,cvPoint(310,435),10); cvAdd(outputimg,resultimg,resultimg); cvNamedWindow("source",0); cvShowImage("source",sourceimage); cvNamedWindow("result",0); cvShowImage("result",resultimg); cvWaitKey(0); cvReleaseImage(&sourceimage); cvReleaseImage(&outputimg); cvReleaseImage(&resultimg); system("pause"); return 0; }
View Code
[b]这个代码实现结果,就是提取下面左图中的5个区域,右边为提取结果,由于用的是灰度差作为生长条件,效果一般般。
参考文章:http://blog.csdn.net/robin__chou/article/details/50071313
相关文章推荐
- JavaWeb学习总结(十三)——使用Session防止表单重复提交
- 考考你的页面跳转
- svn for linux安装
- 【转】R树空间索引
- 将数据写入.txt文件中
- hdu 2501--Tiling_easy version
- 【转】B树、B-树、B+树、B*树、红黑树、 二叉排序树、trie树Double Array 字典查找树简介
- javascript中的Array对象的方法
- 【算法】对分查找(排序队列)
- JavaSE入门学习13:Java面向对象之封装
- mariadb connect引擎连接sqlserver
- span设为inline-block之后,未包含文字时下面会多出一条空白问题
- HDU 1863 - 畅通工程
- Guess Your Way Out! II---cf 558D (区间覆盖,c++STL map 的使用)
- MySQL执行状态分析
- 如何将word中所有的图片一次性保存
- 01背包的DFS解法
- ArcSDE用户介绍
- java线程池问题
- 3.6 常用查询的例子