RV1126 NO.40:OPENCV图形计算面积、弧长API讲解

一.OPENCV图形面积、弧长计算的API介绍

在之前的章节中,我们已经讲解了图形轮廓检测和画框功能。本章节我们将重点介绍如何利用轮廓检测API来计算图形面积,包括矩形、圆形等多种形状的面积计算。这些面积和弧长计算方法在车辆识别、桥梁识别等实际应用中起着重要作用。课程将涉及contourArea、arcLength、minAreaRect、boundingRect、rectangle、line等常用API的使用。

1.1.contourArea的API讲解

**contourArea**函数主要用于计算轮廓曲线包围的区域面积,即图像中目标物体的实际面积。如上图所示,该函数会计算白色区域的面积,其内部实现通常采用微积分等数学方法进行面积计算。

函数原型:

cpp 复制代码
CV_EXPORTS_W double contourArea(InputArray contour, bool oriented = false);

参数说明:

  • contour:输入轮廓的点集数据
  • oriented:可选参数,用于指定是否返回带方向的面积值(当设为true时,返回值可能为负数)

返回值: 返回计算得到的轮廓面积值(单位:像素)

1.2. arcLength的API讲解

arcLength 函数主要用于计算轮廓的周长,即图形边缘的曲线总长度。如下图所示,该函数通过计算轮廓点之间的连线长度来获取轮廓周长。

函数定义:

cpp 复制代码
CV_EXPORTS_W double arcLength(InputArray curve, bool closed);

参数说明:

  • curve:输入轮廓的2D像素点集
  • closed:布尔值,表示轮廓是否闭合(true表示闭合)

返回值: 计算得到的轮廓周长数值

1.3. minAreaRect的API讲解

minAreaRect的核心功能是计算最小外接矩形,即能够完全包含所有给定点的最小面积矩形。如图所示,数字"8"的形状被minAreaRect生成的矩形完美包围。这个矩形不仅能完整覆盖整个形状的所有点,还具有旋转特性 - 即使"8"存在倾斜角度,最小矩形也能准确贴合包裹。

cpp 复制代码
CV_EXPORTS_W RotatedRect minAreaRect( InputArray points );

第一个参数:points输入的二维点数,可以Mat类型也可以是std::vector的向量类型

返回值:RotatedRect 的矩形对象,它表示的是一个轮廓的最小外接矩形,我们来看看RotatedRect结构体成员变量

cpp 复制代码
template<typename _Tp> class Point_
{
public:
    typedef _Tp value_type;

    //! default constructor
    Point_();
    Point_(_Tp _x, _Tp _y);
    Point_(const Point_& pt);
    Point_(const Size_<_Tp>& sz);
    Point_(const Vec<_Tp, 2>& v);

    Point_& operator = (const Point_& pt);
    //! conversion to another data type
    template<typename _Tp2> operator Point_<_Tp2>() const;

    //! conversion to the old-style C structures
    operator Vec<_Tp, 2>() const;

    //! dot product
    _Tp dot(const Point_& pt) const;
    //! dot product computed in double-precision arithmetics
    double ddot(const Point_& pt) const;
    //! cross-product
    double cross(const Point_& pt) const;
    //! checks whether the point is inside the specified rectangle
    bool inside(const Rect_<_Tp>& r) const;
    _Tp x; //!< x coordinate of the point
    _Tp y; //!< y coordinate of the point
};

center: 旋转矩形的质心

****size:****旋转矩形的宽度和高度

****angle:****顺时针的旋转角度。

RotatedRect 矩形四个点的确定

在RotatedRect中,矩形的四个顶点通常用Point2f表示,其中p[0]点的确定尤为重要。p[0]的位置主要分为两种情况:

  1. 当最小外接矩形不与坐标轴平行时,Y坐标最大的点即为p[0],如图2、3、4所示
  2. 当最小外接矩形与坐标轴平行时,会有两个Y坐标最大的点,如图1所示

1.4. boundingRect的API讲解

boundingRect的核心功能是计算图形轮廓的最小垂直边界矩形,该矩形必须与图像的上下边界平行。如上图所示:我们仍以数字8的形状为例,它保持在原先的位置。boundingRect生成的矩形能够完整包围数字8的垂直边界。

cpp 复制代码
CV_EXPORTS_W Rect boundingRect( InputArray array );

第一个参数: array输入的灰度图像或者2D点集,数据类型为vector或者Mat矩阵数据

