详解车道线检测算法之传统图像处理

智车科技IV
关注

绘制车道线

# 定义左右车道线的点集合right_list = []left_list = []

# 根据霍夫变换得到的线段,绘制左右各一条车道线if lines is not None:    for line in lines:        for x1,y1,x2,y2 in line:            if (y1 - y2) / (x1 - x2) > 0:# right side                right_list.append([x1,y1,x2,y2,(y2-y1)/(x2-x1),(x1*y2-x2*y1)/(x1-x2)])            else:# left side                left_list.append([x1,y1,x2,y2,(y2-y1)/(x2-x1),(x1*y2-x2*y1)/(x1-x2)])# 通过计算斜率,筛选得到最优车道线    if len(right_list) != 0:        [k_right_mean,b_right_mean,x_list,y_list] = filter_lines(right_list)        y1_right = img.shape[0]-60        x1_right = (y1_right - b_right_mean) / k_right_mean        y2_right = img.shape[0]*.65 #min(y_right)        x2_right = (y2_right - b_right_mean) / k_right_mean                cv2.line(img, (np.int32(x1_right),  np.int32(y1_right)), (np.int32(x2_right),  np.int32(y2_right)), [255,0,0], thickness)           if len(left_list) != 0:        [k_left_mean,b_left_mean,x_list,y_list] = filter_lines(left_list)        y1_left = img.shape[0]-60        x1_left = (y1_left - b_left_mean) / k_left_mean        y2_left = img.shape[0]*.65 #min(y_left)        x2_left = (y2_left - b_left_mean) / k_left_mean        cv2.line(img, (np.int32(x1_left),  np.int32(y1_left)), (np.int32(x2_left),  np.int32(y2_left)), color, thickness)  
def filter_lines(xy_kb_list):    n = 3    k_list = [xy_kb[4] for xy_kb in xy_kb_list]    mean = np.mean(k_list)    std = np.std(k_list)    good_k_list = []    good_b_list = []    good_x_list = []    good_y_list = []    for [x1, y1, x2, y2, k, b] in xy_kb_list:        if k < mean + n*std:            good_k_list.append(k)            good_b_list.append(b)            good_x_list.append(x1)            good_x_list.append(x2)            good_y_list.append(y1)            good_y_list.append(y2)    if not good_x_list:        good_k_list = k_list        good_b_list = [xy_kb[5] for xy_kb in xy_kb_list]        good_x_list = [xy_kb[0] for xy_kb in xy_kb_list] + [xy_kb[2] for xy_kb in xy_kb_list]        good_y_list = [xy_kb[1] for xy_kb in xy_kb_list] + [xy_kb[3] for xy_kb in xy_kb_list]    k_mean = np.median(good_k_list)    b_mean = np.median(good_b_list)        return k_mean,b_mean,good_x_list,good_y_list

将算法应用于视频

output = 'test_video_output.mp4'

from moviepy.editor import VideoFileClip

clip1 = VideoFileClip("test_video.mp4")white_clip = clip1.fl_image(process_image) %time white_clip.write_videofile(output , audio=False)

高级车道线检测算法--曲线

计算相机校正矩阵和失真系数

# 使用提供的一组棋盘格图片计算相机校正矩阵(camera calibration matrix)和失真系数(distortion coefficients).

objpoints = [] imgpoints = [] 

for ny in [5,6]:    for nx in [6,7,8,9]:        objp = np.zeros((ny*nx,3), np.float32)        objp[:,:2] = np.mgrid[0:nx, 0:ny].T.reshape(-1,2)
       for idx, fname in enumerate(images):            img = cv2.imread(fname)            gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)            # 使用cv2自动寻找棋盘corners            ret, corners = cv2.findChessboardCorners(gray, (nx,ny), None)            if ret == True:                objpoints.append(objp)                imgpoints.append(corners)                # 绘制corners                cv2.drawChessboardCorners(img, (nx,ny), corners, ret)                image_name=os.path.split(fname)[1]                write_name = out_dir_cam+'corners_found_ny'+str(ny)+'_nx'+str(nx)+'_'+image_name                cv2.imwrite(write_name, img)                print(fname)                plt.imshow(img)

# Test undistortion on an imageimg = cv2.imread('camera_cal/calibration.jpg')img_size = (img.shape[1], img.shape[0])

# Do camera calibration given object points and image pointsret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, img_size,None,None)dst = cv2.undistort(img, mtx, dist, None, mtx)

# 保存相机校正矩阵和失真系数结果dist_pickle = {}dist_pickle["mtx"] = mtxdist_pickle["dist"] = distpickle.dump(dist_pickle, open( "camera_dist_pickle.p", "wb" ) )

校正车道线图片

使用计算好的相机校正矩阵(camera calibration matrix)和失真系数(distortion coefficients)校正车道线图片。

# 打开相机校正矩阵和失真系数结果with open('camera_dist_pickle.p', mode='rb') as f:    dist_pickle = pickle.load(f)    mtx = dist_pickle["mtx"]    dist = dist_pickle["dist"]

# 应用于车道线图片images = glob.glob('test_images.jpg')

for idx, fname in enumerate(images):    img = cv2.imread(fname)    dst = cv2.undistort(img, mtx, dist, None, mtx)    image_name=os.path.split(fname)[1]    write_name = out_dir_img+'undistorted_'+image_name    cv2.imwrite(write_name,dst)    print(write_name)

组合阈值处理

# 转换到HLS颜色空间(也可尝试其他颜色空间)hls = cv2.cvtColor(img, cv2.COLOR_RGB2HLS).astype(np.float)l_channel = hls[:,:,1]s_channel = hls[:,:,2]

# 使用Sobel算法在x方向进行阈值处理sobelx = cv2.Sobel(l_channel, cv2.CV_64F, 1, 0)abs_sobelx = np.absolute(sobelx) scaled_sobel = np.uint8(255*abs_sobelx/np.max(abs_sobelx))

声明: 本文由入驻OFweek维科号的作者撰写,观点仅代表作者本人,不代表OFweek立场。如有侵权或其他问题,请联系举报。
侵权投诉

下载OFweek,一手掌握高科技全行业资讯

还不是OFweek会员,马上注册
打开app,查看更多精彩资讯 >
  • 长按识别二维码
  • 进入OFweek阅读全文
长按图片进行保存