检测最大星云图的边缘和面积
分析图片
此图片有很多噪声,包括文字小片星云都对我们处理此图片造成了一定的影响
首先我们先去噪声,有前面所需的API函数可知道先腐蚀
在膨胀
可以去除小块噪声并且图像大小不改变
基于上面图像处理,理论上我们已经把文字以及小片的星云噪声给去掉了,接下来就是轮廓提取了,轮廓提取有很多种方法像Canny
,findContours
,拉普拉斯锐化
都可以很好地体现轮廓和提取轮廓,但是这里我们采用形态学的内梯度
进行轮廓提取
现在理论上我们已经把图片的轮廓提取出来了,然后我们在利用’findContours’API对轮廓的点进行提取,在提取时候还会提取到很多杂乱的信息,这里我们就需要对轮廓进行过滤了,我们采用面积的方式进行过滤利用contourArea
API函数得到面积,除去图片本身的轮廓,我们需要最大的轮廓.
现在目标也已经发现了,我们可以利用polylines
API函数绘画出我们的轮廓
至此分析完毕
结果图
代码
void Demo::exampleOne(Mat &src)
{
Mat gray, dst, binary, erode_image, inside_contour;
if (src.channels() >= 2)
{
cvtColor(src, gray, COLOR_BGR2GRAY);
} else
{
gray = src.clone();
}
//高斯模糊
GaussianBlur(gray, gray, Size(9, 9), 0);
//结构元素
Mat remove_noise_kernerl = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
//腐蚀
erode(gray, erode_image, remove_noise_kernerl, Point(-1, -1), 10);
//膨胀
dilate(erode_image, gray, remove_noise_kernerl, Point(-1, -1), 10);
namedWindow("腐蚀和膨胀", WINDOW_FREERATIO);
imshow("腐蚀和膨胀", gray);
Mat kernerl = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
//腐蚀
erode(gray, erode_image, kernerl, Point(-1, -1), 3);
//图片相减 提取轮廓
subtract(gray, erode_image, inside_contour);
namedWindow("内轮廓", WINDOW_FREERATIO);
imshow("内轮廓", inside_contour);
threshold(inside_contour, inside_contour, 0, 255, THRESH_BINARY | cv::THRESH_OTSU);
namedWindow("二值", WINDOW_FREERATIO);
imshow("二值", inside_contour);
//发现轮廓
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
findContours(inside_contour, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
dst = Mat::zeros(src.size(), CV_8UC3);
dst = Scalar(0, 0, 0);
for (int i = 1; i < contours.size(); ++i)
{
double area = contourArea(contours[i]);
//轮廓筛选
if (area > 1690)
{
//绘制轮廓
cout << area << endl;
polylines(dst, contours[i], true, Scalar(0, 0, 255), 2);
polylines(src, contours[i], true, Scalar(0, 0, 255), 2);
//形状逼近
Mat pts;
approxPolyDP(contours[i], pts, 4, true);
for (int j = 0; j < pts.rows; ++j)
{
Vec2i pt=pts.at<Vec2i>(j,0);
circle(dst,Point (pt[0],pt[1]), 2, Scalar(255, 0, 0), 2);
circle(src,Point (pt[0],pt[1]), 2, Scalar(255, 0, 0), 2);
}
}
}
namedWindow("结果", WINDOW_FREERATIO);
namedWindow("结果1", WINDOW_FREERATIO);
imshow("结果", dst);
imshow("结果1", src);
}