- Photo nebula images from space telescopes, scientists want to know the area and perimeter.
- Gaussian blur binary segmentation + + + morphological image contour extraction
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main(int argc, char** argv)
{
Mat src,gray_temp, gauss_temp,threshold_temp,morph_temp,dst;
src = imread("../path.jpg");
if (src.empty())
{
cout << "could not load image..." << endl;
return -1;
}
namedWindow("src", WINDOW_AUTOSIZE);
imshow("src", src);
//高斯模糊
GaussianBlur(src, gauss_temp, Size(15, 15), 0, 0);
//转换为灰度图
cvtColor(gauss_temp, gray_temp, COLOR_BGR2GRAY);
//通过二值分割
threshold(gray_temp, threshold_temp, 0, 255, THRESH_BINARY | THRESH_TRIANGLE);
//图像形态学//去噪声
Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
morphologyEx(threshold_temp, morph_temp, MORPH_CLOSE, kernel, Point(-1, -1), 2);
//(最大)轮廓提取
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
findContours(morph_temp, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
dst = Mat::zeros(src.size(), CV_8UC3);
double Area = 0;//定义轮廓面积
double ArcL = 0;//定义轮廓周长
for (size_t i = 0; i < contours.size(); i++)
{
Rect rect = boundingRect(contours[i]);
if (rect.width < (src.cols / 2) )//过滤掉小轮廓
continue;
if (rect.width > (src.cols - 10))//过滤掉大(边框)轮廓
continue;
drawContours(dst, contours, i, Scalar(0, 255, 255), 1, 8, hierarchy);
Area = contourArea(contours[i]);
ArcL = arcLength(contours[i],true);
cout << "目标面积为:" << Area << endl;
cout << "目标周长为:" << ArcL << endl;
}
imshow("Contours", dst);
waitKey(0);
return 0;
}
Output: