OpenCV:图像轮廓

embedded/2025/2/6 23:11:11/

目录

简述

1. 什么是图像轮廓?

2. 查找图像轮廓

2.1 接口定义

2.2 参数说明

 2.3 代码示例

2.4 运行结果

3. 绘制图像轮廓

3.1 接口定义

3.2 参数说明

3.3 代码示例

 3.4 运行结果

4. 计算轮廓周长

5. 计算轮廓面积

6. 示例:计算图像轮廓的面积与周长

7. 应用场景


相关阅读

OpenCV:多边形逼近与凸包-CSDN博客


简述

图像处理领域,轮廓是图像中物体的边界或形状信息的表达方式。通过提取轮廓,可以对图像中的目标进行识别、测量和分析。本文将从概念到实际操作详细介绍图像轮廓及其相关操作,并展示如何在 OpenCV 中实现。


1. 什么是图像轮廓?

图像轮廓 是图像中物体边界的闭合曲线,表示具有相同强度或颜色像素的连接路径。它是一种重要的图像特征,常用于形状分析和对象检测。

特点

  • 轮廓基于二值图像计算,必须先将输入图像转换为二值图。
  • OpenCV 提供的轮廓查找算法将视图像中的白色区域为前景(目标)。
  • 轮廓的方向可以是顺时针或逆时针。

2. 查找图像轮廓

OpenCV 提供了 cv2.findContours() 函数来查找图像的轮廓。

2.1 接口定义

contours, hierarchy = cv2.findContours(image, mode, method)

2.2 参数说明

image:输入的二值图像(通常是灰度图的阈值化结果)。
mode:轮廓的检索模式,常见值:

  • cv2.RETR_EXTERNAL:只检测最外层轮廓。
  • cv2.RETR_LIST:检测所有轮廓,不建立层级关系。
  • cv2.RETR_TREE:检测所有轮廓,并构建完整层级关系。

method:轮廓的近似方法:

  • cv2.CHAIN_APPROX_NONE:存储所有的轮廓点。
  • cv2.CHAIN_APPROX_SIMPLE:只存储必要的轮廓点,压缩水平和垂直冗余点。

返回值:

  • contours:检测到的轮廓列表,每个轮廓是一个 Numpy 数组。
  • hierarchy:每个轮廓的层级关系。

 2.3 代码示例

