opencv 连通区域边界坐标提取

目录

 

1.Iplmage版提取连通区域坐标

2.Mat版提取连通区域坐标,仅保留最大连通区域

3.标记连通区域并计算连通区域特性

4.Mat与IplImage转换


 

1.Iplmage版提取连通区域坐标

#include <iostream>  
#include "cv.h"  
#include "cxcore.h"  
#include "highgui.h"  
using namespace std;  
int main()  
{  
    CvMemStorage *storage = cvCreateMemStorage(0);   // 内存存储序列  
    IplImage *img = cvLoadImage("E:\\study_opencv_video\\lesson14_1\\Debug\\55.png", 0);  
    IplImage *imgColor = cvCreateImage(cvGetSize(img), 8, 3);  
    IplImage *contoursImage = cvCreateImage(cvGetSize(img), 8, 1);  
  
    CvSeq *contours = 0, *contoursTemp = 0;    
    cvZero(contoursImage);  
    cvThreshold(img, img, 100, 255, CV_THRESH_BINARY);  // 二值化操作  
    cvCvtColor(img, imgColor, CV_GRAY2BGR);  
    int totals = cvFindContours(img, storage,&contours, sizeof(CvContour),    //img必须是一个二值图像 storage 用来存储的contours指向存储的第一个轮廓  
        CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE, cvPoint(0,0));  
    contoursTemp = contours;  
    int count = 0;  
    int i;  
    for(;contoursTemp != 0; contoursTemp = contoursTemp -> h_next)  /// 这样可以访问每一个轮廓  ====横向轮廓  
    {  
        for(i = 0; i < contoursTemp -> total; i++)    // 提取一个轮廓的所有坐标点  
        {  
            CvPoint *pt = (CvPoint*) cvGetSeqElem(contoursTemp, i);   // 得到一个轮廓中一个点的函数cvGetSeqElem  
            cvSetReal2D(contoursImage, pt->y, pt->x, 255.0);  
            cvSet2D(imgColor, pt->y, pt->x, cvScalar(0,0,255,0));  
        }  
        count ++;  
        CvSeq *InterCon = contoursTemp->v_next;     // 访问每个轮廓的纵向轮廓  
        for(; InterCon != 0; InterCon = InterCon ->h_next)  
        {  
            for(i = 0; i < InterCon->total; i++ )  
            {  
                CvPoint *pt = (CvPoint*)cvGetSeqElem(InterCon, i);  
                cvSetReal2D(contoursImage, pt->y, pt->x, 255.0);  
                cvSet2D(imgColor, pt->y, pt->x, cvScalar(0, 255, 0, 0));  
            }  
        }  
    }  
    cvNamedWindow("contoursImage");  
    cvShowImage("contoursImage", contoursImage);  
    cvNamedWindow("imgColor");  
    cvShowImage("imgColor",imgColor);  
    cvWaitKey(0);  
    cvReleaseMemStorage(&storage);      // 也要释放内存序列空间  
    cvReleaseImage(&contoursImage);  
    cvReleaseImage(&imgColor);  
    cvDestroyWindow("contoursImage");  
    cvDestroyWindow("imgColor");  
    return 0;
}

2.Mat版提取连通区域坐标,仅保留最大连通区域

Mat findMaxContours(Mat src)
{
	Mat bw; src.copyTo(bw);
	//查找最大连通区域
	vector<vector<Point>>contours;  //每个轮廓中的点
	vector<Vec4i>hierarchy;         //轮廓的索引  
	findContours(bw, contours, hierarchy, CV_RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
	double max_area = 0;
	int index = 0;
	for (int i = 0; i < contours.size(); i++)
	{
		if (contourArea(contours[i]) > max_area)
		{
			max_area = contourArea(contours[i]);
			index = i;
		}
	}
	Mat dstImage = Mat::zeros(src.rows, src.cols, CV_8UC1);
	if (contours.size()>0)
	{
		drawContours(dstImage, contours, index, Scalar(255), -1);
	}
	contours.clear();
	hierarchy.clear();
	contours.swap(vector<vector<Point>>(contours));
	hierarchy.swap(vector<Vec4i>(hierarchy));
	return dstImage;
	//RotatedRect rect_Pointer = minAreaRect(contours[index]);
	//cv::Point2f* vertices = new cv::Point2f[4];
	//rect_Pointer.points(vertices);
	//std::vector<cv::Point> contourRect;
	//for (int i = 0; i < 4; i++)
	//{
	//	contourRect.push_back(vertices[i]);
	//}
	//std::vector<std::vector<cv::Point>> contourRects;
	//contourRects.push_back(contourRect);
	//drawContours(dstImage, contourRects, 0, Scalar(255), -1);
}

3.标记连通区域并计算连通区域特性

//ref:https://blog.csdn.net/fei13148687/article/details/104800400
int cv::connectedComponents(
        InputArray    image,             // 输入二值图像
        OutputArray   labels,            // 输出的标记图像,背景index=0
        int           connectivity = 8,  // 连通域,默认是8连通
        int           ltype = CV_32S     // 输出的labels类型,默认是CV_32S
) 
//带有统计信息的API:
int cv::connectedComponentsWithStats(
        InputArray   image,        // 输入二值图像
        OutputArray  labels,       // 输出的标记图像,背景index=0
        OutputArray  stats,        // 统计信息,包括每个组件的位置、宽、高与面积
        OutputArray  centroids,    // 每个组件的中心位置坐标cx, cy
        int          connectivity, // 连通域,默认是8连通
        int          ltype,        // 输出的labels类型,默认是CV_32S
        int          ccltype       // 连通组件算法
)

4.Mat与IplImage转换

//--Mat to IplImage
Mat src = Mat::zeros(10, 10, CV_8UC1);
IplImage* srcIpl = NULL;
srcIpl = &(IplImage)src;//Ipl与Mat共享内存,Release尽量两个变量都手动释放

//--IplImage to Mat
Mat srcMat(srcIpl , false);//仅创建Mat头与IplImage共享内存

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值