当前位置: 首页 > article >正文

加强版 第六节 图像轮廓几何属性分析

轮廓面积与周长

最大/最小外接矩形

boundingrect

boundingRect主要用于计算轮廓(contour)的边界矩形。轮廓通常是由一系列的点构成的曲线,通过这个函数可以得到一个能够刚好包围这个轮廓的最小矩形。这个矩形是一个直立(非旋转)的矩形。

它的语法一般是cv2.boundingRect(array),参数array通常是一个轮廓点的数组(例如通过findContours函数得到的轮廓)。返回值是一个包含四个值的元组,分别是矩形左上角的x坐标、y坐标,以及矩形的宽度和高度((x, y, w, h))。

例如,在目标检测或者物体识别场景中,当你已经通过边缘检测等方式获得了物体的轮廓后,使用boundingRect可以快速确定物体在图像中的位置和大小范围,方便后续进一步处理,比如提取物体所在区域的图像块等。

RotatedRect

1. 定义与用途

• 在OpenCV中,RotatedRect(旋转矩形)是一个用于表示旋转后的矩形的数据结构。与boundingRect返回的非旋转矩形不同,RotatedRect可以更好地贴合具有一定角度的物体轮廓,尤其在处理倾斜物体时非常有用。

2. 结构成员

• 它主要包含三个成员:中心坐标(center),表示旋转矩形的中心位置,是一个Point2f类型(包含x和y坐标);尺寸(size),是一个Size2f类型,用于表示矩形的宽度和高度;旋转角度(angle),是一个浮点数,表示矩形相对于水平方向的旋转角度,以逆时针方向为正。

3. 获取旋转矩形的方式

• 例如,使用minAreaRect函数可以获取轮廓的最小旋转包围矩形。假设contours是通过findContours函数得到的轮廓集合,对于其中的一个轮廓contours[i],可以这样获取其旋转包围矩形:
RotatedRect rotated_rect = minAreaRect(contours[i]);
4. 绘制旋转矩形

• 要绘制旋转矩形,可以使用Point2f数组来获取矩形的四个顶点,然后用line函数逐个连接顶点来绘制。以下是一个简单的示例代码片段:
RotatedRect rotated_rect = minAreaRect(contours[i]);
Point2f vertices[4];
rotated_rect.points(vertices);
for (int j = 0; j < 4; j++)
{
    line(src, vertices[j], vertices[(j + 1) % 4], Scalar(0, 255, 0), 2);
}
• 这里src是目标图像,Scalar(0, 255, 0)是绘制线条的颜色(绿色),2是线条的宽度。points函数用于获取旋转矩形的四个顶点,然后通过循环连接这些顶点来绘制旋转矩形。

ellipse

在 OpenCV 中,ellipse函数用于绘制椭圆。

一、函数语法

void ellipse(InputOutputArray img, Point center, Size axes, double angle, double startAngle, double endAngle, const Scalar& color, int thickness = 1, int lineType = LINE_8, int shift = 0);

二、参数解释

    1.    img:要在其上绘制椭圆的图像。

    2.    center:椭圆的中心坐标。

    3.    axes:椭圆的长轴和短轴长度,以Size(w, h)的形式给出,其中w是长轴的一半长度,h是短轴的一半长度。

    4.    angle:椭圆的旋转角度,以度为单位。

    5.    startAngle:椭圆弧的起始角度,以度为单位。

    6.    endAngle:椭圆弧的结束角度,以度为单位。

    7.    color:椭圆的颜色。

    8.    thickness:椭圆轮廓的线宽。如果为负数,则绘制实心椭圆。

    9.    lineType:线条类型,如LINE_8、LINE_4等。

    10.    shift:坐标点的小数位数。
 



