問題のI.説明
面積と周囲長の測定対象物の画像を撮影し、プログラムを周囲画素の面積を測定し、プロセス内の実際的な問題、およびスケール変換ユニットへ。
II。ソリューション
バイナリ画像を処理することによって分割形態+ +輪郭抽出
III。ソース
#include <opencv2/opencv.hpp>
#include <math.h>
#include <iostream>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
Mat srcImage = imread("E:\\pictures\\48.jpg");
if (srcImage.empty())
{
Mat srcImage = imread("E:\\pictures\\48.jpg");
if (srcImage.empty())
{
cout << "图像读取错误!" << endl;
return -1;
}
namedWindow("【1】原图", WINDOW_AUTOSIZE);
imshow("【1】原图", srcImage);
}
//高斯模糊降噪
Mat blurImage;
GaussianBlur(srcImage, blurImage, Size(15, 15), 0, 0);
imshow("【2】高斯去噪后", blurImage);
//二值化
Mat gray_srcImage, binary_srcImage;
cvtColor(blurImage, gray_srcImage, COLOR_BGR2GRAY);
threshold(gray_srcImage, binary_srcImage, 0, 255, THRESH_BINARY | THRESH_TRIANGLE);
//这里使用THRESH_TRIANGLE而不使用THRESH_OTSU的原因是该图像的直方图显示是一个单峰
imshow("【3】二值化后", binary_srcImage);
//形态学操作
Mat morphImage;
Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
morphologyEx(binary_srcImage, morphImage, MORPH_CLOSE, kernel, Point(-1, -1), 2);
//开操作是将边缘断开,闭操作是先膨胀后腐蚀,即将图像中的小洞填上
imshow("【4】形态学操作后", morphImage);
//获取最大轮廓
vector<vector<Point>> contours;
vector<Vec4i> hireachy;
//findContours(morphImage, contours, hireachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point());
findContours(morphImage, contours, hireachy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
Mat contoursImage = Mat::zeros(srcImage.size(), CV_8UC3);
for (size_t t = 0; t < contours.size(); t++)
{
Rect rect = boundingRect(contours[t]);
if (rect.width < srcImage.cols / 2)//筛选出小于原图一般宽度尺寸的轮廓
{
continue;
}
double area = contourArea(contours[t]); //轮廓的面积
double length = arcLength(contours[t], true); //轮廓的周长
drawContours(contoursImage, contours, static_cast<int>(t), Scalar(0, 0, 255), 1, 8, hireachy);
//显示的数值是像素,实际中要与比例尺进行转换
cout << "轮廓的面积为:" << area << endl;
cout << "轮廓的周长为:" << length << endl;
}
imshow("【5】效果图", contoursImage);
waitKey(0);
return 0;
}
出力: