【问题标题】:Angle of a line using OpenCV使用 OpenCV 的直线角度
【发布时间】:2021-02-04 18:02:22
【问题描述】:

我有这两张图片

黑色背景上的垂直白线

黑色背景上的水平白线

我使用下面的代码来获取直线的角度

import numpy as np
import cv2
x = cv2.imread('ver.png') 
cv_image = cv2.cvtColor(x, cv2.COLOR_RGB2GRAY)
ret, thresh = cv2.threshold(cv_image,70,255,cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
recta = cv2.minAreaRect(contours[0])
center_x, center_y, angle = recta
print (angle)

但两个图像的打印角度值相同,即 -90

documentation 中提到 cv2.minAreaRect() 返回如下: (左上角(x,y), (width, height), 旋转角度)

但对我来说,它只返回 (center-x, center-y, angle)

顺便说一句:我想为线跟随无人机编写代码,以便我需要知道检测到的线的角度,因此我根据它调整我的无人机

【问题讨论】:

    标签: python opencv image-processing computer-vision


    【解决方案1】:

    minAreaRect 为两者打印 -90,因为它为这些线定义了不同的矩形(您可以交换宽度和高度并最终得到相同的矩形)。如果您需要可以区分它们的东西,那么您可以取矩形角并找到较长的边。您可以使用该线来计算角度。

    以下代码将区分两者(水平为 0 度,垂直为 -89.999999 度)。它应该在 [-90, 90] 度之间(相对于屏幕底部)。

    import numpy as np
    import cv2
    import math
    
    # 2d distance
    def dist2D(one, two):
        dx = one[0] - two[0];
        dy = one[1] - two[1];
        return math.sqrt(dx*dx + dy*dy);
    
    # angle between three points (the last point is the middle)
    def angle3P(p1, p2, p3):
        # get distances
        a = dist2D(p3, p1);
        b = dist2D(p3, p2);
        c = dist2D(p1, p2);
    
        # calculate angle // assume a and b are nonzero
        # (law of cosines)
        numer = c**2 - a**2 - b**2;
        denom = -2 * a * b;
        if denom == 0:
            denom = 0.000001;
        rads = math.acos(numer / denom);
        degs = math.degrees(rads);
    
        # check if past 90 degrees
        return degs;
    
    # get the rotated box
    x = cv2.imread('horizontal.png') 
    cv_image = cv2.cvtColor(x, cv2.COLOR_RGB2GRAY)
    ret, thresh = cv2.threshold(cv_image,70,255,cv2.THRESH_BINARY)
    _, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    recta = cv2.minAreaRect(contours[0])
    center_x, center_y, angle = recta
    
    # get the corners
    box = cv2.boxPoints(recta)
    box = np.int0(box)
    
    # choose the first point
    root = box[0];
    
    # find the longer side
    end = None;
    one = box[-1];
    two = box[1];
    if dist2D(one, root) > dist2D(two, root):
        end = one;
    else:
        end = two;
    
    # take the left-most point
    left_point = None;
    right_point = None;
    if end[0] < root[0]:
        left_point = end;
        right_point = root;
    else:
        left_point = root;
        right_point = end;
    
    # calculate the angle [-90, 90]
    offshoot = [left_point[0] + 100, left_point[1]];
    angle = angle3P(right_point, offshoot, left_point);
    if left_point[1] > right_point[0]:
        angle = -angle;
    print(angle);
    

    编辑:

    糟糕,我的方向搞混了。我编辑了代码,现在应该是 [-90, 90] 度。

    【讨论】:

      猜你喜欢
      • 2018-07-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多