首先计算每个关键像素点的面积和周长方便后续的操作

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;
int main(int argc, char** argv) {
    Mat sqw, swe, ser;
    Mat src = imread("C:/newword/image/5.png");
    if (src.empty()) {
        printf("no");
        return -1;
    }
    namedWindow("abc", WINDOW_AUTOSIZE);
    GaussianBlur(src,sqw,Size(3,3),0);
    cvtColor(sqw, swe, COLOR_BGR2GRAY);
    threshold(swe, ser, 0, 255, THRESH_BINARY | THRESH_OTSU);
    imshow("abc", ser);
    vector<vector<Point>>sky;
    vector<Vec4i>sea;
    findContours(ser, sky, sea, RETR_TREE, CHAIN_APPROX_SIMPLE, Point());
    for (size_t t = 0; t < sky.size(); t++) {
        double are = contourArea(sky[t]);计算每个轮廓的面积
        double len = arcLength(sky[t],true);计算每个轮廓的周长,是否为封闭图形
        if (are > 150 || len < 40)continue;
        printf("are:=%.2f,len:=%.2f\n",are, len);
        
        drawContours(src, sky, -1, Scalar(0, 0, 255), 2, 8);
    }

        
    
    imshow("abcd", src);
    waitKey(0);
    return 0;


}



绘制最小直立外接矩形

double are = contourArea(sky[t]);
double len = arcLength(sky[t],true);
if (are < 50 || len < 40)continue;
printf("are:=%.2f,len:=%.2f\n",are, len);
Rect box = boundingRect(sky[t]);
rectangle(src, box, Scalar(0, 255, 0), 2, 8,0);



绘制外接(重要的是rotaedrect这个函数)

RotatedRect min_area = minAreaRect(sky[t]);
ellipse(src, min_area, Scalar(0, 0, 255), 2, 8);



之后就是带有角度的最小外接矩形

RotatedRect min_area = minAreaRect(sky[t]);
//ellipse(src, min_area, Scalar(0, 0, 255), 2, 8);
Point2f pts[4];//四个点的格式为Point2f
min_area.points(pts);
for (int i = 0; i < 4; i++) {
    line(src, pts[i], pts[(i + 1) % 4], Scalar(0, 0, 255), 2, 8);
}


http://www.kler.cn/a/378559.html

相关文章:

  • 火山引擎VeDI数据服务平台:在电商场景中,如何解决API编排问题?
  • 优选算法精品——双指针
  • 【Java知识】java进阶-一个好用的java应用分析工具arthas
  • 哔哩哔哩车机版2.7.0|专为司机打造的车机版B站,内容丰富,功能齐全
  • Docker使用复习(11.3)
  • Puppeteer点击系统:解锁百度流量点击率提升的解决案例
  • 无人机维修培训班开班课程技术详解
  • 「Mac畅玩鸿蒙与硬件17」鸿蒙UI组件篇7 - Animation 组件基础
  • npm入门教程17:准备发布的npm包
  • 家具制造的效率与美观并重,玛哈特矫平机让家具产品更具竞争力。
  • 2024前端面试训练计划-高频题-网络基础篇
  • QT中TextEdit或者QLineEdit以十六进制显示数组数据
  • uni-app 下拉刷新、 上拉触底(列表信息)、 上滑加载(短视频) 一键搞定
  • nginx配置转发到elk的kibana的服务器
  • 【开发工具——依赖管理工具——Maven】
  • unity c# Tcp网络通讯
  • C++ 函数调用时的参数传递方法
  • 线性数据结构之队列
  • 【读书笔记/深入理解K8S】集群控制器
  • 《GBDT 算法的原理推导》 11-15更新决策树的叶子节点值 公式解析
  • mac 系统下载 vscode
  • 如何设置使PPT的画的图片导出变清晰
  • 自动驾驶-端到端大模型
  • 三层交换实现不同VLAN之间设备的互通
  • SQL 常用语句
  • 【系统架构设计师】2024年上半年真题论文: 论云上自动化运维级其应用(包括解题思路和素材)