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

opencv实现轮廓绘制和选择

前面学习了opencv中图像的一些处理,但对于opencv我们更多的还是对图像做出一些判断和识别,所以下面开始学习图像的识别。

原图:

一 图像轮廓的识别

import cv2
pen=cv2.imread('pen.png',0)
ret,new_pen=cv2.threshold(pen,120,255,cv2.THRESH_BINARY)
cv2.imshow('pen',new_pen)
contours, hierarchy = cv2.findContours(new_pen,cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
print(hierarchy)
print(contours)
print(len(contours))
pen1=pen.copy()
Contours = cv2.cvtColor(pen1, cv2.COLOR_GRAY2BGR)
cv2.drawContours(Contours,contours,-1,(0,255,0),2)
cv2.imshow('pen1',Contours)
cv2.waitKey(0)

1 图像二值处理

ret,new_pen=cv2.threshold(pen,120,255,cv2.THRESH_BINARY)

我们这里识别图像的时候,转化为了灰度图,目的是为了后面做灰度处理,在识别轮廓之前我们要让我们的图像更加鲜明,所以我们做了一下二值处理

2 寻找轮廓

contours, hierarchy = cv2.findContours(new_pen,cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

这里会返回两个参数,这里contours就是我们的轮廓。hierarchy这个表示层级之间的一种嵌套方式,不是特别重要。

我们这里查看下contours

这个是一个一个的坐标,我们要知道轮廓就是一个一个点组成的。然后我们可以通过drawContours来绘制。

3 绘制

注意到我们绘制之前我们还进行了一次的转换,把我们的图像转化为了RGB图像(我们前面转换成了单维度的图像),不然的话,我们使用灰度图的线条绘制的不明显。

Contours = cv2.cvtColor(pen1, cv2.COLOR_GRAY2BGR)
cv2.drawContours(Contours,contours,-1,(0,255,0),2)

这个里面有5个参数,第一个参数是表示我们要绘制到的目标图像,第二个参数是我们绘制的轮廓信息,第三个表示我们要绘制的索引(-1表示绘制全部的轮廓),第四个表示我要绘制的轮廓颜色,第五个表示要绘制的粗度。

二 根据面积进行轮廓选择

import cv2
pen1=cv2.imread('pen.png',0)
ret,pen=cv2.threshold(pen1,120,255,cv2.THRESH_BINARY)
cv2.imshow('pen',pen)
contours, hierarchy = cv2.findContours(pen,cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)pen1=pen.copy()
aa = cv2.cvtColor(pen1, cv2.COLOR_GRAY2BGR)
cv2.drawContours(aa,contours,-1,(0,255,0),2)
are=cv2.contourArea(contours[0])
print(are)
ls=[]
for i in contours:if cv2.contourArea(i) >10000:ls.append(i)
print(ls)
cv2.drawContours(aa,ls,-1,(0,0,255),2)
cv2.imshow('pen1',aa)
cv2.waitKey(0)
key=cv2.contourArea, reverse=True)[0]
cv2.drawContours(aa,[sorted_contours],contourIdx=-1,color=(0,0,255),thickness=3)
cv2.imshow('pen2',aa)
cv2.waitKey(0)

1 查看轮廓面积

cv2.contourArea(contours[0])

我们可以使用这个函数来查看一个轮廓的面积

2 利用面积筛选轮廓

我们对所有轮廓进行遍历,找出面积大于10000的面积,然后添加到ls中,再画出来,就找到了符合我们条件的轮廓。

ls=[]
for i in contours:if cv2.contourArea(i) >10000:ls.append(i)
print(ls)
cv2.drawContours(aa,ls,-1,(0,0,255),2)
# cv2.imshow('contours',contours)
cv2.imshow('pen1',aa)
cv2.waitKey(0)

3 先对轮廓面积进行排序

我们使用sorted对所有轮廓面积进行排序,然后打印出最大的那一个。注意我们绘制的时候也要对sorted_contours加上一个中括号,不然画出来的图像是断断续续的。

sorted_contours = sorted(contours, key=cv2.contourArea, reverse=True)[0]
cv2.drawContours(aa,[sorted_contours],contourIdx=-1,color=(0,0,255),thickness=3)
cv2.imshow('pen2',aa)
cv2.waitKey(0)

三 画出轮廓的外界圆和外接矩形

1 外接圆

import cv2
pen1=cv2.imread('pen.png',0)
ret,pen=cv2.threshold(pen1,120,255,cv2.THRESH_BINARY)
cv2.imshow('pen',pen)
contours, hierarchy = cv2.findContours(pen,cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
pen1=pen.copy()
aa = cv2.cvtColor(pen1, cv2.COLOR_GRAY2BGR)
cv2.drawContours(aa,contours,-1,(0,255,0),2)
cnt=contours[7]
[x,y],r=cv2.minEnclosingCircle(cnt)
ab=cv2.circle(aa,(int(x),int(y)),int(r),(255,0,0),2)
cv2.imshow('pen3',ab)
cv2.waitKey(0)

这里选取了第七个轮廓也就是那个铅笔,然后使用cv2.minEnclosingCircle(cnt)来获取这个轮廓的外界圆的外界圆,会返回两个值,一个是坐标的圆心,一个是半径,然后就可以通过cv2.circle专门的画圆工具来绘制了。

cnt=contours[7]
[x,y],r=cv2.minEnclosingCircle(cnt)
ab=cv2.circle(aa,(int(x),int(y)),int(r),(255,0,0),2)
cv2.imshow('pen3',ab)
cv2.waitKey(0)

2 外接矩形

import cv2
pen1=cv2.imread('pen.png',0)
ret,pen=cv2.threshold(pen1,120,255,cv2.THRESH_BINARY)
cv2.imshow('pen',pen)
contours, hierarchy = cv2.findContours(pen,cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
pen1=pen.copy()
aa = cv2.cvtColor(pen1, cv2.COLOR_GRAY2BGR)
cv2.drawContours(aa,contours,-1,(0,255,0),2)
cnt=contours[7]
x,y,w,h=cv2.boundingRect(cnt)
ac=cv2.rectangle(aa,(x,y),(x+w,y+h),(0,0,255),2)
cv2.imshow('pen4',ac)
cv2.waitKey(0)

还是和上面的那个一样,选取铅笔的笔杆轮廓,然后使用boundingRect获取我们要画的坐标起点了,宽和高,然后就可以画出来了。

四 绘制近似轮廓

import cv2
pen1=cv2.imread('pen.png',0)
ret,pen=cv2.threshold(pen1,120,255,cv2.THRESH_BINARY)
cv2.imshow('pen',pen)
contours = cv2.findContours(pen,cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)[-2]
# cv2.imshow('contours',contours)
# cv2.waitKey(0)
es=0.01*cv2.arcLength(contours[0],True)
approx=cv2.approxPolyDP(contours[0],0.01*cv2.arcLength(contours[0],True),True)
phone_new=pen1.copy()
aa = cv2.cvtColor(phone_new, cv2.COLOR_GRAY2BGR)
image_contours=cv2.drawContours(aa,[approx],-1,(0,255,0),2)
cv2.imshow('phone_new',image_contours)
cv2.waitKey(0)

先给结果图

我们可以看到,结果图中我们的手机的角角的地方,本来弯的变成了菱形,是因为这里采用了

es=0.01*cv2.arcLength(contours[0],True)
approx=cv2.approxPolyDP(contours[0],0.01*cv2.arcLength(contours[0],True),True)

这个es表示一个距离,就是这个地方的d如果大于我们设置的,就会直接用这个直线来取代。

http://www.dtcms.com/a/358360.html

相关文章:

  • Intellij IDEA社区版(下载安装)
  • 学习python第15天
  • 网络编程(4)
  • 项目管理方法全流程解析
  • 【前端教程】HTML 基础界面开发
  • destoon8.0根据模块生成html地图
  • 星链调查(SOS)线上问卷调查服务:全流程专业闭环
  • Python自定义函数形式参中的*args、**kwargs、*和/
  • 学习:uniapp全栈微信小程序vue3后台(7)
  • AI生成思维导图和AI生成Excel公式
  • Dify1.8.0最新版本安装教程:Ubuntu25.04系统本地化安装部署Dify详细教程
  • Langflow核心技术学习笔记
  • kube-proxy
  • 【系列09】端侧AI:构建与部署高效的本地化AI模型 第8章:移动端部署实战 - Android
  • 宽带有丢包,重传高的情况怎么优化
  • w嵌入式分享合集125
  • day43-Ansible-PlayBook
  • web渗透PHP反序列化漏洞
  • HunyuanVideo-Foley - AI视频配音 根据视频和文本描述生成逼真的电影级音频 支持50系显卡 一键整合包下载
  • (三)Python语法基础(实战)
  • LabVIEW测斜设备承压试验台
  • pip 镜像源配置(清华/阿里/豆瓣)详解
  • 智瞰风评 - 基于大语言模型的个人征信报告风险分析师
  • vscode新建终端默认不是cmd问题
  • 无人机也能称重?电力巡检称重传感器安装与使用指南
  • macOS 15.6 ARM golang debug 问题
  • 如何评价 Kimi 开源的推理平台 Mooncake?对行业有什么影响?
  • 从零实现一个可扩展的规则解析引擎 —— 支持 AND/OR 优先级、短路求值与多类型运算符
  • Vue2之axios在脚手架中的使用以及前后端交互
  • RabbitMQ 和 Kafka