使用OpenCV检测并计算直线角度

文摘   2024-11-14 07:45   重庆  

点击下方卡片,关注“OpenCV与AI深度学习

视觉/图像重干货,第一时间送达! 

   检测线可用于各种类型的应用,例如机器人导航、无人机导航、运动分析和交通管理。本文我们将使用HoughLinesP函数来检测线条并从线条中提取角度。
检测线
    想象一下,您想要创建一架无人机或一辆可以沿着路线行驶的简单汽车。事实上,创造和使用它似乎很有趣。或者您可能想跟踪道路上的线路并根据车道对汽车进行分类。对于这些类型的程序,您需要检测线条,并且可能需要根据您的目的提取角度。OpenCV 提供了多种检测直线和提取角度的函数:
    • HoughLines()
    • HoughLinesP()

选择合适的功能

    HoughLinesP可以检测碎片或不连续线(例如图像中的虚线或线段)时更有效。它提供有关检测到的线路的更多详细信息。
    HoughLines更适合检测完整、连续的线条。当检测图像中长的、不间断的线条时,它非常有用。
    我们需要一种可以检测各种形状的线条的算法,而不仅仅是直线。例如,如果道路向右成 45 度角,则 HoughLines() 函数在这种情况下可能无效。因此,我将使用HoughLinesP()函数
HoughLinesP() 函数如何工作?
    我不会深入研究该HoughLinesP()函数的数学细节,因为 Google 或 Youtube 等平台上有很多可用的资源。下面简单解释一下该HoughLinesP()函数的工作原理:
    OpenCV 中的函数HoughLinesP使用概率霍夫变换来检测图像中的线段。
    • 从边缘检测开始提取潜在的线点,然后进行投票过程来识别经过这些点的线,在参数空间中累积投票。
    • 参数空间是霍夫变换累积投票以检测图像中的线条的地方,每个维度代表被检测模型的一个参数,例如线条的斜率和截距。
    • 在阈值化选择突出线之后,它提取由端点表示的线段,提供有关其位置和长度的详细信息。
    这种方法可有效检测碎片或不连续的线,例如虚线或线段,与传统方法(如HoughLines.
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 边缘检测器有助于识别图像中的边缘

检测直线并计算角度代码:
# read imageimage = cv2.imread("resources/blog1.png")# conert image to graygray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)rgb_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# extract edges with canny edge detectoredges = cv2.Canny(gray, 50, 150, apertureSize=3)
# apply HoughLinesP# cv2.HoughLinesP() returns an array of lines detected in the image.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)
plt.imshow(rgb_image)

—THE END—

下载1:Pytorch常用函数手册

在「OpenCV与AI深度学习公众号后台回复:Pytorch函数手册即可下载学习全网第一份Pytorch函数常用手册,包括Tensors介绍、基础函数介绍、数据处理函数、优化函数、CUDA编程、多处理等十四章内容。

下载2:145个OpenCV实例应用代码
在「OpenCV与AI深度学习」公众号后台回复:OpenCV145即可下载学习145个OpenCV实例应用代码(Python和C++双语言实现)。

欢迎加入CV学习交流微信

觉得有用,记得点个赞和在看 

OpenCV与AI深度学习
专注计算机视觉、深度学习和人工智能领域干货、应用、行业资讯的分享交流!
 最新文章