基于格林公式计算:
连续型: 离散型
基于L2范数计算距离。
矩形,椭圆等外接形状。
查找轮廓:
void cv::findContours ( InputArray image,
OutputArrayOfArrays contours,
OutputArray hierarchy,
int mode,
int method,
Point offset = Point()
)
绘制轮廓:
void cv::drawContours ( InputOutputArray image,
InputArrayOfArrays contours,
int contourIdx,
const Scalar & color,
int thickness = 1,
int lineType = LINE_8,
InputArray hierarchy = noArray(),
int maxLevel = INT_MAX,
Point offset = Point()
)
代码展示了对二值化图像的轮廓查找、轮廓绘制、轮廓面积及周长的计算和应用、轮廓外接矩形、椭圆、带角度的矩形及角度信息的提取。
void QuickDemo::contour(Mat& image)
{
//高斯模糊
GaussianBlur(image, image, Size(3, 3), 0);
Mat gray;
cvtColor(image, gray, COLOR_BGR2GRAY);
Mat binary;
threshold(gray, binary, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);
namedWindow("THRESH_OTSU", WINDOW_FREERATIO);
imshow("THRESH_OTSU", binary);
//查找轮廓
vector> contours;
vector hierachy;
findContours(binary, contours, hierachy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
for (size_t t = 0; t < contours.size(); ++t) {
double area = contourArea(contours[t]);
double size = arcLength(contours[t], true);//只记录了闭合轮廓
cout << "第" << t << "个轮廓的面积为" << area << endl;
cout << "第" << t << "个轮廓的周长为" << size << endl << endl;
//根据面积和周长过滤,然后绘制轮廓或绘制外接图形
if (area > 100 || size > 100)continue;
//轮廓
//drawContours(image, contours, t, Scalar(0, 0, 255), 2, 8);
//外接矩形
/*Rect box = boundingRect(contours[t]);
rectangle(image, box, Scalar(0, 0, 255), 2, 8);*/
RotatedRect rt = minAreaRect(contours[t]);
//椭圆
ellipse(image, rt, Scalar(0, 0, 255), 2, 8);
//有角度的矩形绘制
Point2f pts[4];
rt.points(pts);
for (int i = 0; i < 4; ++i) {
line(image, pts[i], pts[(i + 1) % 4], Scalar(0, 0, 255), 2, 8);
}
//角度获取
cout << rt.angle << endl;
}
imshow("contours", image);
}