OpenCV图像处理——轮廓的面积与弧长计算(C++/Python)

news2024/9/22 10:22:51

概述

轮廓面积与轮廓周长是图像分析中的两项核心统计特征,它们为理解和量化图像中的形状提供了基础。

  1. 轮廓面积:这代表了轮廓所界定区域的像素数量,是衡量区域大小的直接指标。面积的计算结果以像素平方为单位,为我们提供了一个量化的尺度来比较不同物体的相对大小。

  2. 轮廓周长:它反映了轮廓边界的总长度,以像素为单位。周长是描述形状复杂度和边界长度的关键参数,对于评估物体的形状和轮廓的平滑度或不规则性至关重要。

通过对这些特征的细致分析,我们能够实现以下目标:

  • 物体大小区分:通过比较物体的面积和周长,我们可以区分不同尺寸的物体,筛选出符合特定大小标准的物体。

  • 形状识别:不同形状的物体具有独特的面积与周长比。例如,对于正方形,周长与面积的比值是常数,而圆形的周长与面积之间遵循特定的数学关系。

  • 几何属性推断:利用面积和周长之间的固定数学关系,我们可以对物体的几何属性进行推断,比如判断物体是否接近于理论的几何形状。

  • 异常检测与分析:如果物体的面积与周长比例显著偏离预期,这可能揭示了物体的异常或变形,为进一步的分析提供了线索。

  • 模式识别与机器学习:在这些领域中,轮廓的面积和周长可以作为特征向量的一部分,辅助算法进行更准确的物体分类和识别。

OpenCV对轮廓点集计算面积的API函数如下:

double cv::contourArea(
    InputArray 	contour,
    bool oriented = false
)

计算轮廓的面积,其原理是基于格林公式。

参数contour表示输入的轮廓点集
参数oriented默认是false返回的面积是正数,如果方向参数为true表示会根据是顺时针或者逆时针方向返回正值或者负值面积。

OpenCV对轮廓点集计算弧长的API函数如下:

double cv::arcLength(
    InputArray curve,
    bool closed 
)

参数curve表示输入的轮廓点集
参数closed默认表示是否闭合区域

C++实现

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

using namespace std;
using namespace cv;

