OpenCV项目之测量角度

用OpenCV测量图像中的角度

        今天Franpper给大家带来一个有趣的项目——使用OpenCV在图像中计算角度。想象一下,通过简单的点击,我们就能精确地测量出图像中任意三点形成的角度。这不仅仅是一项技术展示,更是开启我们对图像处理认知新大门的钥匙。

        首先Franpper先给大家展示一下效果   

示例1:     

 示例2:

        可以看到,当我们在图像上点击三个点时(顺序为:一条边上的某点->角的顶点->另一条边上的某点),算法会自动测量出由这三个点形成的角度。这得益于OpenCV的事件处理功能,它允许我们在图像上捕捉鼠标点击的位置,并实时显示这些点和它们之间的连线。下面正式开始今天的介绍!

目录

用OpenCV测量图像中的角度

1.  设置鼠标回调函数

2.  计算角度

3. 完整代码


1.  设置鼠标回调函数

        测量一个角需要三个点,即顶点与两条边上的各一点。设置鼠标的回调函数可以获取鼠标点击的点,并将一个角中的三个点进行连线(第二个点连第一个点,第三个点连第二个点)。

def get_mouse_points(events, x, y, flags, params):
    if events == cv2.EVENT_LBUTTONDOWN:
        size = len(point_list)

        if size != 0 and size % 3 != 0:
            cv2.line(self.image, tuple(self.point_list[-1]), (x, y), (0, 255, 0), 2)

        cv2.circle(self.image, (x, y), 5, (0, 255, 0), -1)
        self.point_list.append([x, y])
        print(self.point_list)

2.  计算角度

        获取到顶点与两条边上的各一点之后就可以计算角度了,这里Franpper给大家提供的是解三角形求角度

        具体原理如下:

实现代码为: 

def calculate_angle1(point_list):
    """

    :param point_list:
    :return:
    """
    p1, p2, p3 = np.array(point_list[-3:]) # 取出最后三个点
    # 计算两点之间的距离
    a = np.linalg.norm(p2 - p1)
    b = np.linalg.norm(p3 - p2)
    c = np.linalg.norm(p1 - p3)

    # 使用余弦定理计算每个角的余弦值
    cos_C = (a ** 2 + b ** 2 - c ** 2) / (2 * a * b)

    # 使用反余弦函数计算每个角的角度
    angle = np.arccos(cos_C) * 180 / np.pi
    print(angle)
    return angle, p2

3. 完整代码

完整的项目代码以及测试图片如下:

import cv2
import math
import numpy as np


class AngleCalculator:
    def __init__(self, image_path):
        self.point_list = []
        self.image = cv2.imread(image_path)
        self.refresh_image = self.image.copy()

    def get_mouse_points(self, events, x, y, flags, params):
        if events == cv2.EVENT_LBUTTONDOWN:
            size = len(self.point_list)

            if size != 0 and size % 3 != 0:
                cv2.line(self.image, tuple(self.point_list[-1]), (x, y), (0, 255, 0), 2)

            cv2.circle(self.image, (x, y), 5, (0, 255, 0), -1)
            self.point_list.append([x, y])
            print(self.point_list)

    def calculate_angle(self):
        p1, p2, p3 = np.array(self.point_list[-3:])
        a = np.linalg.norm(p2 - p1)
        b = np.linalg.norm(p3 - p2)
        c = np.linalg.norm(p1 - p3)
        cos_C = (a ** 2 + b ** 2 - c ** 2) / (2 * a * b)
        angle = int(np.arccos(cos_C) * 180 / np.pi)
        print(angle)
        return angle, p2

    def __call__(self):
        while True:
            if len(self.point_list) % 3 == 0 and len(self.point_list) > 0:
                angle, point = self.calculate_angle()
                cv2.putText(self.image, str(angle), (point[0] - 40, point[1] - 20),
                            cv2.FONT_HERSHEY_COMPLEX, 1.5, (0, 255, 0), 2)

            cv2.imshow('Image', self.image)
            cv2.setMouseCallback('Image', self.get_mouse_points)
            if cv2.waitKey(1) & 0xFF == ord('q'):
                self.point_list = []
                self.image = self.refresh_image.copy()


if __name__ == '__main__':
    image_path = r'E:\pythonProject\OpenCV\opencv_proj\angle.jpg'
    calculator = AngleCalculator(image_path)
    calculator()

 

 

  • 14
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Franpper

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值