RV1126 NO.41:利用OPENCV的API计算轮廓面积
一.计算常见的图形形状的面积DEMO
本节将介绍如何使用OpenCV计算各种图形的面积,包括矩形、三角形和圆形等。在代码示例中,我们将结合之前学习的轮廓检测技术和面积计算API,演示如何计算矩形的多种面积类型:轮廓面积、最小外接矩形面积以及垂直边界面积。
二.计算矩形面积的大体流程
计算矩形面积的主要步骤如下:
- 读取图像
- 灰度化处理
- 二值化处理
- 通过findContours函数提取轮廓
- 遍历轮廓并使用contourArea计算每个轮廓面积
- 计算最小外接矩形面积(minAreaRect)
- 计算边界垂直矩形面积(boundingRect)
具体流程如下图所示:

三.代码的实现DEMO
3.1. 调用OPENCV读取需要计算的图片
Mat src = imread("soc.png");//读取ten这张图片第一步,调用imread读取我们需要处理的图片,这里我们选择的图片是soc这个图片。
3.2. 对图片进行灰度操作
cvtColor(src, gray, COLOR_RGB2GRAY);//对图片进行灰度处理读取完图片之后,使用cvtColor把三通道的彩色图像转换成单通道(COLOR_RGB2GRAY)的灰度图。
3.3. 对灰度图进行二值操作
threshold(gray, bin_img, 150, 255, THRESH_BINARY_INV);//二值化处理阈值150,最大值255,THRESH_BINARY_INV完成灰度处理后,我们需要使用OpenCV的threshold函数对图像进行二值化操作,以获得更清晰的图像便于后续识别和计算。这里设置的参数如下:阈值为150,最大阈值为255,采用THRESH_BINARY_INV模式(该模式会将背景转为黑色,数字转为白色,有利于数字面积的计算)。具体处理规则是:当像素值超过150时设为0,否则设为255。

3.4. 查找二值图像中的所有轮廓
vector<vector<Point>> contours;// 存储轮廓点的向量(每个轮廓由连续点集构成)
findContours(bin_img, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE);//查询轮廓调用findContours去查找整个二值图像的轮廓,由于我们读取的图片没有嵌套的轮廓,所以我们选择RETR_EXTERNAL的模式只查找外部轮廓,轮廓的近似方法是CV_CHAIN_APPROX_NONE来保存边界上所有连续的轮廓点。
3.5. 循环轮廓数量来计算图像轮廓的最小外接矩形的面积
for (int i = 0; i < contours.size(); i++){RotatedRect minRect = minAreaRect(contours[i]);//通过minAreaRect找到最小外接矩形// 获取旋转矩形的四个顶点坐标(按顺时针顺序)minRect.points(pts);// 在原图上绘制旋转矩形的四条边(黑色,线宽3)line(src, pts[0],pts[1],Scalar(0),3);//用line连接p[0]->p[1]line(src, pts[1],pts[2],Scalar(0),3);//用line连接[p1]->p[2]line(src, pts[2],pts[3],Scalar(0),3);//用line连接p[2]->p[3]line(src, pts[3],pts[0],Scalar(0),3);//用line连接p[3]->p[0]这段代码采用循环轮廓的方式计算最小外接矩形,调用minAreaRect函数在二值图像中定位最小矩形区域,并使用line函数绘制矩形(如图1所示)。如图所示,矩形的四个顶点(以Point2f类型存储的p[0]至p[3])按照p[0]->p[1]、p[1]->p[2]、p[2]->p[3]、p[3]->p[0]的顺序连接形成完整矩形。最小矩形面积的计算公式为:矩形宽度乘以高度,对应代码实现为int minRectArea = rects.size.width * rects.size.height。

3.6. 循环轮廓数量来计算图像轮廓的最小垂直矩形面积
Rect bArea = boundingRect(contours[i]);//调用boundingRect查找边界矩形int boundingArea = bArea.width * bArea.height;//计算边界矩形面积rectangle(src, bArea, Scalar(255,255,0));//rectangle矩形画框printf("boundingArea = %d\n", boundingArea);该代码通过遍历轮廓数量来计算最小外接矩形。首先调用boundingRect函数获取二值图像中轮廓的最小垂直矩形,然后使用rectangle函数绘制矩形框。其中,最小垂直矩形面积的计算公式为:矩形宽度乘以高度,即代码中的int boundingArea = rect.width * rect.height。

3.7. 循环轮廓数量来计算图像轮廓的面积
double cArea = contourArea(contours[i]);//计算轮廓面积
printf("contourArea = %lf\n", cArea);这部分代码就是通过循环轮廓数量来计算轮廓的面积,通过contourArea来计算轮廓的面积。
完整代码:
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>using namespace cv;
using namespace std;int main()
{Mat src = imread("soc.png");//读取ten这张图片Mat gray, bin_img;cvtColor(src, gray, COLOR_RGB2GRAY);//对图片进行灰度处理threshold(gray, bin_img, 150, 255, THRESH_BINARY_INV);//二值化处理阈值150,最大值255,THRESH_BINARY_INVvector<vector<Point>> contours;// 存储轮廓点的向量(每个轮廓由连续点集构成)findContours(bin_img, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE);//查询轮廓Point2f pts[4];// 存储矩形顶点的数组for (int i = 0; i < contours.size(); i++){RotatedRect minRect = minAreaRect(contours[i]);//通过minAreaRect找到最小外接矩形// 获取旋转矩形的四个顶点坐标(按顺时针顺序)minRect.points(pts);// 在原图上绘制旋转矩形的四条边(黑色,线宽3)line(src, pts[0],pts[1],Scalar(0),3);//用line连接p[0]->p[1]line(src, pts[1],pts[2],Scalar(0),3);//用line连接[p1]->p[2]line(src, pts[2],pts[3],Scalar(0),3);//用line连接p[2]->p[3]line(src, pts[3],pts[0],Scalar(0),3);//用line连接p[3]->p[0]int minArea = minRect.size.width * minRect.size.height;printf("minArea = %d\n", minArea);Rect bArea = boundingRect(contours[i]);//调用boundingRect查找边界矩形int boundingArea = bArea.width * bArea.height;//计算边界矩形面积rectangle(src, bArea, Scalar(255,255,0));//rectangle矩形画框printf("boundingArea = %d\n", boundingArea);double cArea = contourArea(contours[i]);//计算轮廓面积printf("contourArea = %lf\n", cArea);}imwrite("area.jpg", src);return 0;
}
输出的结果:

结果显示为两部分:左图展示了数字10的最小外接矩形和最小垂直矩形,并输出为area.jpg;右图则呈现了边界垂直矩形面积(boundingArea)、最小外接矩形面积(minArea)和轮廓面积(contourArea)等相关数据信息。