返回值:Rect的矩形对象,它表示的是物体轮廓的最大外接矩形。我们来看看Rect主要的成员变量

cpp 复制代码
template<typename _Tp> class Point_
{
public:
    typedef _Tp value_type;

    //! default constructor
    Point_();
    Point_(_Tp _x, _Tp _y);
    Point_(const Point_& pt);
    Point_(const Size_<_Tp>& sz);
    Point_(const Vec<_Tp, 2>& v);

    Point_& operator = (const Point_& pt);
    //! conversion to another data type
    template<typename _Tp2> operator Point_<_Tp2>() const;

    //! conversion to the old-style C structures
    operator Vec<_Tp, 2>() const;

    //! dot product
    _Tp dot(const Point_& pt) const;
    //! dot product computed in double-precision arithmetics
    double ddot(const Point_& pt) const;
    //! cross-product
    double cross(const Point_& pt) const;
    //! checks whether the point is inside the specified rectangle
    bool inside(const Rect_<_Tp>& r) const;
    _Tp x; //!< x coordinate of the point
    _Tp y; //!< y coordinate of the point
};

****x:****矩形的x坐标轴

y: 矩形的y坐标轴

****width:****矩形的宽度

****height:****矩形的高度

1.5. rectangle的API讲解

rectangle函数的作用是绘制矩形,它有两种表示形式

1.5.1. 以两个顶点的方式画矩形
cpp 复制代码
void cv::rectangle(InputOutputArray img, Point pt1, Point pt2, const Scalar & color, int  thickness = 1,int  lineType = LINE_8, int  shift = 0)

****第一个参数:****输入的矩阵图像数据

****第二个参数:****pt1是矩形的一个顶点,左上角的顶点

****第三个参数:****pt2矩形中与pt1相对的顶点,也就是两个点在对角线上,也就是右下角的顶点

****第四个参数:****Scalar颜色的标量

****第五个参数:****thickness线宽

****第六个参数:****lineType线的类型,默认是LINE_8就行,具体的类型如下代码:

cpp 复制代码
//! type of line
enum LineTypes {
    FILLED  = -1,
    LINE_4  = 4, //!< 4-connected line
    LINE_8  = 8, //!< 8-connected line
    LINE_AA = 16 //!< antialiased line
};

****第七个参数:****shift坐标的小数点位,默认为0就可以

1.5.2.以Rect的方式画矩形
cpp 复制代码
void cv::rectangle(InputOutputArray img, Rect rec, const Scalar & color, int thickness = 1,int  lineType = LINE_8, int  shift = 0)   

****第一个参数:****输入的矩阵图像数据

****第二个参数:****Rect的结构体,我们来看看这个Rect的重要成员变量

cpp 复制代码
template<typename _Tp> class Rect_
{
public:
    typedef _Tp value_type;

    //! default constructor
    Rect_();
    Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height);
    Rect_(const Rect_& r);
    Rect_(const Point_<_Tp>& org, const Size_<_Tp>& sz);
    Rect_(const Point_<_Tp>& pt1, const Point_<_Tp>& pt2);

    Rect_& operator = ( const Rect_& r );
    //! the top-left corner
    Point_<_Tp> tl() const;
    //! the bottom-right corner
    Point_<_Tp> br() const;

    //! size (width, height) of the rectangle
    Size_<_Tp> size() const;
    //! area (width*height) of the rectangle
    _Tp area() const;
    //! true if empty
    bool empty() const;

    //! conversion to another data type
    template<typename _Tp2> operator Rect_<_Tp2>() const;

    //! checks whether the rectangle contains the point
    bool contains(const Point_<_Tp>& pt) const;

    _Tp x; //!< x coordinate of the top-left corner
    _Tp y; //!< y coordinate of the top-left corner
    _Tp width; //!< width of the rectangle
    _Tp height; //!< height of the rectangle
};

x:矩形的x坐标轴

y: 矩形的y坐标轴

****width:****矩形的宽度

****height:****矩形的高度

****第三个参数:****Scalar颜色的标量

****第四个参数:****thickness线宽,默认是1

****第五个参数:****lineType线的类型,默认是LINE_8就行,line的类型如下:

cpp 复制代码
//! type of line
enum LineTypes {
    FILLED  = -1,
    LINE_4  = 4, //!< 4-connected line
    LINE_8  = 8, //!< 8-connected line
    LINE_AA = 16 //!< antialiased line
};

****第六个参数:****shift坐标点的小数点位数

1.6. line的API讲解

