代码
#include "../common/common.hpp"
void main(int argc, char** argv) {
Mat src = imread(getCVImagesPath("images/case3-6.png"));
imshow("src3-6", src);
// 降噪(二值分割THRESH_TRIANGLE 的效果会更好) 二值分割+图像形态学+轮廓提取
Mat blurImage;
GaussianBlur(src, blurImage, Size(15, 15), 0, 0);
imshow("blur", blurImage);
Mat gray_src, binary;
cvtColor(blurImage, gray_src, COLOR_BGR2GRAY);
threshold(gray_src, binary, 0, 255, THRESH_BINARY | THRESH_TRIANGLE); // 颜色单一,所以使用 THRESH_TRIANGLE
imshow("binary", binary);
// 形态学操作
Mat morphImage;
Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
morphologyEx(binary, morphImage, MORPH_CLOSE, kernel, Point(-1, -1), 2);
imshow("morphology", morphImage);
// 获取最大轮廓
vector<vector<Point>> contours;
vector<Vec4i> hireachy;
findContours(morphImage, contours, hireachy, CV_RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
cout << "contours.size=" << contours.size() << endl; // contours.size=31
Mat connImage = Mat::zeros(src.size(), CV_8UC3);
for (size_t t = 0; t < contours.size(); t++) {
Rect rect = boundingRect(contours[t]);
if (rect.width < src.cols / 2) continue;
if (rect.width >(src.cols - 20)) continue;
double area = contourArea(contours[t]); // 轮廓面积,求面积的时候需要将轮廓中的区域变成黑色,否则面积会求的不正确?
double len = arcLength(contours[t], true); // 轮廓弧长
drawContours(connImage, contours, static_cast<int>(t), Scalar(0, 0, 255), 1, 8, hireachy);
printf("area of star could : %f\n", area); // area of star could : 148728.000000
printf("length of star could : %f\n", len); // length of star could : 2386.708920
}
imshow("result", connImage);
waitKey(0);
}
效果图