opencv contourArea()计算轮廓面积偏小问题,及问题解决方法

问题描述:利用opencv 库函数contourArea()计算轮廓面积得到的面积比实际面积小的原因,及其求精确面积方法。

opencv contourArea()使用方法:

#include <opencv2/opencv.hpp>  
#include <iostream>  
  
using namespace cv;  
using namespace std;  
  
int main() {  
    Mat image = imread("example.jpg", IMREAD_GRAYSCALE); // 读取灰度图像  
    if (image.empty()) {  
        cout << "Could not read the image." << endl;  
        return -1;  
    }  
  
    vector<vector<Point>> contours; // 存储轮廓的向量  
    findContours(image, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE); // 查找轮廓  
  
    double area = 0; // 轮廓面积  
    for (size_t i = 0; i < contours.size(); i++) {  
        area += contourArea(contours[i]); // 计算轮廓面积  
    }  
  
    cout << "Total contour area: " << area << endl; // 输出轮廓面积  
  
    return 0;  
}

如图所示,以求一个半径为10的圆面积为例:

利用contourArea()提取圆的外轮廓,计算外轮廓面积为:288

利用圆面积公式计算圆的面积为:10*10*3.14=314

原因分析:

contourArea()面积计算原理,如下图所示:

利用contourArea()计算轮廓面积实际为轮廓中心点所围成虚拟轮廓的面积,而非实际轮廓面积。

解决方法:

方法1:

使用drawContours函数将轮廓绘制到空白图像上,然后使用countNonZero函数统计非零像素的数量。下面是示例代码:

#include <opencv2/opencv.hpp>  
  
using namespace cv;  
  
int main() {  
    // 读取图像并转换为灰度图像  
    Mat image = imread("image.jpg");  
    Mat gray;  
    cvtColor(image, gray, COLOR_BGR2GRAY);  
  
    // 检测轮廓并绘制到空白图像上  
    vector<vector<Point>> contours;  
    findContours(gray, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);  
    Mat drawing = Mat::zeros(image.size(), CV_8UC3);  
    for (int i = 0; i < contours.size(); i++) {  
        drawContours(drawing, contours, i, Scalar(255, 255, 255), 1);  
    }  
  
    // 统计非零像素的数量  
    int count = countNonZero(drawing);  
    cout << "Number of pixels in contours: " << count << endl;  
  
    return 0;  
}

方法1 ,计算圆面积为317,与原实际面积314相差3

方法2:

利用contourArea()函数计算面积,加上轮廓周长的一半,

轮廓精确周长就算方法见:微信用户:opencv ArcLength()计算轮廓周长偏大问题,及解决办法

c++代码示例:

#include<opencv2//opencv.hpp>
#include<math.h>

using namespace std;
using namespace cv;

int main()
{
	Mat img = Mat::zeros(Size(300,300), CV_8UC1);
	circle(img,Point(150,150),10,Scalar(255),-1);
	vector<vector<Point>>contours;
	findContours(img, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE);
	double  a=contourArea(contours[0]);
	float  b = arcLength(contours[0],true);
        vector<Point>contours_poly;
	approxPolyDP(contours[0], contours_poly, 1, true);
	float  d = arcLength(contours_poly, true);
	float circle_area = a + d / 2;
	cout << circle_area << endl;
	return 0;
}

方法2 ,计算圆面积为318,与原实际面积314相差4

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值