OpenCV图象孔洞内轮廓填充

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

                     图像内轮廓填充通常称为孔洞填充,主要用于目标提取。不带任何条件的内轮廓填充,在目标密度很大时,可能导致错误填充。一种典型情况,当多个目标粘连,并 且形成环状时,简单的内轮廓填充会将环状内部背景部分误认为目标空洞进行错误填充。这种错误对于目标分割和提取是非常致命的。


  如果将内轮廓面积作为限制条件进行填充,就可以很好解决上述问题。通常内轮廓面积应该不大于目标的最大面积。


#include  #include  #include #pragma comment(lib, "cv.lib")#pragma comment(lib, "cxcore.lib") #pragma comment(lib, "highgui.lib")// 内轮廓填充 // 参数: // 1. pBinary: 输入二值图像,单通道,位深IPL_DEPTH_8U。// 2. dAreaThre: 面积阈值,当内轮廓面积小于等于dAreaThre时,进行填充。 void FillInternalContours(IplImage *pBinary, double dAreaThre) {  double dConArea;  CvSeq *pContour = NULL;  CvSeq *pConInner = NULL;  CvMemStorage *pStorage = NULL;  // 执行条件  if (pBinary)  {   // 查找所有轮廓   pStorage = cvCreateMemStorage(0);   cvFindContours(pBinary, pStorage, &pContour, sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);   // 填充所有轮廓   cvDrawContours(pBinary, pContour, CV_RGB(255, 255, 255), CV_RGB(255, 255, 255), 2, CV_FILLED, 8, cvPoint(0, 0));  // 外轮廓循环   for (; pContour != NULL; pContour = pContour->h_next)   {    // 内轮廓循环    for (pConInner = pContour->v_next; pConInner != NULL; pConInner = pConInner->h_next)    {     // 内轮廓面积     dConArea = fabs(cvContourArea(pConInner, CV_WHOLE_SEQ));     if (dConArea <= dAreaThre)     {      cvDrawContours(pBinary, pConInner, CV_RGB(255, 255, 255), CV_RGB(255, 255, 255), 0, CV_FILLED, 8, cvPoint(0, 0));    }    }   }   cvReleaseMemStorage(&pStorage);   pStorage = NULL;  } } int main()  {   IplImage *img = cvLoadImage(".//test.png", 0);   IplImage *bin = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1); cvCopy(img, bin); FillInternalContours(bin, 200);   cvNamedWindow("img");   cvShowImage("img", img);   cvNamedWindow("result");   cvShowImage("result", bin);   cvWaitKey(-1);   cvReleaseImage(&img);   cvReleaseImage(&bin);   return 0;  } 

           

给我老师的人工智能教程打call!http://blog.csdn.net/jiangjunshow

这里写图片描述

你可能感兴趣的:(OpenCV图象孔洞内轮廓填充)