OpenCV(图像处理)-基于Python-轮廓查找

在这里插入图片描述

轮廓查找

  • 1. 轮廓
  • 2.轮廓查找
    • 2.1 findContours()
    • 2.2 drawContours()
    • 2.3 contourArea()和arcLength()
    • 2.4 多边形逼近与凸包
    • approxPolyDP()
    • convexHull()
    • 2.5 外接矩形
    • minAreaRect()
    • boundingRect()

1. 轮廓

一个图像中具有相同颜色或强度(灰度图)的连续点所组成的集合,就是轮廓。轮廓可用于图形分析、物体的识别与检测等等。

2.轮廓查找

在图像中,为了防止轮廓边缘强弱不明显,需要先对图像进行二值化或Canny操作(一般改为黑底白字),画轮廓时会修改输入的图像。

2.1 findContours()

查找图形的轮廓
contours, hierarchy = cv2.findContours(img, mode, ApproximationMode…)
contours:查找到所有轮廓的列表(点的集合)
hierarchy:层级,轮廓有无顺序

mode:(检测方式)

  • RETR_EXTERNAL = 0 :表示只检测外部轮廓(红色为轮廓)
    在这里插入图片描述
  • RETR_LIST = 1 :检测的轮廓不建立等级关系,从里到外、从右到左,一层一层的编号,返回的列表也是按这个顺序排列的
    在这里插入图片描述
  • RETR_CCOMP = 2 :每层最多两级,从里到外、从右到左,单个图形,每两级为一层
    在这里插入图片描述
  • RETR_TREE = 3 :按树形存储轮廓 ,从右到左,从外到里,一个图形一个图像的来,符合正常逻辑
    在这里插入图片描述
    ApproximationMode:(逼近方式)
  • CHAIN_APPROX_NONE:保存所有轮廓上的点
  • CHAIN_APPROX_SIMPLE:只保存角点

2.2 drawContours()

根据获得到的坐标点(contours)绘制轮廓
cv2.drawContours(img, contours, contourIdx, color, thickness…)
img:需要画轮廓的图像
contours:轮廓的点集
contourldx:-1表示绘制所有轮廓 0~n
color:颜色(255,255,255)
thinckness:线宽,-1是全部填充,1~n

import cv2
import numpy as npimg = cv2.imread('./image/contours1.png')
# 转换为灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 二值化,使轮廓更明显
ret, binary = cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY)# 获得轮廓列表
contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)# 画全部的轮廓
cv2.drawContours(img, contours, -1, (0, 0, 255), 2)cv2.imshow('img', img)
# cv2.imshow('gray', gray)
cv2.imshow('binary', binary)cv2.waitKey(0) 

在这里插入图片描述

2.3 contourArea()和arcLength()

求轮廓的面积和周长
cv2.contourArea(contour)
contour:点集(轮廓)
cv2.arcLength(curve, closed)
curve:点集(轮廓)
closed:True/False是否是封闭的轮廓

# 计算面积
area = cv2.contourArea(contours[0])
print('面积 = %d' % area)# 计算周长
len = cv2.arcLength(contours[0], True)
print('周长 = %d' % len)

2.4 多边形逼近与凸包

多边形逼近就是按照画多边形的方式画出图形的轮廓,而凸包只需画出大概轮廓即可。左图为多边形逼近,右图为凸包。
在这里插入图片描述

approxPolyDP()

多边形逼近轮廓
approx = cv2.approxPolyDP(curve, epsilon, closed)
curve:点集(轮廓)
epsilon:精度(越小越逼近)
closed:是否是闭合的轮廓True/False
返回值approx是一个列表

