这次讲的是优达学城的无人驾驶工程师的P4项目,利用车前方的摄像头检测车道线,下面开始我们的代码部分。
import numpy as np
import cv2
import glob
import matplotlib.pyplot as plt
import pickle
import matplotlib.image as mpimg
from moviepy.editor import VideoFileClip
from IPython.display import HTML
%matplotlib inline
我们先import一些我们需要的包
第二步是计算摄像机标定矩阵和给定一组棋盘图像的畸变系数。
# prepare object points, like (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0)
objp = np.zeros((6*9,3), np.float32)#构建一个72行,3列的零矩阵
objp[:,:2] = np.mgrid[0:9, 0:6].T.reshape(-1,2)#把数组变成网格的顺序
# Arrays to store object points and image points from all the images.
objpoints = [] # 3d points in real world space
imgpoints = [] # 2d points in image plane.
# Make a list of calibration images
images = glob.glob('camera_cal/calibration*.jpg')
# Step through the list and search for chessboard corners
for idx, fname in enumerate(images):
img = cv2.imread(fname)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Find the chessboard corners
ret, corners = cv2.findChessboardCorners(gray, (9,6), None)
print('number:',fname,'ret = ',ret)
# If found, add object points, image points
if ret == True:
objpoints.append(objp)
imgpoints.append(corners)
# Draw and display the corners
cv2.drawChessboardCorners(img, (9,6), corners, ret)
#write_name = 'corners_found'+str(idx)+'.jpg'
plt.figure(figsize = (8,8))
plt.imshow(img)
plt.show()
#cv2.imwrite(write_name, img)
#cv2.imshow('img', img)
#cv2.waitKey(500)
#cv2.destroyAllWindows()
输出效果如下:
第二步:对原始图像应用失真校正,这里是因为我们的摄像头拍出来的视频会有一定的畸变,所以我们要调整
img = cv2.imread('camera_cal/calibration1.jpg')
print(img.shape)
img_size = (img.shape[1],img.shape[0])
print(img_size)
# Do camera calibration given object points and image points
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, img_size,None,None)#标定
#这个函数会返回标定结果、相机的内参数矩阵、畸变系数、旋转矩阵和平移向量。
# Save the camera calibration result for later use (we won't worry about rvecs / tvecs)
dist_pickle = {}
dist_pickle["mtx"] = mtx
dist_pickle["dist"] = dist
pickle.dump( dist_pickle, open( "camera_cal/wide_dist_pickle.p", "wb" ) )
def undistort(img):
cal_pickle = pickle.load(open("camera_cal/wide_dist_pickle.p", "rb"))
mtx = cal_pickle['mtx']
dist = cal_pickle['dist']
undist = cv2.undistort(img,mtx,dist,None,mtx)
return undist
image_test = 'camera_cal/calibration1.jpg'
img_test = cv2.imread(image_test)
img_undistort = undistort(img_test)
plt.figure(figsize = (15,15))
plt.subplot(121)
plt.imshow(img_test)
plt.title('Original image')
plt.subplot(122)
plt.imshow(img_undistort)
plt.title('Undistort image')
效果图如下:
下面是真实情况下测试,可以看出差异。
image_test = 'test_images/test1.jpg'
img_test = plt.imread(image_test)
img_undistort = undistort(img_test)
plt.figure(figsize = (15,15))
plt.subplot(121)
plt.imshow(img_test)
plt.title('Original image')
plt.subplot(122)
plt.imshow(img_undistort)
plt.title('Undistort image')
第三步:使用颜色变换、渐变等创建阈值二值图像
#define functions
def grayscale(img):
return cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
def gaussian_blur(img,kernel_size):
return cv2.GaussianBlur(img,(kernel_size,kernel_size),0)
def abs_sobel_thresh(img,orient = 'x',sobel_kernel = 3,thresh = (0,255)):
gray = grayscale(img)
if orient == 'x':
abs_sobel = np.absolute(cv2.Sobel(gray,cv2.CV_64F,1,0,ksize = sobel_kernel))
if orient =