import cv2# 读取图像并转为灰度图
image = cv2.imread('D:\\resource\\filter\\find_contours.png', cv2.IMREAD_GRAYSCALE)# 二值化
_, binary_img = cv2.threshold(image, 150, 255, cv2.THRESH_BINARY)# 轮廓查找
#contours, hierarchy = cv2.findContours(binary_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours, hierarchy = cv2.findContours(binary_img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
print(contours)# 显示图像 
cv2.imshow('image', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

示例说明:

  • 当前示例使用的图像为:白色背景,中间画了一个黑色的矩形。
  • 用win11自带的画图软件画出来的,并非纯粹的黑白图像,在代码中最好进行二值化处理
  • 该示例的作用是将图像中所有轮廓的必要点打印出来。

2.4 运行结果

 

打印结果显示的是:图像必要的轮廓点。

该图像包含2个轮廓 :

  • 最外层的白色背景边框。
  • 中间黑色矩形边框。

3. 绘制图像轮廓

OpenCV 提供了 cv2.drawContours() 函数用于绘制轮廓。

3.1 接口定义

cv2.drawContours(image, contours, contourIdx, color, thickness)

3.2 参数说明

image:目标图像,轮廓将绘制在此图像上。
contours:轮廓数据,cv2.findContours() 的输出。
contourIdx:指定绘制的轮廓索引:

  • -1:绘制所有轮廓。
  • >=0:绘制特定索引的轮廓。

color:绘制轮廓的颜色(BGR 格式)。
thickness:线条粗细,-1 表示填充轮廓。

3.3 代码示例

import cv2# 读取图像
image = cv2.imread('D:\\resource\\filter\\find_contours.png')# 转为灰度图
gray_img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 二值化
_, binary_img = cv2.threshold(gray_img, 150, 255, cv2.THRESH_BINARY)# 轮廓查找
contours, hierarchy = cv2.findContours(binary_img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)# 绘制轮廓
result = cv2.drawContours(image, contours, -1, (0,0,255), 2)# 显示图像 
cv2.imshow('result', result)
cv2.waitKey(0)
cv2.destroyAllWindows()

示例说明:

  • 依旧使用同一张图片。
  • 该示例的作用是将图像中所有的轮廓用红色的线条绘制出来,其中线条的粗细数值为2。 

 3.4 运行结果

将图像中所有的轮廓绘制出来:


    4. 计算轮廓周长

    OpenCV 提供了 cv2.arcLength() 函数计算轮廓的周长。

    接口定义

    perimeter = cv2.arcLength(curve, closed)

    参数说明

    • curve:输入轮廓点。
    • closed:布尔值,是否将轮廓视为闭合曲线。

    返回值

    轮廓的周长(浮点数)。


    5. 计算轮廓面积

    OpenCV 提供了 cv2.contourArea() 函数计算轮廓的面积。

    接口定义:

    area = cv2.contourArea(contour)
    

    参数说明:

    • contour:输入轮廓点。

    返回值

    轮廓的面积(浮点数)。


    6. 示例:计算图像轮廓的面积与周长

    示例如下: 

    import cv2# 读取图像
    image = cv2.imread('D:\\resource\\filter\\find_contours.png')# 转为灰度图
    gray_img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 二值化
    _, binary_img = cv2.threshold(gray_img, 150, 255, cv2.THRESH_BINARY)# 轮廓查找
    #contours, hierarchy = cv2.findContours(binary_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    contours, hierarchy = cv2.findContours(binary_img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    # print(contours)# 绘制轮廓
    #result = cv2.drawContours(image, contours, -1, (0,0,255), 2)# 计算面积
    area = cv2.contourArea(contours[1])
    print("area=%d"%(area))# 计算周长
    len = cv2.arcLength(contours[1], True)
    print("len=%d"%(len))# 显示图像 
    #cv2.imshow('image', image)
    #cv2.imshow('result', result)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    示例说明:

    • 依旧使用同一张图像。
    • 查找图像轮廓,取索引为1的轮廓。
    • 计算其面积与周长,并打印出来。

     打印输出:

    PS D:\code\opencv_python> & "D:/Program Files/Python38-32/python.exe" d:/code/opencv_python/calc_contours.py
    area=35951
    len=769
    PS D:\code\opencv_python>

    7. 应用场景

    1. 目标检测与识别:通过轮廓提取图像中的特定对象。
    2. 形状分析:计算周长、面积等几何属性。
    3. 物体测量:用于测量物体的尺寸和外观特征。

    http://www.ppmy.cn/embedded/160144.html

    相关文章

    中国城商行信贷业务数仓建设白皮书(第一期:总体规划)

    一、项目背景与行业现状 1.1 国内城商行信贷业务痛点 2024年统计数据显示:全国134家城商行平均历史数据处理延迟达37小时/次 传统Oracle架构日均处理能力上限仅为320万笔交易 客户特征维度不足(现行系统平均维护86个客户标签) 监管报表生成耗时超同业股份制银行2.3倍 1.2 H…

    车载软件架构 --- 基于AUTOSAR软件架构的ECU开发流程小白篇

    我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 简单,单纯,喜欢独处,独来独往,不易合同频过着接地气的生活…

    Java进阶文件输入输出实操(图片拷贝)

    Java进阶文件输入输出实操(图片拷贝) 把某个目录下的全部图片,全部拷贝到另外一个目录 package test; import domee.chapter6_7.B; import java.io.*; public class Ex10_10 { public static void main(String[] args) throws IOException { …

    用BGP的路由聚合功能聚合大陆路由,效果显著不?

    正文共:666 字 11 图,预估阅读时间:1 分钟 之前我们统计过中国境内的IP地址和路由信息(你知道中国大陆一共有多少IPv4地址吗?),不过数量比较多,有8000多条。截止到2021年底&#xff…

    IOC三种实现方式的区别

    在Spring框架中,IOC(控制反转)通过依赖注入(DI)来实现,而依赖注入主要有三种实现方式:构造器注入、Setter注入和字段注入。每种方式都有其特点、适用场景和优缺点。以下是它们的详细对比&#x…

    YOLOV11改进1-检测头篇

    文章目录 前言一、YAML修改二、模型训练1.数据集准备2.环境准备3.训练3.1原结构训练3.2更改后的模型 三.效果对比1.原始结构2.修改后的结果3.详细对比 总结 前言 目标检测领域里,小目标一直是一个难点问题,虽然我们可以用YOLOSAHI的方式进行滑动窗口推理…

    【论文分享】Ultra-AV: 一个规范化自动驾驶汽车纵向轨迹数据集

    和大家分享一份最近的工作! 统一自动驾驶纵向轨迹数据集(Ultra-AV) 摘要 自动驾驶车辆在交通运输领域展现出巨大潜力,而理解其纵向驾驶行为是实现安全高效自动驾驶的关键。现有的开源AV轨迹数据集在数据精炼、可靠性和完整性方…

    SpringMVC SpringMVC响应 一、数据处理及跳转

    1. 结果跳转方式 ①.ModelAndView 设置ModelAndView对象 , 根据view的名称 , 和视图解析器跳到指定的页面 <bean id"templateResolver" class"org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver"><property name"p…