• c++视觉处理---计算轮廓面积


    矩的计算:cv::moments

    cv::momentsOpenCV中用于计算图像或轮廓的矩特征的函数。矩特征是一种用于描述图像或轮廓的几何特性的方法,包括中心矩、归一化中心矩、中心矩矩和归一化中心矩矩等。这些特征在形状分析、对象识别和物体测量等领域非常有用。

    cv::moments 函数的基本用法如下:

    cv::Moments cv::moments(const cv::Mat& array, bool binaryImage = false);
    
    • 1
    • array: 输入的图像或轮廓。
    • binaryImage: 一个布尔值,指定输入是否为二进制图像。如果设置为 true,将仅考虑轮廓内的像素。

    这个函数返回一个 cv::Moments 对象,其中包含了各种矩特征的值,可以通过 m 成员变量来访问这些值,如 m.m00m.m01m.m10 等。

    轮廓面积:cv::contourArea

    cv::contourArea 是OpenCV中用于计算轮廓的面积的函数。它接受一个轮廓作为输入,并返回该轮廓所围成区域的面积。这个函数非常有用,可以用于形状分析、对象测量和图像处理中的各种任务。

    cv::contourArea 函数的基本用法如下:

    double cv::contourArea(const std::vector<cv::Point>& contour, bool oriented = false);
    
    • 1
    • contour: 输入的轮廓,通常是一个 std::vector
    • oriented: 一个布尔值,指定是否考虑轮廓的方向。如果设置为 true,则会考虑轮廓的方向,如果为 false,则忽略方向。

    这个函数返回一个 double 类型的值,表示轮廓所围成区域的面积。
    cv::arcLength
    cv::arcLength 是OpenCV中用于计算轮廓的弧长(周长)的函数。它接受一个轮廓作为输入,并返回轮廓的弧长。弧长是轮廓的所有线段(弧段)长度的总和。

    轮廓长度:cv::arcLength 函数的基本用法如下:

    double cv::arcLength(const std::vector<cv::Point>& contour, bool closed);
    
    • 1
    • contour: 输入的轮廓,通常是一个 std::vector
    • closed: 一个布尔值,指定轮廓是否封闭。如果设置为 true,则轮廓被认为是封闭的,如果为 false,则认为是开放的。

    这个函数返回一个 double 类型的值,表示轮廓的弧长。

    查找和绘制图像轮廓矩

    #include 
    #include 
    #include 
    #include 
    
    using namespace std;
    using namespace cv;
    #include 
    #include 
    using namespace cv; //包含cv命名空间
    #include 
    //-- - --【宏定义部分】---- ---- ----------
    //描述: 定义一些辅助宏
    #define WINDOW_NAME1 "【原始图】" //为窗口标题定义的宏
    #define WINDOW_NAME2 "【图像轮廓】" //为窗口标题定义的宏
    //--【全局变量声明部分】------------------------
    // 描述: 全局变量的声明
    Mat g_srcImage; Mat g_grayImage;
    int g_nThresh = 100;
    int g_nMaxThresh = 255;
    RNG g_rng(12345);
    Mat g_cannyMat_output;
    vector<vector<Point> > g_vContours;
    vector<Vec4i> g_vHierarchy;
    // ---------------------【全局变量声明部分】-------------------
    // 描述: 全局变量的声明
    //
    void on_ThreshChange(int, void*);
    static void ShowHelpText();
    //-【main()函数】------------------------
    // 描述: 控制台应用程序的入口函数, 我们的程序从这里开始执行
    int main(int argc, char** argv)
    {
    	//【0】改变 console字体颜色
    	system("color 1E");
    	//读入原图像,返回3通道图像数据
    	g_srcImage = imread("1.jpg", 1);
    	// 把原图像转化成灰度图像并进行平滑
    	cvtColor(g_srcImage, g_grayImage, COLOR_BGR2GRAY);
    	blur(g_grayImage, g_grayImage, Size(3, 3));
    	// 创建新窗口
    	namedWindow(WINDOW_NAME1, WINDOW_AUTOSIZE);
    	imshow(WINDOW_NAME1, g_srcImage);
    	//创建滚动条并进行初始化
    	createTrackbar(" 阈值", WINDOW_NAME1, &g_nThresh, g_nMaxThresh, on_ThreshChange);
    	on_ThreshChange(0, 0);
    	waitKey(0);
    	return(0);
    }
    //-----------------------【on_ThreshChange()函数】-------------------
    // 描述: 回调函数
    //--
    void on_ThreshChange(int, void*)
    {
    	// 使用Canndy检测边缘
    	Canny(g_grayImage, g_cannyMat_output, g_nThresh, g_nThresh * 2, 3);
    	// 找到轮廓
    	findContours(g_cannyMat_output, g_vContours, g_vHierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
    	// 计算矩
    	vector<Moments> mu(g_vContours.size());
    	for (unsigned int i = 0; i < g_vContours.size(); i++)
    	{
    		mu[i] = moments(g_vContours[i], false);
    	}
    	// 计算中心矩
    	vector<Point2f> mc(g_vContours.size());
    	for (unsigned int i = 0; i < g_vContours.size(); i++)
    	{
    		mc[i] = Point2f(static_cast<float>(mu[i].m10 / mu[i].m00), static_cast<float>(mu[i].m01 / mu[i].m00));
    	}
    	// 绘制轮廓
    	Mat drawing = Mat::zeros(g_cannyMat_output.size(), CV_8UC3); for (unsigned int i = 0; i < g_vContours.size(); i++)
    	{
    		Scalar color = Scalar(g_rng.uniform(0, 255),
    			g_rng.uniform(0, 255), g_rng.uniform(0, 255));//随机生成颜色值
    		drawContours(drawing, g_vContours, i, color, 2, 8, g_vHierarchy, 0, Point());//绘制外层和内层轮廓
    		circle(drawing, mc[i], 4, color, -1, 8, 0);;//绘制圆
    	}
    	// 显示到窗口中
    	namedWindow(WINDOW_NAME2, WINDOW_AUTOSIZE);
    	imshow(WINDOW_NAME2, drawing);
    	// 通过 m00计算轮廓面积并且和OpenCV函数比较
    	printf("\t 输出内容:面积和轮廓长度\n");
    	for (unsigned int i = 0; i < g_vContours.size(); i++)
    	{
    		printf(" >通过m00计算出轮廓[%d]的面积:(M_00) = %,2f \n OpenCV函数计算出的面积=%.2f , 长度: %.2f \n\n", i, mu[i].m00,
    			contourArea(g_vContours[i]), arcLength(g_vContours[i], true));
    		Scalar color = Scalar(g_rng.uniform(0, 255),
    			g_rng.uniform(0, 255), g_rng.uniform(0, 255));
    		drawContours(drawing, g_vContours, i, color, 2, 8, g_vHierarchy, 0, Point());
    		circle(drawing, mc[i], 4, color, -1, 8, 0);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93

    在这里插入图片描述

  • 相关阅读:
    MySQL索引合并
    Java使用WebSocket(基础)
    Liunx 部署后端服务jar包脚本
    Redis 中常见的集群部署方案
    Python中的requests库日常使用教程
    React 在非组件环境切换路由
    【JavaEE】JavaScript(基础语法)1
    震惊!强大的接口自动化测试框架2.0,unittest与pytest无缝穿插对接,可以像postman一样编写代码
    副业该怎么选择,适合新手的四个副业项目,零基础也可操作的兼职
    分组后再子集再查询
  • 原文地址:https://blog.csdn.net/qq_46107892/article/details/133774414