OpenCV与AI深度学习 | 使用OpenCV检测并计算直线角度

本文来源公众号“OpenCV与AI深度学习”,仅用于学术分享,侵权删,干货满满。

原文链接:使用OpenCV检测并计算直线角度

检测线可用于各种类型的应用,例如机器人导航、无人机导航、运动分析和交通管理。本文我们将使用HoughLinesP函数来检测线条并从线条中提取角度。

检测线

    想象一下,您想要创建一架无人机或一辆可以沿着路线行驶的简单汽车。事实上,创造和使用它似乎很有趣。或者您可能想跟踪道路上的线路并根据车道对汽车进行分类。对于这些类型的程序,您需要检测线条,并且可能需要根据您的目的提取角度。OpenCV 提供了多种检测直线和提取角度的函数:

  • HoughLines()
  • HoughLinesP()

选择合适的功能

    HoughLinesP可以检测碎片或不连续线(例如图像中的虚线或线段)时更有效。它提供有关检测到的线路的更多详细信息。

    HoughLines更适合检测完整、连续的线条。当检测图像中长的、不间断的线条时,它非常有用。

    我们需要一种可以检测各种形状的线条的算法,而不仅仅是直线。例如,如果道路向右成 45 度角,则 HoughLines() 函数在这种情况下可能无效。因此,我将使用HoughLinesP()函数

HoughLinesP() 函数如何工作?

    我不会深入研究该HoughLinesP()函数的数学细节,因为 Google 或 Youtube 等平台上有很多可用的资源。下面简单解释一下该HoughLinesP()函数的工作原理:

    OpenCV 中的函数HoughLinesP使用概率霍夫变换来检测图像中的线段。

  • 从边缘检测开始提取潜在的线点,然后进行投票过程来识别经过这些点的线,在参数空间中累积投票。
  • 参数空间是霍夫变换累积投票以检测图像中的线条的地方,每个维度代表被检测模型的一个参数,例如线条的斜率和截距。
  • 在阈值化选择突出线之后,它提取由端点表示的线段,提供有关其位置和长度的详细信息。

    这种方法可有效检测碎片或不连续的线,例如虚线或线段。

HoughLinesP() 函数的参数

HoughLinesP(image, rho, theta, threshold,minLineLength,maxLineGap)

  • image:8 位、单通道输入图像。

  • rho:累加器的距离分辨率(以像素为单位)。(1在大多数情况下是有效的)

  • theta:累加器的角度分辨率(以弧度为单位)。(np.pi/180)

  • 阈值:简单的阈值。较高的阈值会导致线条更少但更准确,而较低的阈值会产生相反的效果。设置此参数的最佳方法是尝试不同的值。这完全取决于您的目的。

  • minLineLength:最小行长度。

  • maxLineGap:同一直线上的点之间允许的最大间隙以链接它们。

选择这些参数(Threshold、minLineLength 和 maxLineGap)的最佳方法是尝试不同的值组合。这些参数没有通用的最佳值;它们取决于图像的具体特征和期望的结果。

检测直线时如何使用提取的角度?

    想象一下算法从直线中提取出 67 度角。等式为:

direction_x = cos(extracted_angle=67) → velocity_x=1*direction_x
direction_y = sin(extracted_angle=67) → velocity_y=1*direction_y

步骤/代码

    1. 读取图像并将其转换为灰度

    2. 使用 Canny 边缘检测器提取边缘。  

    3. 对Canny边缘检测后得到的图像应用HoughLinesP函数。

    4. 获取 HoughLinesP 函数的输出,对其进行迭代,绘制线条,并使用简单的公式提取角度。

Canny 边缘检测

    Canny 边缘检测器创建一个二值图像,这在使用 HoughLinesP 函数之前是必不可少的。或者,可以使用其他过滤器或检测器。

    Canny 边缘检测器有助于识别图像中的边缘

检测直线并计算角度代码:

import cv2
import numpy as np
import matplotlib.pyplot as plt

# Read image
image = cv2.imread("resources/blog1.png")

# Convert image to gray
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
rgb_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

# Extract edges with Canny edge detector
edges = cv2.Canny(gray, 50, 150, apertureSize=3)

# Apply HoughLinesP
lines = cv2.HoughLinesP(edges, 1, np.pi/180, threshold=75, minLineLength=100, maxLineGap=20)

if lines is not None:
    for i, line in enumerate(lines):
        x1, y1, x2, y2 = line[0]
        dy = (y2 - y1)
        dx = (x2 - x1)
        # Convert radian to degree and extract angle
        angle = np.rad2deg(np.arctan2(dy, dx))
        # Since the Y-axis increases downwards (in OpenCV), invert the angle.
        angle = 180 - angle if angle > 0 else -angle
        # Different color for every line
        color = tuple(np.random.randint(0, 255, 3).tolist())
        # Detected line
        cv2.line(rgb_image, (x1, y1), (x2, y2), color, 3)
        # Draw shape to starting and finishing points of lines
        cv2.putText(rgb_image, '>', (x1, y1), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 3)
        cv2.putText(rgb_image, '<', (x2, y2), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 3)
        # Angle
        cv2.putText(rgb_image, str(round(angle, 1)), (x1, int((y1 + y2) / 2)), cv2.FONT_HERSHEY_SIMPLEX, 1, color, 3)

# Display the image
plt.imshow(rgb_image)
plt.show()

THE END !

文章结束,感谢阅读。您的点赞,收藏,评论是我继续更新的动力。大家有推荐的公众号可以评论区留言,共同学习,一起进步。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值