【转载】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);