我在 python 和 OpenCV 中使用 LSD: LineSegmentDetector,現在的問題是我想計算檢測到的水平線數和檢測到的垂直線數。
img = cv2.imread("test/images.jpg")
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 100, 200, cv2.THRESH_BINARY_INV cv2.THRESH_OTSU)[1]
linesL = lsd(gray)
for line in linesL:
x1, y1, x2, y2, width = map(int,line)
length = line_length(x1,y1,x2,y2)
if line[-1]<3:
lines_img = cv2.line(img, (x1,y1), (x2,y2), (0,0,0),1)
show_img(lines_img,"FLD")

線陣列 [[x1,y1,x2,y2,width],....]
我也嘗試過形態學操作和 houghlinesP,但它們表現不佳。
uj5u.com熱心網友回復:
正如你知道端點的坐標,你可以簡單地計算線的斜率
slope = (y2 - y1) / (x2 - x1)
如果斜率是 0,那么這條線是水平的,如果它是無窮大,那么這條線是垂直的。在實踐中,您很少會遇到等于 0 或無窮大的斜率。因此,只需設定一個閾值,例如:
if abs(slope) < 1:
print("It's an horizontal line!")
elif abs(slope) > 100:
print("It's a vertical line!")
else:
print("It's... a line!")
如果您真的只關心水平線和垂直線,另一種簡單的解決方案是比較 x 值和 y 值:
if abs(x1 - x2) < 5:
print("It's a vertical line!")
elif abs(y1 - y2) < 5:
print("It's an horizontal line!")
else:
print("It's... a line!")
編輯:我將絕對值添加到斜率比較中。
uj5u.com熱心網友回復:
我們可以使用斜率來解決這個問題。我們知道以角度為單位的直線的斜率將是s 和sarctan之差的比值yx
slope_as_angle = atan((y1 - y2) / (x1 - x2))
使用atan2代替atan. 為簡單起見,讓我們使用度數而不是弧度:
slope_as_angle = math.degrees(math.atan2((y1 - y2), (x1 - x2)))
現在讓我們看看不同傾斜角度的線條會是什么樣子:
for i in range(0, 360, 20):
x = 10 * math.cos(math.radians(i))
y = 10 * math.sin(math.radians(i))
spl = math.degrees(math.atan2(y - 0, x - 0)) % 360
plt.plot([0, x], [0, y], label=str(i))
plt.legend()
plt.show()
請注意我們得到的傾斜角度為所有線路(0,0)和(之間cos,sin)(見:
現在我們需要一個邏輯來理解給定傾斜角的線是垂直還是水平:
水平的
我會說斜角在 [160, 200] 或大于 340 或小于 20 的每條線是水平的。
if 160 < angle < 200 or 340 < angle or angle < 20
更好的方法:
if 160 < angle < 200 or not 20 < angle < 340
垂直的
I would say each line with slope angles between [60, 120] or [240, 300] is vertical.
if 60< angle < 120 or 240 < angle < 300.
Let's assign a limit variable as a threshold so we can change it as will:
for horizontal lines:
if (not limit < spl <= 360 - limit) or (180 - limit <= spl < 180 limit):
for vertical lines:
if (90 - limit < spl < 90 limit) or (270 - limit < spl < 270 limit):
The code to check would be:
def check_the_line(slope, limit=10):
if (not limit < spl <= 360 - limit) or (180 - limit <= spl < 180 limit):
return "h"
elif (90 - limit < spl < 90 limit) or (270 - limit < spl < 270 limit):
return "v"
return "o"
Let's validate:
import math
from matplotlib import pyplot as plt
fig, (ax1, ax2, ax3) = plt.subplots(3, 1)
limit = 10
def check_the_line(slope, limit=10):
if (not limit < spl <= 360 - limit) or (180 - limit <= spl < 180 limit):
return "h"
elif (90 - limit < spl < 90 limit) or (270 - limit < spl < 270 limit):
return "v"
return "o"
for i in range(0, 360, 1):
x = 10 * math.cos(math.radians(i))
y = 10 * math.sin(math.radians(i))
spl = math.degrees(math.atan2(y, x)) % 360
ax1.plot([0, x], [0, y])
if check_the_line(spl, limit=limit) == "h":
ax2.plot([0, x], [0, y])
elif check_the_line(spl, limit=limit) == "v":
ax3.plot([0, x], [0, y])
ax1.set_title("All lines")
ax1.set_xlim([-10, 10])
ax1.set_ylim([-10, 10])
ax2.set_title("Horizontal Lines")
ax2.set_xlim([-10, 10])
ax2.set_ylim([-10, 10])
ax3.set_title("Vertical Lines")
ax3.set_xlim([-10, 10])
ax3.set_ylim([-10, 10])
plt.show()

轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/357742.html
標籤:Python opencv 数学 计算机视觉 图像分割
上一篇:3皇后問題有通用的公式嗎?
