封闭几何区域填充 http://blog.sina.com.cn/s/blog_4b9cc6db0100bbyb.html 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 void FindRegion(IplImage *pImg, CvMemStorage *storage, list<CvRegion> *pRegionList){ //载入图像 if( pImg != 0 ) { IplImage *pSignedImg = cvCreateImage(cvGetSize(pImg), 8, 1); cvZero(pSignedImg); cvCopy(pImg, pSignedImg); CvSeq *contours = 0, *contoursTemp = 0; int totals = cvFindContours(pSignedImg, storage,&contours, sizeof(CvContour), //img必须是一个二值图像 storage 用来存储的contours指向存储的第一个轮廓 CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE, cvPoint(0,0)); contoursTemp = contours; cvCopy(pImg, pSignedImg); list<CvRegion> regionList; //保持区域 int nSignedVal = 100; // 标记像素值 for(;contoursTemp != 0; contoursTemp = contoursTemp -> h_next) /// 这样可以访问每一个轮廓 ====横向轮廓 { CvRegion region; memset(®ion, 0, sizeof(region)); CvPoint *pt = (CvPoint*) cvGetSeqElem(contoursTemp, 0); cvFloodFill(pSignedImg, *pt, cvScalarAll(nSignedVal), cvScalarAll(nSignedVal)); CvRect rt = cvBoundingRect(contoursTemp); region.boundRt = rt; int nAreaCount = 0; for(int h=rt.y; h<rt.y+rt.height; h++) { BYTE* pDataRow = (BYTE*)(pSignedImg->imageData + h*pSignedImg->widthStep); for(int w=rt.x; w<rt.x+rt.width; w++) { BYTE* pData = pDataRow + w; if(*pData == nSignedVal) { *pData = 0; nAreaCount++; } } } region.nArea = nAreaCount; //printf("nAreaCount = %d...........\n", nAreaCount); region.pSeqCountours = contoursTemp; pRegionList->push_back(region); } cvZero(pSignedImg); cvReleaseImage(&pSignedImg); return; }}void TestFindRegion(){ char *pszImgPath = "c:\\holdfill.bmp"; IplImage* pImg = NULL; //声明IplImage指针 //载入图像 if( (pImg = cvLoadImage( pszImgPath, 0)) != 0 ) { CvMemStorage *storage = cvCreateMemStorage(0); // 内存存储序列 list<CvRegion> regionList; FindRegion(pImg, storage, ®ionList); IplImage *pSignedImg = cvCreateImage(cvGetSize(pImg), 8, 1); cvZero(pSignedImg); int nExternalClrVal = 255; int nHoleClrVal = 255; for (list<CvRegion>::iterator itr=regionList.begin(); itr!=regionList.end(); itr++) { cvDrawContours( pSignedImg, //img itr->pSeqCountours, //countours CV_RGB(nExternalClrVal, nExternalClrVal, nExternalClrVal), //external_color CV_RGB(nHoleClrVal, nHoleClrVal, nHoleClrVal), //hole_color -2, //max_level CV_FILLED, //thick_ness CV_AA, //lines_type cvPoint(0,0) ); //offset } cvShowImage("img", pImg); cvShowImage("pSignedImg", pSignedImg); cvWaitKey(0); cvReleaseImage(&pSignedImg); cvReleaseMemStorage(&storage); // 也要释放内存序列空间 cvReleaseImage(&pImg); }}typedef struct _CvRegion { int nArea; CvRect boundRt; CvSeq *pSeqCountours; }CvRegion, *PCvRegion; floodfill算法,连通域标记算法都可以;给个floodfill算法DEMO:http://bbs.csdn.net/topics/390256087 对话框chlid风格//无法接受自定义消息吗? 循序渐进实现仿QQ界面(三):界面调色与控件自绘 [难题]已知一个进程ID\API函数名\DLL名\求此API函数在此进程中的入口地址 如何从doc文件里提取纯文本?? 面试的问题 帮忙比较一下 我刚开始学VC,可以问一个问题吗? 送分,简单的切分视问题 GDI+ 实现橡皮擦 本人创办了一小型的软件公司,现在有资本家有意合作,请问有什么好的合作方式吗? mfc基于windows media player控件的视频播放器制作 数字图像处理如何做矩形检测
void FindRegion(IplImage *pImg, CvMemStorage *storage, list<CvRegion> *pRegionList)
{
//载入图像
if( pImg != 0 )
{
IplImage *pSignedImg = cvCreateImage(cvGetSize(pImg), 8, 1);
cvZero(pSignedImg); cvCopy(pImg, pSignedImg); CvSeq *contours = 0, *contoursTemp = 0; int totals = cvFindContours(pSignedImg, storage,&contours, sizeof(CvContour), //img必须是一个二值图像 storage 用来存储的contours指向存储的第一个轮廓
CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE, cvPoint(0,0));
contoursTemp = contours; cvCopy(pImg, pSignedImg); list<CvRegion> regionList; //保持区域
int nSignedVal = 100; // 标记像素值 for(;contoursTemp != 0; contoursTemp = contoursTemp -> h_next) /// 这样可以访问每一个轮廓 ====横向轮廓
{
CvRegion region;
memset(®ion, 0, sizeof(region)); CvPoint *pt = (CvPoint*) cvGetSeqElem(contoursTemp, 0);
cvFloodFill(pSignedImg, *pt, cvScalarAll(nSignedVal), cvScalarAll(nSignedVal)); CvRect rt = cvBoundingRect(contoursTemp);
region.boundRt = rt; int nAreaCount = 0; for(int h=rt.y; h<rt.y+rt.height; h++)
{
BYTE* pDataRow = (BYTE*)(pSignedImg->imageData + h*pSignedImg->widthStep); for(int w=rt.x; w<rt.x+rt.width; w++)
{
BYTE* pData = pDataRow + w; if(*pData == nSignedVal)
{
*pData = 0;
nAreaCount++;
}
}
} region.nArea = nAreaCount;
//printf("nAreaCount = %d...........\n", nAreaCount); region.pSeqCountours = contoursTemp; pRegionList->push_back(region);
} cvZero(pSignedImg);
cvReleaseImage(&pSignedImg); return;
}
}void TestFindRegion()
{
char *pszImgPath = "c:\\holdfill.bmp";
IplImage* pImg = NULL; //声明IplImage指针 //载入图像
if( (pImg = cvLoadImage( pszImgPath, 0)) != 0 )
{
CvMemStorage *storage = cvCreateMemStorage(0); // 内存存储序列 list<CvRegion> regionList;
FindRegion(pImg, storage, ®ionList); IplImage *pSignedImg = cvCreateImage(cvGetSize(pImg), 8, 1);
cvZero(pSignedImg); int nExternalClrVal = 255;
int nHoleClrVal = 255;
for (list<CvRegion>::iterator itr=regionList.begin(); itr!=regionList.end(); itr++)
{
cvDrawContours( pSignedImg, //img
itr->pSeqCountours, //countours
CV_RGB(nExternalClrVal, nExternalClrVal, nExternalClrVal), //external_color
CV_RGB(nHoleClrVal, nHoleClrVal, nHoleClrVal), //hole_color
-2, //max_level
CV_FILLED, //thick_ness
CV_AA, //lines_type
cvPoint(0,0) ); //offset
} cvShowImage("img", pImg);
cvShowImage("pSignedImg", pSignedImg);
cvWaitKey(0); cvReleaseImage(&pSignedImg);
cvReleaseMemStorage(&storage); // 也要释放内存序列空间
cvReleaseImage(&pImg);
}
}typedef struct _CvRegion
{
int nArea; CvRect boundRt;
CvSeq *pSeqCountours;
}CvRegion, *PCvRegion;
给个floodfill算法DEMO:http://bbs.csdn.net/topics/390256087