int main() 
{
    Mat src = imread("12.jpg");
    if (src.empty()) 
    {
        cout << "could not load image.." << endl;
    }
    cv::namedWindow("src", 0);
    imshow("src", src);

    // 提取边缘
    Mat binary;
    Canny(src, binary, 80, 160);

    cv::namedWindow("binary", 0);
    cv::imshow("binary", binary);

    // 膨胀
    Mat k = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
    dilate(binary, binary, k);

    // 轮廓发现于绘制
    vector<vector<Point>> contours;
    vector<Vec4i> hierarchy;
    findContours(binary, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
    for (size_t t = 0; t < contours.size(); ++t) 
    {
        // 最大外接矩形
        // Rect rect = boundingRect(contours[t]);
        // rectangle(src, rect, Scalar(0, 0, 255));

        // 面积与弧长过滤
        double area = contourArea(contours[t]);
        double curvelen = arcLength(contours[t], true);
        if (area < 100 || curvelen < 100) 
        {
            continue;
        }

        // 最小外接矩形
        RotatedRect rrt = minAreaRect(contours[t]);
        Point2f pts[4];
        rrt.points(pts);

        // 绘制旋转矩形与中心位置
        for (int i = 0; i < 4; ++i) 
        {
            line(src, pts[i % 4], pts[(i + 1) % 4], Scalar(0, 255, 0), 2);
        }
        Point2f cpt = rrt.center;
        circle(src, cpt, 2, Scalar(255, 0, 0), 2);
    }

    cv::namedWindow("contours", 0);
    cv::imshow("contours", src);

    waitKey(0);
    return 0;
}

在这里插入图片描述

Python 实现

import cv2 as cv
import numpy as np


def canny_demo(image):
    t = 80
    canny_output = cv.Canny(image, t, t * 2)
    cv.imshow("canny_output", canny_output)
    cv.imwrite("D:/canny_output.png", canny_output)
    return canny_output


src = cv.imread("D:/images/zhifang_ball.png")
cv.namedWindow("input", cv.WINDOW_AUTOSIZE)
cv.imshow("input", src)
binary = canny_demo(src)
k = np.ones((3, 3), dtype=np.uint8)
binary = cv.morphologyEx(binary, cv.MORPH_DILATE, k)

# 轮廓发现
out, contours, hierarchy = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
for c in range(len(contours)):
    # x, y, w, h = cv.boundingRect(contours[c]);
    # cv.drawContours(src, contours, c, (0, 0, 255), 2, 8)
    # cv.rectangle(src, (x, y), (x+w, y+h), (0, 0, 255), 1, 8, 0);
    area = cv.contourArea(contours[c])
    arclen = cv.arcLength(contours[c], True)
    if area < 100 or arclen < 100:
        continue
    rect = cv.minAreaRect(contours[c])
    cx, cy = rect[0]
    box = cv.boxPoints(rect)
    box = np.int0(box)
    cv.drawContours(src,[box],0,(0,0,255),2)
    cv.circle(src, (np.int32(cx), np.int32(cy)), 2, (255, 0, 0), 2, 8, 0)


# 显示
cv.imshow("contours_analysis", src)
cv.imwrite("D:/contours_analysis.png", src)
cv.waitKey(0)
cv.destroyAllWindows()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2042124.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Wireshark_DNS_v7.0

Wireshark_DNS_v7.0 一、 nslookup 前置 nslookup 是一个网络命令行工具&#xff0c;用于查询域名系统&#xff08;DNS&#xff09;中的域名解析记录。通过使用 nslookup&#xff0c;你可以获取某个域名的IP地址&#xff0c;或者获取与某个IP地址关联的域名信息。 查看域名…

学校医院NTP电子钟让时间管理更加智能

在学校和医院这样的重要场所&#xff0c;时间的精确管理至关重要。每一分每一秒都可能关系到教学的进度、医疗的效果以及师生和患者的体验。而 NTP 电子钟的出现&#xff0c;为学校和医院的时间管理带来了全新的智能化变革。 一、NTP 电子钟在学校应用 NTP 电子钟&#xff0c;…

【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第五篇 文件系统构建篇-第七十八章 离线构建Yocto系统

i.MX8MM处理器采用了先进的14LPCFinFET工艺&#xff0c;提供更快的速度和更高的电源效率;四核Cortex-A53&#xff0c;单核Cortex-M4&#xff0c;多达五个内核 &#xff0c;主频高达1.8GHz&#xff0c;2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…

【HarmonyOS】鸿蒙应用蓝牙功能实现 (一)

【HarmonyOS】鸿蒙应用蓝牙功能实现 前言 蓝牙技术是一种无线通信技术&#xff0c;可以在短距离内传输数据。它是由爱立信公司于1994年提出的&#xff0c;使用2.4 GHz的ISM频段&#xff0c;可以在10米左右的距离内进行通信。可以用于连接手机、耳机、音箱、键盘、鼠标、打印机…

工厂流水线MES报工一体机改善生产管理效率

作为智能制造的重要组成部分&#xff0c;MES系统&#xff08;制造执行系统&#xff09;在优化生产流程、提高生产效率、降低生产成本等方面发挥着不可替代的作用。而MES报工一体机作为MES系统的重要组成部分&#xff0c;更是帮助企业实现生产管理效率提升的利器。 一、MES报工一…

为何有了云计算,还需要边缘计算?EasyCVR视频平台助力数据高效汇聚与管理

在当今数字化的时代&#xff0c;云计算可谓是大名鼎鼎&#xff0c;它为我们的生活和工作带来了巨大的便利。但你有没有想过&#xff0c;既然有了强大的云计算&#xff0c;为什么还会出现边缘计算呢&#xff1f; 一、云计算与边缘计算&#xff1a;相辅相成的科技双雄 先来说说…

船员考证题库刷题

1、船舶主配电板系统&#xff0c;设有地气灯、配电板式兆欧表和低绝缘报警装置&#xff0c;及船舶照明分配电箱&#xff0c;当发生单相接地故障时而进行排查时&#xff0c;______设备是不能随意断电的。 A、厨房用电 B、卫星基站 C、起重机用电 答案&#xff1a;B 2、燃油…

修复或更换:螺杆机支撑座磨损后的处理选择

螺杆机后端支撑座磨损&#xff0c;主要是由于长期使用&#xff0c;润滑不足或使用劣质润滑油等原因导致的。当螺杆机支撑座出现磨损时&#xff0c;其承载能力会逐渐下降&#xff0c;加速磨损&#xff0c;导致设备运行不稳定&#xff0c;噪音增大&#xff0c;严重时还会导致设备…

老照片一键修复怎么做?6个软件帮助你快速进行老照片修复

老照片一键修复怎么做&#xff1f;6个软件帮助你快速进行老照片修复 老照片修复可以让陈旧、褪色或损坏的照片恢复到原有的光彩和清晰度。以下是六款方便好用的软件&#xff0c;能够帮助你快速进行老照片修复&#xff0c;且许多都支持一键操作。 智能修复老照片 这是一款专…

【Linux】守护进程:containerd的使用教程

这里写目录标题 前言一. ctr1.1 ctr CLI1.2 ctr 调试 二、 创建 container2.1 进入 NewContainer2.2 ContainerService().Create 前言 介绍了 kubelet 通过 cri 接口和 containerd 交互的过程&#xff0c;containerd 源码分析&#xff1a;启动注册流程 介绍了 containerd 作为…

屏幕防拍照技术:防止屏幕被拍照的方法有哪些?答案超乎想象!

“防身立命&#xff0c;安内攘外。” 在数字化时代&#xff0c;信息安全已成为企业乃至个人不可忽视的重要议题。 屏幕作为信息展示的主要窗口&#xff0c;其安全性尤为关键。 然而&#xff0c;随着拍照技术的日益普及与精进&#xff0c;屏幕内容被轻易捕捉并泄露的风险也随…

暗区突围辅助攻略:VMOS云手机硬核辅助!农场地图攻略大全!

在《暗区突围》中&#xff0c;了解地图和撤离点的分布对于游戏的胜利至关重要。使用VMOS云手机进行游戏辅助&#xff0c;可以为你带来显著的优势。VMOS云手机专门针对《暗区突围》进行了定制&#xff0c;内置游戏安装包&#xff0c;无需重新下载安装游戏。它能够实现24小时云端…

您看这篇就够了:ComfyUI 新手指南

欢迎来到 ComfyUI 的神奇世界&#xff0c;这是 Stable Diffusion 的一个强大而灵活的图形用户界面。无论你是数字艺术的新手&#xff0c;还是希望将你的图像创作提升到新高度的老手&#xff0c;ComfyUI 都能满足你的需求。在这篇全面的指南中&#xff0c;我们将带你穿越 ComfyU…

初识C++ · IO流

前言&#xff1a; IO流&#xff0c;启动&#xff01;因笔者对于IO流的理解不是很深刻&#xff0c;所以这里进行简单的介绍即可。 1 IO流 IO流是我们从学习C开始就一直会使用的东西&#xff0c;我们先了解一下CIO流的一套继承体系&#xff1a; 整个IO体系的基类是ios_base&…

ArkTs基础语法

ArkTs基础语法 声明变量声明常量声明自动类型推断 类型基础类型NumberBooleanString 引用类型VoidObjectArrayEnumUnionAliases 语句if语句switch语句条件表达式 ?:for语句for of语句while语句do while语句breakcontinuethrow和try catch finally语句 函数函数声明可选参数Res…

MySQL中的锁事

一、概述 锁是计算机在执行多线程或线程时用于并发访问同一共享资源时的同步机制&#xff0c;MySQL中的锁是在服务器层或者存储引擎层实现的&#xff0c;保证了数据访问的一致性与有效性。 事务的隔离性是由的锁来实现。 二、MySQL并发事务访问的问题 我们已经知道事务并发…

day-39 矩阵中的最大得分

思路 动态规划。利用一个二维数组记录对应位置可以达到的最高得分&#xff08;位置&#xff08;0,0&#xff09;不可能&#xff09;&#xff0c;然后找出最大值即可&#xff08;如果除了&#xff08;0,0&#xff09;上的值其他值都一样&#xff0c;则返回任意一个即可&#xff…

Python 3 入门基础知识 之数据容器及用法【2】 推荐

前面关于python的下载安装、如何定义变量&#xff0c;基本的数据类型&#xff0c;以及if条件语句、for循环语句&#xff0c;部分运算都进行了梳理总结。参考&#xff1a;Python 3 入门基础知识【1】数据类型 安装下载 推荐-CSDN博客 这里回顾一下python的数据容器基础知识&…

智能换热:图扑智慧供热可视化管理平台

图扑搭建智慧供热可视化管理平台&#xff0c;通过实时监控和数据分析提升运营效率&#xff0c;实现智能化管理&#xff0c;保障系统稳定与高效运行。

深挖Redis分布式缓存:你还在为缓存架构感到困惑吗?灵办AI为你揭开文献背后的秘密!

文章目录 1 灵办AI插件2 翻译~外文文献3 解释~文献标题分析4 文档解析~文献总结5 搜索~全网搜索总结6 总体评价~文献代码分析总结 本文将引用 Research and Application of Distributed Cache Based on Redis [1] 外文文献解读为案例进行剥削&#xff0c;进而提高对 Redis的分布…