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

《OpenCV计算机视觉》—— 图像轮廓检测与绘制

文章目录

  • 一、轮廓的检测
  • 二、轮廓的绘制
    • 图像轮廓检测与绘制的代码实现
  • 三、轮廓的近似

一、轮廓的检测

  • 轮廓检测是指在包含目标和背景的数字图像中,忽略背景和目标内部的纹理以及噪声干扰的影响,采用一定的技术和方法来实现目标轮廓提取的过程
  • 注意:做轮廓检测前需要将图片读取为二值数据,即像素值只为0和255
  • 轮廓检测所用到的函数为 cv2.findcontours(img, mode, method)
  • 参数介绍:
    • image:需要实现轮廓检测的原图
    • mode:轮廓的检索模式,主要有四种方式:
      • CV2.RETR_EXTERNAL:只检测外轮廓,所有子轮廓被忽略
      • CV2.RETR_LIST:检测的轮廓不建立等级关系,所有轮廓属于同一等级。
      • CV2.RETR_CCOMP: 检索所有的轮廓,并建立一个两级层次结构,其中上面的一层为外边界,里面的一层为内孔的边界轮廓。
      • CV2.RETR_TREE:返回所有的轮廓,建立一个完整的组织结构的轮廓。
    • method:轮廓的近似方法,主要有以下两种:
      • CV2.CHAIN_APPROX_NONE:存储所有的轮廓点。
      • CV2.CHAIN_APPROX_SIMPLE:压缩模式,只保留该方向的终点坐标,例如一个矩形轮廓只需4个点来保存轮廊信息。
  • 返回的参数:image,contours,hierarchy
    • image:返回处理的原图(在 OpenCV 4.x 中这个返回值已经被移除)
    • contours:包含图像中所有轮廓的list对象。其中每一个独立的轮廓信息以边界点坐标(x,y)的形式储存在numpy数组中。
    • hierarchy:轮廓的层次结构。一个包含4个值的数组:[Next,Previous,First child,Parent]
      • Next:与当前轮廓处于同一层级的下一条轮廓
      • Previous:与当前轮廓处于同一层级的上一条轮廓
      • First Child:当前轮廓的第一条子轮廓
      • Parent:当前轮廓的父轮廓

二、轮廓的绘制

  • cv2.drawContours()函数是用于在图像上绘制轮廓
  • 参数介绍:cv2.drawContours(image, contours, contourIdx, color, thickness=None
    lineType=None, hierarchy=None, maxLevel=None, offset=None)
    • image:要在其上绘制轮廓的输入图像(在原图中画)。
    • contours:轮廓列表,通常由cv2.findContours()函数返回。
    • contourIdx:要绘制的轮廓的索引。如果为负数,则绘制所有轮廓。–> -1
    • color:轮廓的颜色,以BGR格式表示。例如,(0,255,0)表示绿色。
    • thickness:轮廓线的粗细,默认值为1。
    • lineType:轮廓线的类型。默认值为cV2.LINE_8
    • hierarchy:轮廓层次结构。通常由cv2.findContours()函数返回.
    • maxLevel:绘制的最大轮廓层级。默认值为None,表示绘制所有层级。
    • offset:轮廓点的偏移量。默认值为None。

图像轮廓检测与绘制的代码实现

