OpenCV检测到垂直线与水平线交叉

6ljaweal  于 2022-11-15  发布在  其他
关注(0)|答案(1)|浏览(178)

我正在尝试使用cv2.templateMatching检测一条垂直线的位置,该垂直线与一条水平线(左上角的x,y)相交。
我得到的是一个奇怪的位置,是完全不准确的。而且我想考虑到当垂直线是在水平线的边缘。
下面是我使用的代码:

image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
template = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)

image = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
template = cv2.threshold(template, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]

out = cv2.matchTemplate(image, template, cv2.TM_CCOEFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(out)

# Draw detection
cv2.circle(image, (max_loc[0], max_loc[1]), 5, (0, 255, 0), 3)

在下图中,您将看到输入、模板、当前输出、预期输出以及垂直线位于水平线边缘时的角情况:
图像链接:https://drive.google.com/file/d/1QSmihmyu8LBCHOT3_A-Q1JSmFU7LlQhU/view?usp=sharing
对于这个问题你有什么想法吗?有什么解决方案吗?使用模板匹配还是其他方法?
谢谢你,谢谢你

4ioopgfo

4ioopgfo1#

该代码有两个主要部分。首先检测垂直线和水平线,然后检查哪些垂直线与任何水平线相交。

import cv2
import numpy as np

gray = cv2.imread('image.png')
edges = cv2.Canny(gray,50,150,apertureSize = 3)
minLineLength=100
lines = cv2.HoughLinesP(image=edges,rho=1,theta=np.pi/180, threshold=100,lines=np.array([]), minLineLength=minLineLength,maxLineGap=80)

vlines = []
hlines = []
final_lines = []

a,b,c = lines.shape
for i in range(a):
    if abs(lines[i][0][1] - lines[i][0][3]) < b / 100:
        # print("horizental")
        hlines.append(lines[i][0].tolist())
    else:
        # print("vertical")
        vlines.append(lines[i][0].tolist())

def ccw(p1,p2,p3):
    return (p3[1]-p1[1]) * (p2[0]-p1[0]) > (p2[1]-p1[1]) * (p3[0]-p1[0])

# Return true if line segments l1 and l2 intersect
def intersect(l1, l2):
    return ccw((l1[0], l1[1]), (l2[0], l2[1]),(l2[2], l2[3])) != ccw((l1[2], l1[3]),(l2[0], l2[1]), (l2[2], l2[3])) and ccw((l1[0], l1[1]), (l1[2], l1[3]), (l2[0], l2[1])) != ccw((l1[0], l1[1]), (l1[2], l1[3]), (l2[2], l2[3]))

# check intersect of each vertical lines with horizenal lines
for vl in vlines:
    for hl in hlines:
        if intersect(vl, hl):
            final_lines.append(vl)
            break

print(final_lines)
for line in final_lines:
    cv2.line(gray, (line[0], line[1]), (line[2], line[3]), (0, 0, 255), 3, cv2.LINE_AA)
    cv2.imshow('vertical line',gray)
    cv2.waitKey()

输入图像:

结果图像:

相关问题