通过鼠标点击确定顶点和两个边位置坐标,再运用角度公式,计算出角度,在原图显示结果。
项目流程预览:
通过鼠标定点击确定顶点和两边的坐标位置,确定角度,然后通过计算公式,自定义函数完成操作。
鼠标点击事件(setMouseCallback)、文字绘制(putText)......
1.导入工具包(库)
import cv2
import math
2.导入需要运算角度的图像,创建一个空列表(pointsList)存放顶点和两边的位置数据:
path = 'D:/works/pyton_pic/Angle/Angle.png'
img = cv2.imread(path)
pointsList = []
3.自定义鼠标点击(mousePoints)、梯度运算(gradient)、角度计算(getAngle)函数:
#mousePoints函数
def mousePoints(event,x,y,flags,params):
#if:鼠标左键点击
if event == cv2.EVENT_LBUTTONDOWN:
#计算列表长度,因为第一个点不需要连线
size = len(pointsList)
#点与点之间连线
if size != 0 and size % 3 != 0:
cv2.line(img,tuple(pointsList[round((size - 1) / 3) * 3]),(x,y),(0,0,255),2)
#画点
cv2.circle(img,(x,y),5,(0,0,255),cv2.FILLED)
pointsList.append([x,y])
#进行梯度运算
def gradient(pt1,pt2):
return (pt2[1] - pt1[1]) / (pt2[0] - pt1[0])
#获得角度的函数。并将其绘制在图上
def getAngle(pointsList):
pt1,pt2,pt3 = pointsList[-3:]
m1 = gradient(pt1,pt2)
m2 = gradient(pt1,pt3)
angR = math.atan((m2 - m1) / (1 + (m2 * m1)))
angD = round(math.degrees(angR))
cv2.putText(img,str(angD),(pt1[0] - 40,pt1[1] - 20),cv2.FONT_HERSHEY_COMPLEX,1.5,(0,0,255),2)
4 . 代码主段,通过创建窗口实现鼠标点击事件响应,调用相关函数,实现角度计算。
while True:
if len(pointsList) % 3 == 0 and len(pointsList) != 0:
getAngle(pointsList)
img = cv2.resize(img,(1044,614))
cv2.imshow('Image',img)
#setMouseCallback(),点击后得到响应,第二个参数为点击后要执行的函数。
cv2.setMouseCallback('Image',mousePoints)
#键盘输入‘q’,重新刷新
if cv2.waitKey(1) & 0xFF == ord('q'):
pointsList = []
img = cv2.imread(path)
#键盘输入‘w’,退出循环
elif cv2.waitKey(1) & 0xFF == ord('w'):
break
pycharm+openCV,无需预设参数
#导入库
import cv2
import math
#读入图像、指定存放坐标值的空列表
path = 'D:/works/pyton_pic/Angle/Angle.png'
img = cv2.imread(path)
pointsList = []
#mousePoints函数
def mousePoints(event,x,y,flags,params):
#if:鼠标左键点击
if event == cv2.EVENT_LBUTTONDOWN:
#计算列表长度,因为第一个点不需要连线
size = len(pointsList)
#点与点之间连线
if size != 0 and size % 3 != 0:
cv2.line(img,tuple(pointsList[round((size - 1) / 3) * 3]),(x,y),(0,0,255),2)
#画点
cv2.circle(img,(x,y),5,(0,0,255),cv2.FILLED)
pointsList.append([x,y])
#进行梯度运算(斜率)
def gradient(pt1,pt2):
return (pt2[1] - pt1[1]) / (pt2[0] - pt1[0])
#获得角度的函数。并将其绘制在图上
def getAngle(pointsList):
pt1,pt2,pt3 = pointsList[-3:]
m1 = gradient(pt1,pt2)
m2 = gradient(pt1,pt3)
angR = math.atan((m2 - m1) / (1 + (m2 * m1)))
angD = round(math.degrees(angR))
cv2.putText(img,str(angD),(pt1[0] - 40,pt1[1] - 20),cv2.FONT_HERSHEY_COMPLEX,1.5,(0,0,255),2)
while True:
if len(pointsList) % 3 == 0 and len(pointsList) != 0:
getAngle(pointsList)
img = cv2.resize(img,(1044,614))
cv2.imshow('Image',img)
#setMouseCallback(),点击后得到响应,第二个参数为点击后要执行的函数。
cv2.setMouseCallback('Image',mousePoints)
#键盘输入‘q’,重新刷新
if cv2.waitKey(1) & 0xFF == ord('q'):
pointsList = []
img = cv2.imread(path)
#键盘输入‘w’,退出循环
elif cv2.waitKey(1) & 0xFF == ord('w'):
break
结果准确度需要靠鼠标点击,鼠标点击准确即准确,总体来说准确度可行。
角度展示有时候会超出图像尺寸范围,文字绘制的位置有待更改
按‘w’退出循环的时候希望实现窗口关闭,可以在内循环添加cv2.destroyAllWindow()实现窗口关闭
opencv角度测量 - 搜索结果 - 知乎
Opencv项目实战:02 角度探测器_opencv实现角度识别_夏天是冰红茶的博客-CSDN博客
使用opencv进行角度测量_opencv角度测量_啥都想学点的研究生的博客-CSDN博客