十九、计算机视觉-轮廓检测

news/2024/11/8 11:36:13 标签: 计算机视觉, 人工智能

文章目录

  • 前言
  • 一、什么是轮廓检测
  • 二、轮廓检测与边缘检测的区别
  • 三、轮廓检测的过程


前言

之前我们学习了边缘检测算法(如Sobel、Canny等),接下来的课程将会探讨轮廓检测。轮廓检测是图像处理中的一个重要任务,它的目标是识别出图像中的物体轮廓,即物体的外部边界。与边缘检测不同,轮廓检测通常需要对图像进行更复杂的处理,以便有效地提取出物体的整体形状。


一、什么是轮廓检测

轮廓检测是图像处理中的一项任务,其主要目标是在图像中找到物体的外部轮廓,也就是物体的边界。这些轮廓通常被表示为一系列连接的点、线段或曲线,能够描述物体的整体形状。轮廓检测通常应用于目标检测、物体识别、图像分割等领域,是许多计算机视觉应用的重要步骤之一。

二、轮廓检测与边缘检测的区别

计算机视觉领域中,边缘检测和轮廓检测是两个常用的图像处理任务,它们虽然在一定程度上可以实现相似的目标,但在技术原理和应用场景上有一些区别。
1.边缘检测(Edge Detection)

a.边缘检测旨在检测图像中的边缘,边缘通常表示了图像中灰度值或颜色值的突然变化。

b.边缘检测算法通常会在图像中寻找灰度梯度较大的区域,因为这些区域往往对应着图像中的边缘。

c.常见的边缘检测算法包括Sobel、Prewitt、Canny等,它们可以检测出图像中的强边缘,通常输出的是二值化的图像,其中边缘位置被表示为白色或者其他明显的颜色,而其他部分则是黑色。

2.轮廓检测(Contour Detection):

a.轮廓检测旨在检测图像中的物体轮廓,即物体的外部边界。

b.轮廓检测通常通过将图像分割为不同的区域来实现,然后检测这些区域之间的边界。

c.常见的轮廓检测算法包括基于边缘检测结果的轮廓查找、基于阈值的图像分割算法(如阈值化、分水岭算法等)、基于区域增长的方法等。

d.轮廓检测通常输出的是包含物体外部边界的闭合曲线或者多边形,它们可以用于图像分割、物体识别等任务。

简单的说边缘检测是找出图像中灰度或颜色变化快的地方,通常输出的是边缘的位置信息,用来表示物体的轮廓。轮廓检测则是找出物体的外部轮廓,通常输出的是表示物体形状的闭合曲线或多边形。边缘检测更专注于局部的变化,而轮廓检测则更关注整个物体的外形。
因此,尽管边缘检测和轮廓检测都是图像处理中常用的任务,并且它们在一些方面有着相似之处,但它们的目标和技术方法有所不同,适用于不同的应用场景。

三、轮廓检测的过程

首先我们看一个简单的轮廓检测的代码

import cv2
import numpy as np

# 读取图片
image = cv2.imread('image.jpg')

# 转换为灰度图
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 使用二值化
_, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)

# 寻找轮廓
contours, _ = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

# 绘制轮廓
cv2.drawContours(image, contours, -1, (0, 255, 0), 3)

