【OpenCv】图像的轮廓查找

1 原理

  边界或者轮廓可以简单认为成将连续的点(连着边界)连在一起的曲线,具有相同的颜色或者灰度。轮廓在形状分析和物体的检测和识别中很有用。
在这里插入图片描述
在机器视觉领域最常用的轮廓查找的算法之一是 Moore-Neighbor 算法,像素的摩尔邻域 P P P 是与该像素共享顶点或边的 8 8 8 个像素的集合。这些像素即 如下图所示的像素 P 1 P1 P1 P 2 P2 P2 P 3 P3 P3 P 4 P4 P4 P 5 P5 P5 P 6 P6 P6 P 7 P7 P7 P 8 P8 P8。 摩尔邻域(也称为8 邻域或 间接邻域)是文献中经常出现的一个重要概念。
在这里插入图片描述

其大概的原理如下:

  • 找到一个黑色像素,并将它定为你的起始像素。(定位一个起始像素可以以多种方式来完成的;我们将从网格的左下角开始,自下而上扫描每一列像素,从最左向右的每列像素,直到遇到一个黑色的像素,我们将其作为我们的起始像素)。
  • 每次碰到黑色像素P时,都回溯,即回到之前站立的白色像素,然后以顺时针方向绕过像素 P P P,访问其摩尔邻域中的每个像素,直到击中黑色像素。
  • 重复这个过程,当起始像素被第二次访问时算法终止,在整个运行过程走过的黒色像素就是目标的边界像素。走过的黑色像素将成为图案的轮廓。
    在这里插入图片描述
    动画演示,说明 Moore-Neighbor 跟踪如何继续跟踪给定模式的轮廓。(以顺时针方向跟踪轮廓)
    在这里插入图片描述

2 API

此部分参考了https://blog.csdn.net/sunny2038/article/details/12889059

OpenCv 中轮廓查找主要由如下两个 API 来完成。第一个是查找函数 findContours,第二个是绘制轮廓的函数 drawContours

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

输入:

  • 第一个参数是寻找轮廓的图像,注意是二值图。
  • 第二个参数表示轮廓的检索模式,有四种,cv2.RETR_EXTERNAL 表示只检测外轮廓,cv2.RETR_LIST 检测的轮廓不建立等级关系,cv2.RETR_CCOMP 建立两个等级的轮廓,上面的一层为外边界,里面的一层为内孔的边界信息。如果内孔内还有一个连通物体,这个物体的边界也在顶层。cv2.RETR_TREE 建立一个等级树结构的轮廓。
  • 第三个参数method为轮廓的近似办法,cv2.CHAIN_APPROX_NONE 存储所有的轮廓点,相邻的两个点的像素位置差不超过 1,即 m a x ( a b s ( x 1 − x 2 ) , a b s ( y 2 − y 1 ) ) = = 1 max(abs(x1-x2),abs(y2-y1))==1 max(abs(x1x2)abs(y2y1))==1cv2.CHAIN_APPROX_SIMPLE 压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例如一个矩形轮廓只需 4 个点来保存轮廓信息,cv2.CHAIN_APPROX_TC89_L1CV_CHAIN_APPROX_TC89_KCOS 使用 teh-Chinl chain 近似算法

输出:

  • contours 是轮廓本身。
  • hierarchy 是每条轮廓对应的属性。
cv2.drawContours(image, contours, contourIdx, color[, thickness[, lineType[, hierarchy[, maxLevel[, offset ]]]]])

输入:

  • 第一个参数是指明在哪幅图像上绘制轮廓。
  • 第二个参数是轮廓本身,在 Python 中是一个 list
  • 第三个参数指定绘制轮廓list中的哪条轮廓,如果是-1,则绘制其中的所有轮廓。thickness 表明轮廓线的宽度。

3 案例

绘制下面所有飞机的轮廓
在这里插入图片描述
代码:

import cv2 as cv 
import numpy as np
import matplotlib.pyplot as plt
%matplotlib

img_planes = cv.imread('images/planes.png', 0)
img = np.zeros((img_planes.shape[0], img_planes.shape[1], 3))
#查找轮廓,要注意传入的图像一定要是二值图,因为我这里的图片本就是二值化图片,所以不需要二值化
contours, hierarphy = cv.findContours(img_planes, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_NONE)
#绘制轮廓
cv.drawContours(img, contours,  -1, (0, 0, 255), 1)
cv.imshow('img', img)
cv.waitKey(0)

效果:
在这里插入图片描述

  • 13
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
OpenCV图像轮廓是指在图像中连续的边界线。根据引用中的示例代码,我们可以使用OpenCV库来实现图像轮廓查找和计算。 首先,我们需要读取图像并将其转换为灰度图像。可以使用cv2.imread()函数读取图像,然后使用cv2.cvtColor()函数将图像转换为灰度图像。 接下来,我们可以使用cv2.threshold()函数将灰度图像二值化,得到一个二值图像,其中只有两个像素值,一种是白色(255),一种是黑色(0)。函数中的阈值参数可以根据具体应用进行调整。 然后,我们可以使用cv2.findContours()函数查找图像中的轮廓。该函数返回两个结果,第一个结果是轮廓的列表,第二个结果是层级信息。轮廓是一系列坐标点的集合,描述了对象的边界。 接着,我们可以使用cv2.drawContours()函数将轮廓绘制在图像上。这个函数会直接修改原图像,如果想保持原图像不变,可以先复制一份。通过指定轮廓的索引,我们可以绘制特定的轮廓。 最后,我们可以使用cv2.contourArea()函数计算轮廓的面积,使用cv2.arcLength()函数计算轮廓的周长。这两个函数都需要传入一个轮廓参数。 所以,OpenCV图像轮廓的实现步骤可以总结为以下几个步骤: 1. 读取图像并将其转换为灰度图像。 2. 使用阈值函数将灰度图像二值化。 3. 使用findContours函数查找图像中的轮廓。 4. 绘制轮廓图像上。 5. 计算轮廓的面积和周长。 希望这个回答能帮到你!<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [opencv 图像轮廓的实现示例](https://download.csdn.net/download/weixin_38681736/12849896)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [OpenCv图像轮廓](https://blog.csdn.net/weixin_64443786/article/details/131796588)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

八岁爱玩耍

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值