【转载】openCV轮廓操作

声明:非原创,转载自互联网,有问题联系博主

1.轮廓的提取

从图片中将目标提取出来,常常用到的是提取目标的轮廓。

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

外层vector的size代表了图像中轮廓的个数,里面vector的 size代表了轮廓上点的个数。下面我们通过实例来看函数的用法。

int main() {
     Mat image=imread("../shape.png");
     cvtColor(image,image,CV_BGR2GRAY);
     vector<vector<Point>> contours;
// find
     findContours(image,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE);
// draw
    Mat result(image.size(),CV_8U,Scalar(0));
    drawContours(result,contours,-1,Scalar(255),2);
    namedWindow("contours");
    imshow("contours",result);
    waitKey();
    return 0;
}

findContours() 具体参数用法可以参考openCV手册里函数的介绍。

2.轮廓的描述

提取到轮廓后,更关心的是如何把这些轮廓转换为可以利用的特征,这涉及到轮廓的描述问题。

有多种方法可以选择,比如矢量化为多边形、矩形、椭圆等。OpenCV里提供了一些这样的函数。

// 轮廓表示为一个矩形
Rect r = boundingRect(Mat(contours[0]));
rectangle(result, r, Scalar(255), 2);
 
// 轮廓表示为一个圆
float radius;
Point2f center;
minEnclosingCircle(Mat(contours[1]), center, radius);
circle(result, Point(center), static_cast<int>(radius), Scalar(255), 2);
 
// 轮廓表示为一个多边形
vector<Point> poly;
approxPolyDP(Mat(contours[2]), poly, 5, true);
vector<Point>::const_iterator itp = poly.begin();
while (itp != (poly.end() - 1)){
    line(result, *itp, *(itp + 1), Scalar(255), 2);
    ++itp;
}
line(result, *itp, *(poly.begin()), Scalar(255), 2);
// 轮廓表示为凸多边形
vector<Point> hull;
convexHull(Mat(contours[3]), hull);
vector<Point>::const_iterator ith = hull.begin();
while (ith != (hull.end() - 1)){
    line(result, *ith, *(ith + 1), Scalar(255), 2);
    ++ith;
}
line(result, *ith, *(hull.begin()), Scalar(255), 2);

以上摘自:OpenCV成长之路(8):直线、轮廓的提取与描述(边缘、直线、轮廓)

原文地址:https://www.cnblogs.com/iois/p/4777584.html