前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于OpenCV实现两种方法测量圆弧长度(步骤 + 代码)

基于OpenCV实现两种方法测量圆弧长度(步骤 + 代码)

作者头像
Color Space
发布2024-06-05 15:02:51
1040
发布2024-06-05 15:02:51
举报

导 读

本文主要介绍基于OpenCV实现两种方法测量圆弧长度(步骤 + 代码)。

背景介绍

要求:如上所示,分别用OpenCV计算出图1和图2中圆弧的长度。因为OpenCV中没有提供现成计算圆弧的方法,所以需要自己编写,本文将提供2种不同的方法来实现,仅供参考。

实现步骤

首先以图1为例,如上图所示,方法一具体实现步骤如下:

【1】二值化 + 查找轮廓

代码语言:javascript
复制
img = cv2.imread('11.png')
cv2.imshow('src',img)

gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(gray, 70, 255, cv2.THRESH_BINARY)

contours,hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

【2】查找轮廓凸包缺陷,确定圆弧起点和终点坐标

代码语言:javascript
复制
hull = cv2.convexHull(contours[0],returnPoints=False)#默认returnPoints=True

defects = cv2.convexityDefects(contours[0],hull)
start = end = (0,0)
for i in range(0,defects.shape[0]):
  s,e,f,d = defects[i,0]
  start = tuple(contours[0][s][0])
  end = tuple(contours[0][e][0])
  far = tuple(contours[0][f][0])
  if d > 5000:
    cv2.line(img,start,end,[0,255,0],2)#凸包
    #cv2.circle(img,far,5,[0,0,255],-1)#凸包缺陷点
    cv2.circle(img,end,5,[0,0,255],-1)#凸包缺陷点
    cv2.circle(img,start,5,[0,0,255],-1)#凸包缺陷点
    break
cv2.imshow('defects', img)
cv2.waitKey(0)

【3】获取轮廓最小外接圆,获取圆心,计算圆弧角度

代码语言:javascript
复制
center,radius = cv2.minEnclosingCircle(contours[0])
cv2.circle(img,(int(center[0]),int(center[1])),8,(255,0,255),-1)
cv2.circle(img,end,8,[0,255,255],-1)#凸包缺陷点
cv2.circle(img,start,8,[0,255,255],-1)#凸包缺陷点
cv2.line(img,start,(int(center[0]),int(center[1])),[0,255,0],2)#凸包
cv2.line(img,end,(int(center[0]),int(center[1])),[0,255,0],2)#凸包

angle = cal_ang(start,center,end)
print('angle = %0.2f' % angle)

【4】通过外接圆周长角度比例来计算弧长

代码语言:javascript
复制
length = (1 - angle / 360.0) * math.pi * radius * 2
print((angle / 360.0))
print('radius = %0.2f' % radius)
strL = 'length=%0.2f' % length

cv2.putText(img,strL,(int(center[0]-40),int(center[1]+40)),0,0.8,(255,0,0),2) 
cv2.imshow('result', img)

angle_1 = cal_ang(start, center, ((center[0]+100),(center[1])))
angle_2 = cal_ang(end, center, ((center[0]+100),(center[1])))
cv2.ellipse(img,(int(center[0]),int(center[1])),(int(radius),int(radius)),0,-angle_1,0,(255,0,255),2, cv2.LINE_AA)
cv2.ellipse(img,(int(center[0]),int(center[1])),(int(radius),int(radius)),0,0,angle_2,(255,0,255),2, cv2.LINE_AA)

cv2.imshow('result', img)
cv2.imwrite('result.bmp',img)

cv2.waitKey(0)
cv2.destroyAllWindows()

以图2做测试,验证结果:

方法二将步骤【2】替换为通过角点检测来获取弧线端点坐标:

代码语言:javascript
复制
feature_params = dict(maxCorners = 2,
                      qualityLevel = 0.3,
                      minDistance = 50,
                      blockSize = 5 )

corners = cv2.goodFeaturesToTrack(thresh,mask=None,**feature_params)

print ('cornerNum = ' + str(len(corners)))

for i in range(0,len(corners)):
    cv2.circle(img,(int(corners[i][0][0]),int(corners[i][0][1])),8,(0,255,0),-1, cv2.LINE_AA)
cv2.imshow('cornerNum', img)

最终结果:

测试图2结果:

结果略有差异,请根据实际情况参考使用

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-06-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 OpenCV与AI深度学习 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
腾讯云服务器利旧
云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档