openCV实操练习(2)——角度计算器

项目Introduce:

项目名称:Angle circulator(角度计算器)

        通过鼠标点击确定顶点和两个边位置坐标,再运用角度公式,计算出角度,在原图显示结果。

项目流程预览:

        通过鼠标定点击确定顶点和两边的坐标位置,确定角度,然后通过计算公式,自定义函数完成操作。

项目与知识衔接:

        鼠标点击事件(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博客

猜你喜欢

转载自blog.csdn.net/Crabfishhhhh/article/details/128760745