python - 使用 OpenCV 的直线角度
问题描述
我有这两张图片
黑色背景上的垂直白线
黑色背景上的水平白线
我使用以下代码来获取线的角度
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
文档中提到cv2.minAreaRect() 返回如下:(左上角(x,y),(宽度,高度),旋转角度)
但对我来说,它只返回 (center-x, center-y, angle)
顺便说一句:我想为线跟随无人机编写代码,这样我需要知道检测到的线的角度,所以我根据它调整我的无人机
解决方案
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] 度。
推荐阅读
- spring-boot - Spring JPA:避免在更新前选择
- javascript - 如果是,则重定向
- plugins - 防止 Qt5 应用程序因插件而崩溃
- c++ - 只有 operator() 的结构和普通函数之间的实际区别
- mysql - 如何使用 SQL 正确回答这个问题
- django - django如何加载url但留在同一页面
- javascript - opencart 2.0.3.1 数量加减NaN错误
- r - 从 TOC 抑制 R Markdown 标题
- three.js - 如何在 aframe/三个 js 中渲染成本更低的球体?
- asp.net - Azure Application Insights 中报告的 window.onerror 中的无效字符;ASP.Net 网络应用程序