import cv2
import numpy as npdef drawShape(src, points):i = 0while i<len(points):if i == len(points)-1:x1, y1 = points[i][0]x2, y2 = points[0][0]cv2.line(src, (x1, y1), (x2, y2), (0, 255, 0), 2)else:x1, y1 = points[i][0]x2, y2 = points[i+1][0]cv2.line(src, (x1, y1), (x2, y2), (0, 255, 0), 2)i = i+1img = cv2.imread('./image/hand.png')
# 转换为灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 二值化,使轮廓更明显
ret, binary = cv2.threshold(gray, 100, 255, cv2.THRESH_BINARY)# 获得轮廓列表
contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)# 多边形逼近法
e = 5
approx = cv2.approxPolyDP(contours[0], e, True)
drawShape(img, approx)
print(approx[0][0])cv2.imshow('img_5', img)
# cv2.imshow('gray', gray)
cv2.imshow('binary', binary)cv2.waitKey(0)

分别是精度为20,精度为5的逼近图像
在这里插入图片描述

convexHull()

凸包
hull = cv2.convexHull(points, clockwise, …)
points:轮廓
clockwose:是否顺时针绘制True/False
返回值同样是一个列表

import cv2
import numpy as npdef drawShape(src, points):i = 0while i<len(points):if i == len(points)-1:x1, y1 = points[i][0]x2, y2 = points[0][0]cv2.line(src, (x1, y1), (x2, y2), (0, 255, 0), 2)else:x1, y1 = points[i][0]x2, y2 = points[i+1][0]cv2.line(src, (x1, y1), (x2, y2), (0, 255, 0), 2)i = i+1img = cv2.imread('./image/hand.png')
# 转换为灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 二值化,使轮廓更明显
ret, binary = cv2.threshold(gray, 100, 255, cv2.THRESH_BINARY)# 获得轮廓列表
contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)# 凸包
hull = cv2.convexHull(contours[0])
drawShape(img, hull)cv2.imshow('img', img)
cv2.imshow('binary', binary)cv2.waitKey(0)

在这里插入图片描述

2.5 外接矩形

分为最大外接矩形和最小外接矩形,如下图所示。
在这里插入图片描述

minAreaRect()

最小外接矩形
RotatedRect = cv2.minAreaRect(points)
points:点集(轮廓)
返回值:矩形中心点坐标,宽高,旋转角度

boundingRect()

最大外接矩形
x, y, w, h = cv2.boundingRect(array)
array:点集(轮廓)
返回值是矩形的列表:(x,y是起始坐标,w是宽度,h是高度)

import cv2
import numpy as npimg = cv2.imread('./image/hello.jpeg')
# 转换为灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 二值化,使轮廓更明显
ret, binary = cv2.threshold(gray, 100, 255, cv2.THRESH_BINARY)# 获得轮廓列表
contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)# 获取最小外接矩阵,中心点坐标,宽高,旋转角度
r = cv2.minAreaRect(contours[1])
# 获取矩形四个顶点,浮点型
box = cv2.boxPoints(r)
# 取整
box = np.intp(box)
# 画轮廓
cv2.drawContours(img, [box], -1, (0, 255, 0), 2)# 获取最大外接矩形
x, y, w, h = cv2.boundingRect(contours[1])
# 画矩形
cv2.rectangle(img, (x, y), (x+w, y+h),(255, 0, 0), 2)cv2.imshow('img', img)
cv2.imshow('binary', binary)cv2.waitKey(0)

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

springboot配置https

本身不是一个挺难的东西&#xff0c;但是也踩了很多坑&#xff0c;终于是可以了&#xff0c;在此记录一下。 就两步生成证书和springboot配置。 目录 1.生成证书2.springboot配置3.启动验证注意事项 1.生成证书 这里采用java自带的keytool进行生成。 注意jdk环境&#xff0c;…

最新,2023年6月CDGP设计及论述题解析

2023年6月CDGP设计及论述题解析 &#xff08;加gzh“大数据食铁兽”&#xff0c;回复“2023cdgp”获取完整版&#xff09; 酒店会员建模 结合国内外数据安全法律法规&#xff0c;谈谈境外传输数据安全管理体系建设 国内&#xff1a;《数据安全法》、《网络安全法》、2022年9月…