# 显示图片
cv2.imshow('Contours', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

上面的代码可以看到它的流程,在轮廓检测前需要先对图像进行二值化或Canny操作。我们上面代码是使用threshold做了二值化操作。图像的二值化就是将图像上的像素点的灰度值设置为0或255,这样将使整个图像呈现出明显的黑白效果。在数字图像处理中,二值图像占有非常重要的地位,图像的二值化使图像中数据量大为减少,从而能凸显出目标的轮廓2。threshold的参数127表示 当像素点的值小于127的时候把像素点置于0,当像素点大于127时 置于255,这样就达到吧图片二值化。
二值化过后就可以使用findContours查找轮廓了,我们看下这个方法

contours, hierarchy = cv2.findContours(image, mode, method)
  • image:输入的二值化图像,即轮廓检测的源图像,通常为灰度图像经过二值化处理后的图像
  • mode:轮廓检索模式,指定轮廓的检索模式,可以是以下值之一:
    ○ cv2.RETR_EXTERNAL:只检测外部轮廓。
    ○ cv2.RETR_LIST:检测所有轮廓,不建立等级关系。
    ○ cv2.RETR_CCOMP:检测所有轮廓,建立两级等级关系。
    这种模式下,cv2.findContours() 函数会检测所有轮廓,并将它们组织成两级的等级结构,包括外部轮廓和内部轮廓(可能嵌套多层)。具体来说,当检测到的轮廓之间存在嵌套关系时,外部轮廓被标记为一级轮廓,而内部轮廓被标记为二级轮廓。这种两级等级关系主要用于描述轮廓的包含关系,即一个轮廓是否包含在另一个轮廓内部。例如,假设图像中存在一个外部轮廓和一个内部轮廓,内部轮廓完全包含在外部轮廓内部。在使用 cv2.RETR_CCOMP 模式进行轮廓检测后,返回的轮廓列表中会包含两个轮廓,其中外部轮廓是一级轮廓,内部轮廓是二级轮廓,并且内部轮廓的父轮廓是外部轮廓。总之,建立两级等级关系意味着 cv2.findContours() 函数将轮廓组织成外部轮廓和内部轮廓两个层级,以描述轮廓之间的包含关系。
    ○ cv2.RETR_TREE:检测所有轮廓,建立完整的等级树结构。
  • method:轮廓近似方法,指定轮廓的近似方法,可以是以下值之一:
    ○ cv2.CHAIN_APPROX_NONE:保存所有的轮廓点。
    ○ cv2.CHAIN_APPROX_SIMPLE:压缩水平、垂直和对角线方向上的所有轮廓,只保留端点。

上面这两个参数是什么区别呢?我们知道线是由点组成,通过CHAIN_APPROX_NONE这个参数可以输出所有的轮廓点,就是一个完整的轮廓,CHAIN_APPROX_SIMPLE 只有端点,比如我们有一个正方形 用第一个参数可以返回正方形的四条线的轮廓,而第二个参数则输出的是正方形的四个点

返回值:

● contours:检测到的轮廓,是一个列表,每个轮廓都是一个 numpy 数组,其中存储了轮廓的所有点坐标。
● hierarchy:轮廓的层级关系,通常在层级轮廓检测时才会用到。
contours得到了轮廓信息,我们就可以去绘制轮廓了,

# 在原始图像上绘制轮廓
image = cv2.drawContours(image, contours, contourIdx, color, thickness)

● image:要绘制轮廓的图像,通常是原始图像的副本。
● contours:要绘制的轮廓列表,是由 cv2.findContours() 函数返回的轮廓信息。
● contourIdx:要绘制的轮廓索引,指定要绘制的轮廓在轮廓列表中的索引。如果设置为负数(例如 -1),则表示绘制所有的轮廓。
● color:绘制轮廓的颜色,可以是 BGR 形式的颜色值,例如 (0, 255, 0) 表示绿色。
● thickness:绘制轮廓的线条宽度,如果设置为负数,则表示填充轮廓内部。默认值为 1,表示绘制轮廓的线条。
返回值:
● 绘制了轮廓的图像。

在这里插入图片描述


http://www.niftyadmin.cn/n/5743836.html

相关文章

ModuleNotFoundError: No module named ‘_ssl‘ centos7中的Python报错

报错 ModuleNotFoundError: No module named ‘_ssl’ 解决步骤: 1.下载openssl wget https://www.openssl.org/source/openssl-3.0.7.tar.gz tar -zxvf openssl-3.0.7.tar.gz cd openssl-3.0.72.编译安装 ./config --prefix/usr/local/openssl make make install3…

如何在Python中实现一个简单的搜索引擎:从零开始的指南

如何在Python中实现一个简单的搜索引擎:从零开始的指南 引言 在当今信息爆炸的时代,搜索引擎已成为我们日常生活中不可或缺的工具。无论是学术研究、工作需求,还是日常娱乐,搜索引擎都为我们提供了便捷的信息获取途径。那么,你是否想过自己也能动手实现一个简单的搜索引…

uniapp使用腾讯即时通讯IM(复制即可使用)

一、先创建uniapp项目,可选择vue2/vue3,我们实例为vue2 二、打开项目控制台,下载 TUIKit 组件 命令:npm init -y 三、在这里分为两个版本 macOS和Windows,根据使用的电脑下载对应的般般 《 macOS:》 命令1: npm i @tencentcloud/chat-uikit-uniapp unplugin-vue2-sc…

py和js变量

最近在学习py,总结一下两种语言,基础变量 Python 列表 ([]) 与 JavaScript 数组 ([]) Python: 列表是有序的、可变的,可以包含不同类型的元素。JavaScript: 数组是有序的、可变的,也可以包含不同类型的元素。对比: 两者都允许按索引访问元素&…

Flutter 鸿蒙next 中使用 MobX 进行状态管理

Flutter & 鸿蒙next 中使用 MobX 进行状态管理 在应用开发中,状态管理是一个至关重要的环节,特别是在复杂的Flutter或鸿蒙next项目中。状态的变化往往会影响UI的更新,因此,选择一种高效、灵活的状态管理工具显得尤为重要。Mo…

大数据-213 数据挖掘 机器学习理论 - KMeans Python 实现 距离计算函数 质心函数 聚类函数

点一下关注吧!!!非常感谢!!持续更新!!! 目前已经更新到了: Hadoop(已更完)HDFS(已更完)MapReduce(已更完&am…

如何使用Varjo直接观看Blender内容

最近,开源的3D建模程序Blender为Varjo提供了出色的OpenXR支持,包括四视图和凹进渲染扩展。但是在Blender中,默认不启用VR场景检查。要开始使用VR场景检查,只需遵循以下步骤: 1. 下载并安装Blender 2.启用Blender VR场景…

Postman上传图片如何处理

打开Postman,创建一个新的请求 URL: http://90.104.232.49:80/dev-api/appcommon/upload 如果有解密进入上传就在请求头添加 点击“Body”选项卡。 选择“form-data”类型。 在“KEY”列中输入文件字段的名称,例如file。 在“VALUE”列中&#xff0…