当前位置: 首页 > 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.xdnf.cn/news/1400401.html

相关文章:

  • 生成式 AI 重构内容生产:效率提升背后的创作版权边界争议
  • day43-Ansible-PlayBook
  • 如何使用快照将 AWS OpenSearch 服务中的数据从开发环境复制到生产环境
  • 知料觅得-新一代AI搜索引擎
  • Linux网络服务发现在VPS云服务器自动化配置的关键技术与实践
  • 给某个conda环境安装CUDA 12.4版本 全局CUDA不变
  • C++的迭代器和指针的区别
  • 【小白笔记】基本的Linux命令来查看服务器的CPU、内存、磁盘和系统信息
  • Java SpringAI应用开发面试全流程解析:RAG、流式推理与企业落地
  • 物联网(IoT)中常用的通信协议
  • GD32VW553-IOT 基于 vscode 的 bootloader 移植(基于Cmake)
  • 微论-突触的作用赋能思考(可能是下一代人工智能架构的启发式理论)
  • 响应式编程框架Reactor【5】
  • Spring代理的特点
  • AI-调查研究-65-机器人 机械臂控制技术的前世今生:从PLC到MPC
  • 【MCP系列教程】 Python 实现 FastMCP StreamableHTTP MCP:在通义灵码 IDE 开发并部署至阿里云百炼
  • JsMind 常用配置项
  • 【计算机网络】HTTP是什么?
  • 基于Docker部署的Teable应用
  • Linux驱动开发重要操作汇总
  • “人工智能+”政策驱动下的技术重构、商业变革与实践路径研究 ——基于国务院《关于深入实施“人工智能+”行动的意见》的深度解读
  • wpf之依赖属性
  • 桌面GIS软件FlatGeobuf转Shapefile代码分享
  • 学习游戏制作记录(视觉上的优化)
  • 第三弹、AI、LLM大模型是什么?
  • Visual Studio(vs)免费版下载安装C/C++运行环境配置
  • openEuler2403安装部署Redis8
  • FPGA学习笔记——SPI读写FLASH
  • 【运维篇第三弹】《万字带图详解分库分表》从概念到Mycat中间件使用再到Mycat分片规则,详解分库分表,有使用案例
  • 小迪Web自用笔记7