opencv实现连通域
在本文中使用图像连通域统计使用opencv中的cvFloodFill方法,可是在cvFloodFill方法中CvConnectedComp參数无法返回详细点坐标位置信息,找了些资料、给CvSeq分配空间可是还是contour内容没有值,预计是OPENCV2.00版本号不支持。假设想获取点坐标信息有两种方法:一是通过源码改写cvFloodFill函数来返回点坐标信息;二是cvFloodFill连通之后,依据返回区域统计多少个点,并统计之后对此点做标记,依次重复下一个连通区域。
下面是方法二的代码实现:
//连通区域结构
typedef struct MyConnectedComp
{
double area;
int value;
RECT rect;
list<POINT> listAllPoint;
}MyConnectedComp
/*
*功能说明:统计图像的连通区域
*參数说明:src,表示原始图象;rectSrc,表示图像区域;listData,表示连通域结构链表;nUnionColor,表示连通颜色(0,表示黑点;1,表示白点);nUnionMode,表示连通类型(0,表示4连通;1,表示8连通)
*返回值:int类型。-1,表示參数错误;0,表示非二值/灰度图像
*/
int ImageUnionByFloodFill(CxImage *src,RECT rectSrc,list<MyConnectedComp> &listData,int nUnionColor,int nUnionMode)
{
int nRet = 1;
//參数检測
if(src==NULL || !(nUnionColor==0||nUnionColor==1) || !(nUnionMode==1||nUnionMode==2) || (rectSrc.left==0 && rectSrc.right==0 || rectSrc.top==0 && rectSrc.bottom==0 || rectSrc.left>rectSrc.right || rectSrc.top>rectSrc.bottom))
{
nRet = -1;
return nRet;
}
if(src->GetBpp()>8)
{
nRet = 0;
return nRet;
}
listData.clear();
int nColor = 255;
if(nUnionColor==0)
{
nUnionColor = 255;
}
if(nUnionColor==1)
{
nUnionColor = 0;
}
int nFlag = 4;
if(nUnionMode==1)
{
nFlag = 4;
}
if(nUnionMode==2)
{
nFlag = 8;
}
int iBackColor = GetBlackColor(*src);
long i = 0,j = 0;
long m = 0,n = 0,newN = 0,newM = 0;
long nWidth = 0,nHeight = 0;
IplImage *pcvImageTmp = NULL;
if(!Cximage2IplImage(src,&pcvImageTmp))
{
return 0;
}
//假设是灰度图像,做二值化处理
if(src->GetBpp()!=1)
{
cvThreshold(pcvImageTmp,pcvImageTmp,128,255,CV_THRESH_BINARY);
}
CvSize size = cvGetSize(pcvImageTmp);
DatumnConnectedComp dccTmp;
CvConnectedComp comp;
CvPoint seed;
for(j=rectSrc.top;j<rectSrc.bottom;j++)
{
for(i=rectSrc.left;i<rectSrc.right;i++)
{
if(i<0 || i>=size.width || j<0 || j>=size.height)
{
continue;
}
uchar *p = (uchar *)&(pcvImageTmp->imageData+j*pcvImageTmp->widthStep)[i];
if(*p==nUnionColor || *p==100 || *p==101)
{
continue;
}
//处理为黑点,做连通
seed = cvPoint(i,j);
cvFloodFill(pcvImageTmp, seed,cvScalarAll(100), cvScalarAll(0),cvScalarAll(0), &comp, nFlag, 0 );
dccTmp.area = comp.area;
dccTmp.rect.left = comp.rect.x;
dccTmp.rect.top = comp.rect.y;
dccTmp.rect.right = comp.rect.x + comp.rect.width;
dccTmp.rect.bottom = comp.rect.y + comp.rect.height;
dccTmp.value = int(comp.value.val[1]);
dccTmp.listAllPoint.clear();
POINT ptInsert;
for(n=0;n<=comp.rect.height;n++)
{
for(m=0;m<comp.rect.width;m++)
{
newN = n + comp.rect.y;
newM = m + comp.rect.x;
if(newN>=size.height || newM>=size.width)
{
continue;
}
uchar *q = (uchar *)&(pcvImageTmp->imageData+newN*pcvImageTmp->widthStep)[newM];
if(*q==100)
{
ptInsert.x = newM;
ptInsert.y = newN;
dccTmp.listAllPoint.push_back(ptInsert);
*q = 101;//改变标记,说明已被连通
}
}
}
listData.push_back(dccTmp);
}
}
cvReleaseImage(&pcvImageTmp);
return nRet;
}
注:CxImage是一款优秀的图像操作类库。它能够快捷地存取、显示、转换各种图像。
opencv实现连通域的更多相关文章
- Opencv图像连通域
[摘要] 本文介绍在图像处理领域中较为常用的一种图像区域(Blob)提取的方法——连通性分析法(连通区域标记法). 文中介绍了两种常见的连通性分析的算法:1)Two-pass:2)Seed-Filli ...
- OpenCV: 图像连通域检测的递归算法
序言:清除链接边缘,可以使用数组进行递归运算; 连通域检测的递归算法是定义级别的检测算法,且是无优化和无语义失误的. 同样可用于寻找连通域 void ClearEdge(CvMat* MM,CvPoi ...
- 基于OpenCV.Net连通域分析进行文本块分割
上一次通过投影的方式进行了文本块分割,(见 https://www.cnblogs.com/BoyTNT/p/11812323.html )但这种方法有很大的局限性,要求分行清晰.不能有字符跨多行.不 ...
- C++ & OpenCV 零散学习总结
OpenCV中Mat基本用法: Mat类 (Matrix的缩写) 是OpenCV用于处理图像而引入的一个封装类.从功能上讲,Mat类在IplImage结构的基础上进一步增强,并且,由于引入C++高级编 ...
- ubuntu yolov2 训练自己的数据集
项目需求+锻炼自己,尝试用yolov2跑自己的数据集,中间遇到了很多问题,记下来防止忘记 一.数据集 首先发现由于物体特殊没有合适的现成的数据集使用,所以只好自己标注,为了减少工作量,先用opencv ...
- java OPENCV 连通域, Imgproc.findContours 例子,参数说明
http://stackoverflow.com/questions/29491669/real-time-paper-sheet-detection-using-opencv-in-android/ ...
- opencv 删除二值化图像中面积较小的连通域
对于上图的二值化图像,要去除左下角和右上角的噪点,方法:使用opencv去掉黑色面积较小的连通域. 代码 CvSeq* contour = NULL; double minarea = 100.0; ...
- opencv学习系列:连通域参考处理
OpenCV里提取目标轮廓的函数是findContours,它的输入图像是一幅二值图像,输出的是每一个连通区域的轮廓点的集合:vector<vector<Point>>. 外层 ...
- opencv 连通域需要的函数解析
OpenCV支持大量的轮廓.边缘.边界的相关函数,相应的函数有moments.HuMoments.findContours.drawContours.approxPolyDP.arcLength.bo ...
随机推荐
- OpenCV 安装
OpenCV 安装 一.环境说明: 操作系统:window10 opencv版本是:VERSION3.1 二.安装过程: [1]官网下载:http://opencv.org/downloads.htm ...
- [iOS]超详细Apache服务器的配置(10.10系统)
配置目的:有一个自己专属的测试服务器 我们需要做以下事情: 1.新建一个目录,存放网页 2.修改Apache配置文件httpd.conf - 修改两个路径 - 增加一个属性 - 支持PHP脚本 3.拷 ...
- 「OC」 封装
一.面向对象和封装 面向对象的三大特性:封装.继承和多态 在OC语言中,使用@interface和@implementation来处理类. @interface就好像暴露在外面的时钟表面,像外界提 ...
- C# Socket select模型
http://www.cnblogs.com/Clingingboy/archive/2011/07/04/2097806.html http://www.cnblogs.com/RascallySn ...
- C语言之一数三平方
一数三平方 有这样一个六位数,它本身是一个整数的平方,其高三位和低三位也分别是一个整数的平方,如225625=475*475,225=15*15,625=25*25;统计所有符合该条件的六位数 源代码 ...
- 腾讯QQ是用什么语言开发的(转)
腾讯QQ的部分COM组件用的VC6,用exescope看其中几个dll的依赖,依赖于MFC42.dll,MSVCRT.dll,MSVCP60.dll都说明是VC6写的. 还有一部分用的VS2005,包 ...
- 异步和同步http请求超时机制
异步超时设置: 例子: Example: do a simple HTTP GET request for http://www.nethype.de/ and print the response ...
- Android zip文件压缩解压缩
DirTraversal.java <P style="TEXT-ALIGN: left; PADDING-BOTTOM: 0px; WIDOWS: 2; TEXT-TRANSFORM ...
- 如何提高banner设计含量--网上的一篇文章--感悟
"修改": 本质上是改什么?改大小?图片?文字?颜色? 老板说:修改本质上是提高“设计含量”.检测一个作品设计含量的高低,可以将作品中每一个设计元素进行分析,看它的“属性”与“操作 ...
- ExtJS4.2 - 从 Hello World 到 自定义组件 -01 (为爱女伊兰奋斗)
ExtJS4.2 - 从 Hello World 到 自定义组件 - 01 经验.概述.项目搭建.国际化.HelloWorld.布局 —— 为爱女伊兰而奋斗 ——少走弯路,简单才是王道 1. 写在前面 ...