在本文中使用图像连通域统计使用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是一款优秀的图像操作类库。它能够快捷地存取、显示、转换各种图像。

下载地址:http://www.codeproject.com/KB/graphics/cximage.aspx

opencv实现连通域的更多相关文章

  1. Opencv图像连通域

    [摘要] 本文介绍在图像处理领域中较为常用的一种图像区域(Blob)提取的方法——连通性分析法(连通区域标记法). 文中介绍了两种常见的连通性分析的算法:1)Two-pass:2)Seed-Filli ...

  2. OpenCV: 图像连通域检测的递归算法

    序言:清除链接边缘,可以使用数组进行递归运算; 连通域检测的递归算法是定义级别的检测算法,且是无优化和无语义失误的. 同样可用于寻找连通域 void ClearEdge(CvMat* MM,CvPoi ...

  3. 基于OpenCV.Net连通域分析进行文本块分割

    上一次通过投影的方式进行了文本块分割,(见 https://www.cnblogs.com/BoyTNT/p/11812323.html )但这种方法有很大的局限性,要求分行清晰.不能有字符跨多行.不 ...

  4. C++ & OpenCV 零散学习总结

    OpenCV中Mat基本用法: Mat类 (Matrix的缩写) 是OpenCV用于处理图像而引入的一个封装类.从功能上讲,Mat类在IplImage结构的基础上进一步增强,并且,由于引入C++高级编 ...

  5. ubuntu yolov2 训练自己的数据集

    项目需求+锻炼自己,尝试用yolov2跑自己的数据集,中间遇到了很多问题,记下来防止忘记 一.数据集 首先发现由于物体特殊没有合适的现成的数据集使用,所以只好自己标注,为了减少工作量,先用opencv ...

  6. java OPENCV 连通域, Imgproc.findContours 例子,参数说明

    http://stackoverflow.com/questions/29491669/real-time-paper-sheet-detection-using-opencv-in-android/ ...

  7. opencv 删除二值化图像中面积较小的连通域

    对于上图的二值化图像,要去除左下角和右上角的噪点,方法:使用opencv去掉黑色面积较小的连通域. 代码 CvSeq* contour = NULL; double minarea = 100.0; ...

  8. opencv学习系列:连通域参考处理

    OpenCV里提取目标轮廓的函数是findContours,它的输入图像是一幅二值图像,输出的是每一个连通区域的轮廓点的集合:vector<vector<Point>>. 外层 ...

  9. opencv 连通域需要的函数解析

    OpenCV支持大量的轮廓.边缘.边界的相关函数,相应的函数有moments.HuMoments.findContours.drawContours.approxPolyDP.arcLength.bo ...

随机推荐

  1. Cloudera Manager、CDH零基础入门、线路指导 http://www.aboutyun.com/thread-9219-1-1.html (出处: about云开发)

    Cloudera Manager.CDH零基础入门.线路指导http://www.aboutyun.com/thread-9219-1-1.html(出处: about云开发) 问题导读:1.什么是c ...

  2. BZOJ 1651: [Usaco2006 Feb]Stall Reservations 专用牛棚( 线段树 )

    线段树.. -------------------------------------------------------------------------------------- #includ ...

  3. python安装zlib一直无效

    一直按网上的方法: 1.先安装 apt-get install zlib1g-dev 2.重新安装python(3.3):即是./configure 再make再make install 始终没有解决 ...

  4. Oracle 11g New 热补丁

    热补丁:概览 对于Oracle 实例上的bug 修复或诊断补丁程序,热补丁 可以执行以下操作: • 安装 • 启用 • 禁用 热补丁:概览 使用热补丁可以安装.启用和禁用 正在运行的 活动Oracle ...

  5. 1 初级.net web工程师,在工作中都做些什么

    初级.Net Web工程师,在工作中都做些神马?   职责 初级.Net Web工程师的主要职责,就是按比较详细的要求去完成代码. 比较详细的要求是指:一般会把页面式样.功能的描述.数据库结构.性能要 ...

  6. Trie树:应用于统计和排序

    Trie树:应用于统计和排序 1. 什么是trie树 1.Trie树 (特例结构树)       Trie树,又称单词查找树.字典树,是一种树形结构,是一种哈希树的变种,是一种用于快速检索的多叉树结构 ...

  7. 建房子之前先挖地基 - Java BlockingQueue理解

    最近一直在看<Think In Java>里关于并发部分的章节,读到第二十一章有一个有趣的比喻:必须先挖房子的地基,但是接下来可以并行的铺设钢结构和构建水泥部件,而这两项任务必须在混凝土浇 ...

  8. BZOJ 1610: [Usaco2008 Feb]Line连线游戏

    1610: [Usaco2008 Feb]Line连线游戏 Description Farmer John最近发明了一个游戏,来考验自命不凡的贝茜.游戏开始的时 候,FJ会给贝茜一块画着N (2 &l ...

  9. XMPP--- error : linker command failed with exit code 1

    error: linker command failed with exit code 1 (use -v to see invocation) 错误原因:libidn.a文件没添加上去 解决方法:l ...

  10. 工作需要稍微研究了一下Hyper-V

    Hyper-V是指微软的虚拟化技术,底层用得Hypervisior好像没有特殊的名字 虚拟化市场占有率前三:VMWare,Hyper-V,Citrix Citrix的XenServer今年彻底开源,原 ...