需求描述
- 在一张CAD图上需要知道墙角,并且标注出来,设想先检测出两面墙壁,即两条直线,然后计算线的交点即可
解决过程
- 首先要在python里面opencv库,之后读取图片,然后是直线检测前常规性的转灰度图、高斯模糊、边缘检测,再用获夫变换检测直线。
# -*- coding: UTF-8 -*-
import cv2
import numpy as np
#图片路径
imgPath="xxx.png"
img=cv2.imread(imgPath)
#转灰度图
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#高斯模糊
gray=cv2.GaussianBlur(gray,(3,3),0)
#边缘检测
edges = cv2.Canny(gray, 400, 400)
#霍夫变换
lines = cv2.HoughLinesP(edges, 1, np.pi / 180, 25, minLineLength=650, maxLineGap=8)
- 计算两条直线的交点函数
def cross_point(line1, line2): # 计算交点函数
#是否存在交点
point_is_exist=False
x=0
y=0
x1 = line1[0] # 取四点坐标
y1 = line1[1]
x2 = line1[2]
y2 = line1[3]
x3 = line2[0]
y3 = line2[1]
x4 = line2[2]
y4 = line2[3]
if (x2 - x1) == 0:
k1 = None
else:
k1 = (y2 - y1) * 1.0 / (x2 - x1) # 计算k1,由于点均为整数,需要进行浮点数转化
b1 = y1 * 1.0 - x1 * k1 * 1.0 # 整型转浮点型是关键
if (x4 - x3) == 0: # L2直线斜率不存在操作
k2 = None
b2 = 0
else:
k2 = (y4 - y3) * 1.0 / (x4 - x3) # 斜率存在操作
b2 = y3 * 1.0 - x3 * k2 * 1.0
if k1 is None:
if not k2 is None:
x = x1
y = k2 * x1 + b2
point_is_exist=True
elif k2 is None:
x=x3
y=k1*x3+b1
elif not k2==k1:
x = (b2 - b1) * 1.0 / (k1 - k2)
y = k1 * x * 1.0 + b1 * 1.0
point_is_exist=True
return point_is_exist,[x, y]
- 完整代码
# -*- coding: UTF-8 -*-
import cv2
import numpy as np
def cross_point(line1, line2): # 计算交点函数
#是否存在交点
point_is_exist=False
x=0
y=0
x1 = line1[0] # 取四点坐标
y1 = line1[1]
x2 = line1[2]
y2 = line1[3]
x3 = line2[0]
y3 = line2[1]
x4 = line2[2]
y4 = line2[3]
if (x2 - x1) == 0:
k1 = None
else:
k1 = (y2 - y1) * 1.0 / (x2 - x1) # 计算k1,由于点均为整数,需要进行浮点数转化
b1 = y1 * 1.0 - x1 * k1 * 1.0 # 整型转浮点型是关键
if (x4 - x3) == 0: # L2直线斜率不存在操作
k2 = None
b2 = 0
else:
k2 = (y4 - y3) * 1.0 / (x4 - x3) # 斜率存在操作
b2 = y3 * 1.0 - x3 * k2 * 1.0
if k1 is None:
if not k2 is None:
x = x1
y = k2 * x1 + b2
point_is_exist=True
elif k2 is None:
x=x3
y=k1*x3+b1
elif not k2==k1:
x = (b2 - b1) * 1.0 / (k1 - k2)
y = k1 * x * 1.0 + b1 * 1.0
point_is_exist=True
return point_is_exist,[x, y]
#图片路径
imgPath="xxx.png"
img=cv2.imread(imgPath)
#转灰度图
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#高斯模糊
gray=cv2.GaussianBlur(gray,(3,3),0)
#边缘检测
edges = cv2.Canny(gray, 400, 400)
#霍夫变换
lines = cv2.HoughLinesP(edges, 1, np.pi / 180, 25, minLineLength=650, maxLineGap=8)
lines1 =lines[:, 0, :]# 提取为二维
for x1, y1, x2, y2 in lines1[:]:
cv2.line(img, (x1, y1), (x2, y2), (0, 0, 255), 2)
for x1, y1, x2, y2 in lines1[:]:
for x3,y3,x4,y4 in lines1[:]:
point_is_exist, [x, y]=cross_point([x1, y1, x2, y2],[x3,y3,x4,y4])
if point_is_exist:
cv2.circle(img,(int(x),int(y)),5,(0,0,255),3)
cv2.imshow('Result', img)
cv2.waitKey (0)
遗留问题
- 直线检测部分本来想尝试LSD直线检测算法,网上找到的代码如下
lsd=cv2.createLineSegmentDetector(0)
lines=lsd.detect(img)[0]
drawn_img=lsd.drawSegments(img,lines)
cv2.imshow("LSD",drawn_img )
cv2.waitKey(0)
但是运行的时候会遇到如下问题,以后有机会可以尝试去解决一下。
Traceback (most recent call last):
File "LineDetect.py", line 61, in <module>
lsd=cv2.createLineSegmentDetector(0)
cv2.error: OpenCV(4.1.0) /Users/travis/build/skvark/opencv-python/opencv/modules/imgproc/src/lsd.cpp:143: error: (-213:The function/feature is not implemented) Implementation has been removed due original code license issues in function 'LineSegmentDetectorImpl'
版权声明:本文为qq_33004317原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。