关于星云图获取最大面积轮廓的C++案例的DEMO
作者:Simon
实现图说明
原图
高斯模糊-降噪效果
三角二值化图
图形学闭操作去掉内部小噪点
目标图(红框图)
目标图(白色填充)
打印结果截图
软件环境
VS2015,OpenCV341,C++
实现代码
#include<iostream>
#include<opencv2/opencv.hpp>
#include<math.h>
using namespace std;
using namespace cv;
int main(int argc,char** argv) {
//读取图片,灰度图
Mat src = imread("G:\\opencv_trainning\\vs2015\\3\\objectextractionandmeasurement\\1.jpg",IMREAD_GRAYSCALE);
//判空
if (src.empty()) {
cout << "open fault" << endl;
return -1;
}
//显示
namedWindow("src");
imshow("src",src);
//高斯模糊-降噪,提高周围像素的相似度
Mat gaussianImg;//定义图
GaussianBlur(src,gaussianImg,Size(15,15),0,0);//参数:(原图,目标图,核尺寸,x标准差,y标准差),其他参数默认
imshow("gaussianImg",gaussianImg);
//二值化处理-获得黑底白图
Mat binaryImg;//定义图
threshold(gaussianImg,binaryImg,0,255,THRESH_BINARY|THRESH_TRIANGLE);//参数:(灰度图,目标图,阈值,最大值,阈值处理),此处用自动三角阈值法
imshow("binaryImg",binaryImg);
//形态学操作-闭操作,去掉整体中的干扰
Mat element = getStructuringElement(MORPH_RECT,Size(3,3),Point(-1,-1));//定义元素核,参数:(形状,核尺寸,锚点)
morphologyEx(binaryImg,binaryImg,MORPH_CLOSE,element,Point(-1,-1),2);//闭操作,参数:(二值化图,目标图,操作标记,核元素,锚点,迭代次数)
imshow("morphologyEx",binaryImg);
//获取轮廓,找最大轮廓
vector<vector<Point>> contours;//轮廓向量的向量
vector<Vec4i> hierarchy;//拓扑结构变量
//参数:(二值化图,轮廓向量的向量,拓扑结构变量,检查方法,发现方法,偏移点),此处只要最外层轮廓
findContours(binaryImg,contours,hierarchy,RETR_EXTERNAL,CHAIN_APPROX_SIMPLE,Point(0,0));//图片要求黑底白面
//找和画轮廓
Mat drawContoursImg = Mat::zeros(src.size(), CV_8UC3);//定义画轮廓的新图
for (size_t i = 0; i < contours.size();i++) {//循环轮廓
Rect rect = boundingRect(contours[i]);//获得当前轮廓的正矩形
if (rect.width < src.cols/2) continue;//去掉小于1/2宽的轮廓
if (rect.width>(src.cols-20))continue;//去掉过大的轮廓
double area = contourArea(contours[i]);//计算面积,面积是基于几何矩计算,需要黑底白面
double arclength = arcLength(contours[i], true);//计算周长
printf("area=%g arclength=%g\n", area, arclength);//打印面积和周长
//画轮廓,参数:(图,轮廓,位置id,颜色,线宽)
//drawContours(drawContoursImg,contours,static_cast<int>(i),Scalar(0,0,255),2);//红色框
drawContours(drawContoursImg,contours,static_cast<int>(i),Scalar(255,255,255),-1);//白色填充
}
imshow("drawContoursImg", drawContoursImg);
waitKey(0);//按键等待
return 0;
}
思路
1.高斯模糊:降噪,提高周围像素的相似程度;
2.三角二值化:打银光(TRIANGLE)获得黑白二值化(BINARY)图;
3.图像学闭操作:去掉内部小黑点,注意选择元素核尺寸(15,15);
4.发现轮廓:获得所有外轮廓;
5.对轮廓做出处理:获得正矩形(boundingRect);宽小于一半的不要(过小的不要),大于宽-20的不要(过大的不要);其他的绘制drawConturs()出来;使用contourArea()计算通过的轮廓面积,使用arcLength()计算通过的轮廓周长。
注意:此处的面积是像素面积,一个像素为单位1的平方。
我是Simon,在这里期待与您的交流。