opencv中的直线拟合和直线添加
在用激光雷达数据做道路边沿检测的时候,通过像素点差分阈值大略判断出道边沿点之后,通过边沿点进行直线拟合。opencv有相关函数,先将代码写出来如下。
import cv2
import matplotlib.pyplot as plt
import numpy as np
img = cv2.imread('../depth_from_dat_update/89.jpg', cv2.IMREAD_GRAYSCALE)
list_point = []
for m in range(17, 51):
for n in range(46, 89):
differ = abs((img[m][n]-img[m][n+1]).astype('int8'))
print(m, n, ": ", img[m][n], img[m][n+1], (img[m][n]-img[m][n+1]).astype('int8'))
if differ > 5:
list_point.append((n, m)) # 坐标和行列是反的,横坐标是列,纵坐标是行
print(list_point)
element_point = np.array(list_point)
# 直线拟合,line 是四元素列表,元素分别是与直线平行的单位向量的x坐标、y坐标分量、直线上固定点的x、y分量
line = cv2.fitLine(element_point, cv2.DIST_L2, 0, 0.01, 0.01)
vx = line[0]
vy = line[1]
x = line[2]
y = line[3]
lefty = int((-x*vy/vx) + y)
righty = int(((90-x)*vy/vx)+y)
# cv2.line(img, list_point[0], list_point[-1], 0, thickness=1)
cv2.line(img, (90-1, righty), (0, lefty), 0, thickness=1)
plt.imshow(img, 'gray')
cv2.imwrite("2.jpg", img)
for循环中是产生候选点的代码,专注于直线拟合部门的同学可以不用管。opencv中直线拟合函数是fitLine,必须传入的参数是需要做拟合的点,其他可选参数包括拟合的策略,比如采用cv2.DIST_L2时,就是最小二乘拟合。该函数返回的是一个四元素列表,后两个元素是得到的直线上的固定某点的x、y坐标,前两个元素是与直线平行的单位向量的x、y分量。
直线拟合好之后,可以使用opencv提供的line函数,在图片上画出该直线,因为两点确定一条直线,因此该函数必须传入的参数就是两个固定点,可选参数包括线宽、线型等。
在本例中,两个点是拟合好的直线与图片边沿的交点,高中直线与圆学得好的同学可以看出是怎样得到的。
得到的图片如下图所示。