基于深度学习的高精度打电话检测识别系统(PyTorch+Pyside6+YOLOv5模型)

摘要&#xff1a;基于深度学习的高精度打电话检测识别系统可用于日常生活中或野外来检测与定位打电话目标&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的打电话目标检测识别&#xff0c;另外支持结果可视化与图片或视频检测结果的导出。本系统采用YOLOv5目标检…

Docker 中的 .NET 异常了怎么抓 Dump

一&#xff1a;背景 1. 讲故事 有很多朋友跟我说&#xff0c;在 Windows 上看过你文章知道了怎么抓 Crash, CPU爆高&#xff0c;内存暴涨 等各种Dump&#xff0c;为什么你没有写在 Docker 中如何抓的相关文章呢&#xff1f;瞧不上吗&#xff1f; 哈哈&#xff0c;在DUMP的分…

SpringBoot 实现 PDF 添加水印

SpringBoot 实现 PDF 添加水印 使用场景方式一&#xff1a;使用 Apache PDFBox 库方式二&#xff1a;使用 iText 库方式三&#xff1a;Free Spire.PDF for JavaDemo 使用场景 PDF&#xff08;Portable Document Format&#xff0c;便携式文档格式&#xff09;是一种流行的文件…

Jmeter简单实现登录测试

目录 前言&#xff1a; 1、添加线程组--在测试计划上右击-添加-Threads-线程组 2、添加http请求默认值--在线程组上右击-添加-配置元器件-http请求默认值 3、添加sampler-http请求-登录界面 4、添加sampler-http请求-登录-携带用户名和密码 5、创建存放用户名和密码的文件…

Git:git merge和git rebase的区别

分支合并 git merge是用来合并两个分支的。比如&#xff1a;将 b 分支合并到当前分支。同样git rebase b&#xff0c;也是把 b 分支合并到当前分支。他们的 「原理」如下&#xff1a; 假设你现在基于远程分支"origin"&#xff0c;创建一个叫"mywork"的分支…

Golang的trace性能分析

文章目录 一、trace概述二、trace的使用方式代码中trace采集通过pprof采集 三、trace分析细节trace的web界面trace中需要关注的关注GC的频率关注goroutine调度情况关注goroutine的数量理想情况 四、GC分析当前服务GC情况设置GOGC设置GOMEMLIMITGC阈值的讨论GC的特点 五、gorout…

软件测试不行了?2023软件测试行情分析

1 绪论 本文先对互联网对时代和社会变革进行了论述&#xff0c;然后再由互联网时代对软件工业模式变革进行了介绍&#xff0c;最后引出附属于软件工业的测试行业在新形势下的需求变化&#xff0c;并对趋势进行了分析&#xff0c;并最终给出了相关的从业人员的职业发展建议。…

为摸鱼助力:一份Vue3的生成式ElementPlus表单组件

目录 一、实现背景 二、简介 三、组织架构设计 四、实现方式 五、代码示例 六、示例代码效果预览 七、项目预览地址 & 项目源码地址 目前项目还有诸多待完善的地方&#xff0c;大家有好的想法、建议、意见等欢迎再次评论&#xff0c;或于github提交Issues 一、实现…

VueCli的Nuxt重构

我的博客用vuecli写的&#xff0c;SEO不忍直视。于是用Nuxt重构了代码&#xff0c;过程中踩了无数坑 一&#xff1a;body样式不生效 正常的body样式设置不能生效&#xff0c;需要在nuxt.config.js中配置 1、设置bodyAttrs的class属性&#xff0c;该属性值对应一个类名 2、该…

邻接表按深度优先遍历和按广度优先遍历的序列

求此邻接表的深度优先遍历序列和广度优先遍历序列。 深度优先&#xff1a;按深度优先遍历时会有类似"跳转"的操作&#xff0c;比如例1中顶点v1→边v2后&#xff0c;会直接跳转到顶点v2去&#xff0c;再重新从顶点v2→边v1&#xff0c;由于v1访问过&#xff0c;所以变…