import cv2# 读取图片
phone = cv2.imread('phone.png')
phone_gray = cv2.cvtColor(phone, cv2.COLOR_BGR2GRAY)  # 转换为灰度图# 阙值处理为二值(黑白图像)
ret, phone_binary = cv2.threshold(phone_gray, 120, 255, cv2.THRESH_BINARY)
# 查找图像轮廓  cv2.RETR_LIST --> 查找所有轮廓,且不建立等级关系
_, contours, hierarchy = cv2.findContours(phone_binary, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
# 查看轮廓的层次结构
print(hierarchy)
# 查看一共有多少的轮廓
print(len(contours))# 绘制所有的轮廓
Contours_show = cv2.drawContours(phone, contours=contours, contourIdx=-1, color=(0, 255, 0), thickness=3)# 显示灰度图和在原图中绘出轮廓后的图
cv2.imshow('phone_gray', phone_gray)
cv2.imshow('Contours_show', Contours_show)# 等待任意键按下后关闭所有窗口
cv2.waitKey(0)
cv2.destroyAllWindows()
  • 结果如下
    在这里插入图片描述

三、轮廓的近似

  • 轮廓的近似是计算机视觉和图像处理中的一个常用技术。它可以帮助我们简化轮廓的形状,去除一些不必要的细节,同时保持轮廓的主要形状特征。

  • 在OpenCV中,可以使用cv2.approxPolyDP()函数来近似一个轮廓。这个函数基于 Douglas-Peucker 算法,该算法通过迭代的方式简化轮廓的顶点集合,以生成一个近似于原始轮廓的多边形,但顶点数量更少。这在处理图像中的形状时非常有用,特别是当你想要去除轮廓上的小噪点或不必要的细节,同时保留其主要形状特征时。

  • 参数解释:cv2.approxPolyDP(curve, epsilon, closed)

    • curve:输入轮廓,通常是一个由点组成的 NumPy 数组,这些点定义了轮廓的形状。
    • epsilon:近似的精度参数。它是原始轮廓到近似多边形之间的最大距离。较小的 epsilon 值意味着近似多边形将更接近原始轮廓,但可能会包含更多的顶点。较大的 epsilon 值会导致生成一个更简单的多边形,但可能会丢失一些细节。
    • closed:一个布尔值,指定近似多边形是否应该是封闭的。如果为 True,则函数将确保近似多边形是封闭的,即第一个和最后一个顶点将相同。
  • 返回值 approx 是一个新的 NumPy 数组,包含了近似多边形的顶点。

  • 代码实现

    import cv2# 读取图像
    he = cv2.imread('he.png')# 转换为灰度图像
    he_gray = cv2.cvtColor(he, cv2.COLOR_BGR2GRAY)# 应用阈值处理
    ret, he_thresh = cv2.threshold(he_gray, 120, 255, cv2.THRESH_BINARY)# 查找轮廓
    _, contours, hierarchy = cv2.findContours(he_thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)# 创建一个新图像用于绘制轮廓
    he_new = he.copy()# 遍历所有轮廓
    for cnt in contours:# 轮廓近似# cv2.arcLength()函数用于计算轮廓的周长(近似的精度设置为周长的0.2%)epsilon = 0.002 * cv2.arcLength(cnt, True)  # 可以调整epsilon的值以获得不同的近似精度approx = cv2.approxPolyDP(cnt, epsilon, True)# 绘制近似后的轮廓cv2.drawContours(he_new, [approx], 0, (0, 255, 0), 3)# 显示原始图像和带有轮廓的图像
    cv2.imshow('Original Image', he)
    cv2.imshow('Image with Contours', he_new)# 等待任意键按下后关闭所有窗口
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    • 结果如下
      在这里插入图片描述
    • 由结果可以看出轮廓的近似结果就是一个近似于原始轮廓的多边行。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 在Deepin上安装Cursor
  • Rust运算符
  • Nacos1.X中对NacosNamingService的实现
  • Google大数据架构技术栈
  • HOT 100(七)栈、堆、贪心算法
  • 定时任务和延时任务
  • 前端页面中使用 ppt 功能,并且可以随意插入关键帧
  • uniapp的苹果全屏播放再退出会导致页面字体变大解决方法
  • C语言代码练习(第二十三天)
  • 【Hot100】LeetCode—169. 多数元素
  • Python 课程6-Pandas 和 Matplotlib库
  • 102.WEB渗透测试-信息收集-FOFA语法(2)
  • 【Linux】数据链路层
  • Spring3-IoC1-IoC容器、基于xml管理bean
  • Android 源码多个Launcher设置默认Launcher
  • idea + plantuml 画流程图
  • javascript面向对象之创建对象
  • node和express搭建代理服务器(源码)
  • Promise面试题,控制异步流程
  • TypeScript实现数据结构(一)栈,队列,链表
  • Vue--数据传输
  • 阿里云前端周刊 - 第 26 期
  • 包装类对象
  • 彻底搞懂浏览器Event-loop
  • 如何编写一个可升级的智能合约
  • 如何设计一个比特币钱包服务
  • 视频flv转mp4最快的几种方法(就是不用格式工厂)
  • 新版博客前端前瞻
  • mysql 慢查询分析工具:pt-query-digest 在mac 上的安装使用 ...
  • ​ 轻量应用服务器:亚马逊云科技打造全球领先的云计算解决方案
  • ​ArcGIS Pro 如何批量删除字段
  • #java学习笔记(面向对象)----(未完结)
  • #pragma multi_compile #pragma shader_feature
  • #systemverilog# 之 event region 和 timeslot 仿真调度(十)高层次视角看仿真调度事件的发生
  • (13)Hive调优——动态分区导致的小文件问题
  • (22)C#传智:复习,多态虚方法抽象类接口,静态类,String与StringBuilder,集合泛型List与Dictionary,文件类,结构与类的区别
  • (55)MOS管专题--->(10)MOS管的封装
  • (AtCoder Beginner Contest 340) -- F - S = 1 -- 题解
  • (补)B+树一些思想
  • (二)基于wpr_simulation 的Ros机器人运动控制,gazebo仿真
  • (附源码)springboot学生选课系统 毕业设计 612555
  • (亲测有效)推荐2024最新的免费漫画软件app,无广告,聚合全网资源!
  • (十八)用JAVA编写MP3解码器——迷你播放器
  • (转)淘淘商城系列——使用Spring来管理Redis单机版和集群版
  • (转载)利用webkit抓取动态网页和链接
  • .NET “底层”异步编程模式——异步编程模型(Asynchronous Programming Model,APM)...
  • .NET Core引入性能分析引导优化
  • .NET/C# 使用 #if 和 Conditional 特性来按条件编译代码的不同原理和适用场景
  • .NET企业级应用架构设计系列之技术选型
  • .set 数据导入matlab,设置变量导入选项 - MATLAB setvaropts - MathWorks 中国
  • .sys文件乱码_python vscode输出乱码
  • @ 代码随想录算法训练营第8周(C语言)|Day53(动态规划)
  • @converter 只能用mysql吗_python-MySQLConverter对象没有mysql-connector属性’...
  • @Documented注解的作用
  • [ 隧道技术 ] 反弹shell的集中常见方式(四)python反弹shell