line函数的主要作用是通过两个点绘制直线

cpp 复制代码
CV_EXPORTS_W void line(InputOutputArray img, Point pt1, Point pt2, const Scalar& color,int thickness = 1, int lineType = LINE_8, int shift = 0);

****第一个参数:****输入的矩阵图像数据

第二个参数: pt1是线的起始坐标,也就是图上x1坐标和y1坐标
****第三个参数:****pt2是线的终点坐标,也就是图上x2坐标和y2坐标

第四个参数: Scalar是颜色标量,绘制直线的颜色
****第五个参数:****thickness它是线的粗细程度,默认为1

****第六个参数:****lineType线的类型,默认是LINE_8就行,具体的类型

****第七个参数:****shift坐标点的小数点位数

1.7. threshold的API讲解

threshold主要用途是把图像进行二值化处理,二值化操作可以使图像中的数据量大大降低图像的复杂度,并且能够凸显出图像中的轮廓。

cpp 复制代码
CV_EXPORTS_W double threshold( InputArray src, OutputArray dst, double thresh, double maxval, int type );

第一个参数: src源图像,可以是8位灰度图,也可以是32位的三通道图像
****第二个参数:****dst目标图像

第三个参数: thres h 阈值
第四个参数:maxval 二值图像中灰度最大值,maxval只能在THRESH_BINARYTHRESH_BINARY_INV 有用,但是其他选项也需要填这个值,不能空着。
第五个参数:type阈值操作类型,具体的阈值操作如下图:

THRESH_BINARY:二值化阈值处理将图像转换为仅包含两个灰度值的二值图像。具体规则为:当像素灰度值超过设定阈值时,将其设为最大值(maxval);若像素灰度值不高于阈值,则将其置为0。

THRESH_BINARY_INV(反二值化阈值处理)同样会将图像转换为二值图像,但其处理逻辑与THRESH_BINARY相反。具体表现为:

  1. 当像素灰度值大于阈值时,该像素值设为0
  2. 当像素灰度值小于或等于阈值时,该像素值设为预设的最大值(maxval)

THRESH_TRUNC(截断阈值化)是一种图像处理方法,其规则如下:

  1. 对于像素值超过设定阈值的点,将其值设为该阈值
  2. 对于像素值小于或等于阈值的点,保持原值不变

例如设定阈值为127时:

  • 像素值大于127的点会被设为127
  • 像素值≤127的点保持不变

THRESH_TOZERO_INV 是一种阈值处理方式,其规则如下:

  1. 当像素值大于设定阈值时,将该像素置为0
  2. 当像素值小于或等于阈值时,保持原值不变

例如设定阈值为127时:

  • 像素值>127 → 置为0
  • 像素值≤127 → 保持原值

THRESH_TOZERO阈值处理:当像素值小于或等于设定阈值时,该像素将被置零;高于阈值的像素则保持原值。例如设定阈值为127时,所有≤127的像素会被归零,而>127的像素则保留原始数值。

THRESH_OTSU:OTSU方法会遍历所有可能的阈值,从而找到一个最佳的阈值。值得注意的是,在使用OTSU方法的时候需要把阈值设定为0。这个时候,threshold会自动寻找最优的值。

相关推荐
极客学术工坊4 小时前
2023年第二十届五一数学建模竞赛-A题 无人机定点投放问题-基于抛体运动的无人机定点投放问题研究
人工智能·机器学习·数学建模·启发式算法
Theodore_10225 小时前
深度学习(9)导数与计算图
人工智能·深度学习·机器学习·矩阵·线性回归
PPIO派欧云6 小时前
PPIO上新GPU实例模板,一键部署PaddleOCR-VL
人工智能
TGITCIC8 小时前
金融RAG落地之痛:不在模型,而在数据结构
人工智能·ai大模型·ai agent·ai智能体·开源大模型·金融ai·金融rag
chenzhiyuan201811 小时前
《十五五规划》下的AI边缘计算机遇:算力下沉与工业智能化
人工智能·边缘计算
whaosoft-14311 小时前
51c深度学习~合集11
人工智能
Tiandaren11 小时前
大模型应用03 || 函数调用 Function Calling || 概念、思想、流程
人工智能·算法·microsoft·数据分析
领航猿1号12 小时前
Pytorch 内存布局优化:Contiguous Memory
人工智能·pytorch·深度学习·机器学习
综合热讯12 小时前
宠智灵宠物识别AI:从犬猫到鸟鱼的全生态智能识别
人工智能·宠物