寻找包裹轮廓的最小正矩形。矩形的边界与图像边界平行。 唯一一个参数是输入的二维点集,可以是 vector 或 Mat 类型。只需要 #include "opencv2/opencv.hpp"
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| #include<opencv.hpp> #include<iostream> using namespace cv; using namespace std; int main(){ Mat src = imread("/home/user/test.jpg"); imshow("src", src);
Mat gray, bin_img; cvtColor(src, gray, COLOR_BGR2GRAY); imshow("gray", gray);
threshold(gray, bin_img, 150, 255, THRESH_BINARY_INV); imshow("bin_img", bin_img); vector<vector<Point> >contours; findContours(bin_img, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE);
RNG rngs = { 12345 }; Mat dst = Mat::zeros(src.size(), src.type()); for (int i = 0; i < contours.size(); i++) { Scalar colors = Scalar(rngs.uniform(0, 255), rngs.uniform(0, 255), rngs.uniform(0, 255)); drawContours(dst, contours, i, colors, 1); Rect rects = boundingRect(contours[i]); rectangle(dst, rects, colors, 2); } imshow("dst", dst);
waitKey(0); }
|

寻找包裹轮廓的最小斜矩形。唯一一个参数是输入的二维点集,可以是 vector 或 Mat 类型。只需要 #include "opencv2/opencv.hpp"
与 boundingRect
返回结果的区别是:矩形的边界不必与图像边界平行
RotatedRect
旋转矩形结构体

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| Mat gray, bin_img; cvtColor(src, gray, COLOR_BGR2GRAY); imshow("gray", gray);
threshold(gray, bin_img, 150, 255, THRESH_BINARY_INV); imshow("bin_img", bin_img);
vector<vector<Point> >contours; findContours(bin_img, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE);
RNG rngs = { 12345 }; Mat dst = Mat::zeros(src.size(), src.type()); Point2f pts[4]; for (int i = 0; i < contours.size(); i++) { Scalar colors = Scalar(rngs.uniform(0, 255), rngs.uniform(0, 255), rngs.uniform(0, 255)); drawContours(dst, contours, i, colors, 1); RotatedRect rects = minAreaRect(contours[i]); rects.points(pts); for (int i = 0; i < 4; i++) line(dst, pts[i], pts[(i + 1) % 4], colors, 2); } }
|

计算点与轮廓的距离及位置关系,只需要 #include "opencv2/opencv.hpp"
contour: 所需检测的轮廓对象
pt: Point2f 类型的pt, 待判定位置的点
measureDist: 是否计算距离的标志, 当其为true时, 计算点到轮廓的最短距离, 当其为false时, 只判定轮廓与点的位置关系, 具体关系如下:
① 返回值为-1, 表示点在轮廓外部
② 返回值为0, 表示点在轮廓上
③ 返回值为1, 表示点在轮廓内部
如果不需要知道具体的距离,建议将第三个参数设为false,这样速度会提高2到3倍。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| Mat srcImg = imread("1.png"); imshow("src", srcImg);
Mat dstImg = srcImg.clone(); cvtColor(srcImg, srcImg, CV_BGR2GRAY); threshold(srcImg, srcImg, 100, 255, CV_THRESH_BINARY); imshow("threshold", srcImg);
vector<vector<Point>> contours; vector<Vec4i> hierarcy; findContours(srcImg, contours, hierarcy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE); cout << "contours.size()=" << contours.size() << endl; for (int i = 0; i < contours.size(); i++) { for (int j = 0; j < contours[i].size(); j++) { cout << "(" << contours[i][j].x << "," << contours[i][j].y << ")" << endl; } } double a0 = pointPolygonTest(contours[0], Point(3, 3), true); double b0 = pointPolygonTest(contours[0], Point(212, 184), false);
|
求轮廓面积 cv::contourArea
double contourArea( InputArray contour, bool oriented = false );
- InputArray类型的
contour
,输入的向量,二维点(轮廓顶点),可以为std::vector
或Mat类型。
- bool类型的
oriented
,面向区域标识符。若其为true,会返回一个带符号的面积值,正负取决于轮廓的方向。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| #include<iostream> #include<opencv2/opencv.hpp> using namespace std; using namespace cv; int main(void) { Mat A = Mat::zeros(500, 500, CV_8UC1); circle(A, Point2i(100, 100), 3, 255, -1); circle(A, Point2i(300, 400), 50, 255, -1); circle(A, Point2i(250, 100), 100, 255, -1); circle(A, Point2i(400, 300), 60, 255, -1); std::vector<std::vector<cv::Point> > contours; std::vector<cv::Vec4i> hierarchy; cv::findContours(A, contours, hierarchy, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE, cv::Point()); if (!contours.empty() && !hierarchy.empty()) { std::vector<std::vector<cv::Point> >::const_iterator itc = contours.begin(); int i = 1; while (itc != contours.end()) { double area = cv::contourArea(*itc); cout << "第" << i << "个轮廓的面积为:" << area << endl; i++; itc++; } } imshow("A", A); waitKey(0); system("pause"); return 0; }
|
第一个圆的面积并不是9π,而是20。面积值是按照轮廓的内部面积进行计算的,会损失一些。
参考: cv::contourArea