優達學城無人駕駛工程師——P4車道線檢測功能
這次講的是優達學城的無人駕駛工程師的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 == 'y':
abs_sobel = np.absolute(cv2.Sobel(gray,cv2.CV_64F,0,1,ksize = sobel_kernel))
scaled_sobel = np.uint8(255 * abs_sobel / np.max(abs_sobel))
binary_output = np.zeros_like(scaled_sobel)
binary_output[(scaled_sobel >= thresh[0]) & (scaled_sobel <= thresh[1])] = 1
return binary_output
def mag_thresh(img, sobel_kernel=3, thresh=(0, 255)):
# Apply the following steps to img
# 1) Convert to grayscale
gray = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
# 2) Take the gradient in x and y separatel
sobel_x = cv2.Sobel(gray,cv2.CV_64F,1,0,ksize = sobel_kernel)
#print(sobel_x)
sobel_y = cv2.Sobel(gray,cv2.CV_64F,0,1,ksize = sobel_kernel)
# 3) Calculate the magnitude
magnitude = np.sqrt(sobel_x ** 2 + sobel_y ** 2)
# 4) Scale to 8-bit (0 - 255) and convert to type = np.uint8
scale_factor = np.max(magnitude) / 255
#print('scale_factor = ',scale_factor)
magnitude = (magnitude / scale_factor).astype(np.uint8)
# 5) Create a binary mask where mag thresholds are met
binary_output = np.zeros_like(magnitude)
# 6) Return this mask as your binary_output image
binary_output[(magnitude >= thresh[0]) & (magnitude <= thresh[1])] = 1
return binary_output
def dir_threshold(img, sobel_kernel=3, thresh=(0, np.pi/2)):
# Grayscale
gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
# Calculate the x and y gradients
sobelx = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=sobel_kernel)
sobely = cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize=sobel_kernel)
# Take the absolute value of the gradient direction,
# apply a threshold, and create a binary image result
absgraddir = np.arctan2(np.absolute(sobely), np.absolute(sobelx))
#print(absgraddir)
binary_output = np.zeros_like(absgraddir)
binary_output[(absgraddir >= thresh[0]) & (absgraddir <= thresh[1])] = 1
# Return the binary image
return binary_output
def hls_select(img, thresh=(0, 255)):
# 1) Convert to HLS color space
hls = cv2.cvtColor(img,cv2.COLOR_RGB2HLS)
# 2) Apply a threshold to the S channel
s_channel = hls[:,:,2]
# 3) Return a binary image of threshold result
binary_output = np.zeros_like(s_channel)
binary_output[(s_channel > thresh[0]) & (s_channel <thresh[1])] = 1
return binary_output
image_test = 'test_images/straight_lines1.jpg'
#img_test = cv2.imread(image_test)
img_test = plt.imread(image_test)
plt.figure(figsize = (10,10))
undist = undistort(img_test)
plt.subplot(221)
plt.imshow(undist)
plt.title('Undistorted Iamge')
cv2.imwrite('./output_images/undist.jpg',undist)
x_sobel = abs_sobel_thresh(undist,thresh = (22,100))
plt.subplot(222)
plt.imshow(x_sobel,cmap = 'gray')
plt.title('x_sobel Gradients Image')
cv2.imwrite('./output_images/x_sobel.jpg',x_sobel)
color_transforms = hls_select(undist,thresh=(150,255))
plt.subplot(223)
plt.imshow(color_transforms,cmap = 'gray')
plt.title('Color Thresh Image')
cv2.imwrite('./output_images/color_transforms.png',color_transforms)
color_x_sobel = np.zeros_like(x_sobel)
color_x_sobel[ (color_transforms == 1) | (x_sobel) == 1 ] = 1
plt.subplot(224)
plt.imshow(color_x_sobel,cmap = 'gray')
plt.title('color and granient image')
cv2.imwrite('./output_images/color_x_sobel.png',color_x_sobel)
效果圖如下:
第四步:應用透視變換來修正二值影象。(其實是把影象轉換成鳥瞰圖)
#找點
plt.imshow(color_x_sobel,cmap = 'gray')
print(color_x_sobel.shape)
# plt.plot(800,510,'x')
# plt.plot(1150,700,'x')
# plt.plot(270,700,'x')
# plt.plot(510,510,'x')
plt.plot(650,470,'x')
plt.plot(640,700,'x')
plt.plot(270,700,'x')
plt.plot(270,520,'x')
def warp(img):
img_size = (img.shape[1],img.shape[0])
src = np.float32( [ [800,510],[1150,700],[270,700],[510,510]] )
dst = np.float32( [ [650,470],[640,700],[270,700],[270,540]] )
M = cv2.getPerspectiveTransform(src,dst)
#返回透視變換的對映矩陣,就是這裡的M
#對於投影變換,我們則需要知道四個點,
#通過cv2.getPerspectiveTransform求得變換矩陣.之後使用cv2.warpPerspective獲得矯正後的圖片。
Minv = cv2.getPerspectiveTransform(dst,src)
warped = cv2.warpPerspective(img,M,img_size,flags = cv2.INTER_LINEAR)
#主要作用:對影象進行透視變換,就是變形
#https://blog.csdn.net/qq_18343569/article/details/47953843
unpersp = cv2.warpPerspective(warped, Minv, img_size, flags=cv2.INTER_LINEAR)
return warped, unpersp, Minv
warped_img,unpersp, Minv = warp(color_x_sobel)
plt.imshow(warped_img,cmap = 'gray')
plt.show()
plt.imshow(unpersp,cmap = 'gray')
plt.show()
效果如下:
第五步:檢測車道畫素,並適合找到車道邊界。def find_lines(img,print = True):
#假設您已經建立了一個被扭曲的二進位制影象,稱為“binary_warped”
#取影象下半部分的直方圖
histogram= np.sum(img[img.shape[0] //2:,:],axis = 0)
#建立一個輸出影象來繪製和視覺化結果
out_img = np.dstack((img,img,img))*255
# plt.imshow(out_img)
# plt.show()
#找出直方圖的左半邊和右半邊的峰值
#這些將是左行和右行的起點
midpoint = np.int(histogram.shape[0] // 4)
leftx_base = np.argmax(histogram[:midpoint])
#np.argmax 是返回最大值所在的位置
rightx_base = np.argmax(histogram[midpoint:]) + midpoint
#這裡是要返回右邊HOG值最大所在的位置,所以要加上midpoint
#選擇滑動視窗的數量
nwindows = 9
#設定視窗的高度
window_height = np.int(img.shape[0] // nwindows)
#確定所有的x和y位置非零畫素在影象,這裡就是吧img影象中非0元素(就是不是黑的地方就找出來,一行是x,一行是y)
nonzero = img.nonzero()
#返回numpy陣列中非零的元素
#對於二維陣列b2,nonzero(b2)所得到的是一個長度為2的元組。http://www.cnblogs.com/1zhk/articles/4782812.html
nonzeroy = np.array(nonzero[0])
nonzerox = np.array(nonzero[1])
#為每個視窗當前位置更新
leftx_current = leftx_base
rightx_current = rightx_base
#設定視窗的寬度+ / -
margin = 100
#設定最小數量的像素髮現重定位視窗
minpix = 50
#建立空的列表接收左和右車道畫素指數
left_lane_inds = []
right_lane_inds = []
#遍歷視窗
for window in range(nwindows):
#識別視窗邊界在x和y(左、右)
win_y_low = img.shape[0] - (window + 1) * window_height #就是把影象切成9分,一分一分的算HOG
#print('win_y_low',win_y_low)
win_y_high = img.shape[0] - window * window_height
win_xleft_low = leftx_current - margin
#print('win_xleft_low',win_xleft_low)
win_xleft_high = leftx_current + margin
#print('win_xleft_high = ',win_xleft_high)
win_xright_low = rightx_current - margin
#print('win_xright_low = ',win_xright_low)
win_xright_high = rightx_current + margin
#print('win_xright_high = ',win_xright_high)
#把網格畫在視覺化影象上
cv2.rectangle(out_img,(win_xleft_low,win_y_low),(win_xleft_high,win_y_high),(0,255,0),2)#通過確定對角線 畫矩形
cv2.rectangle(out_img,(win_xright_low,win_y_low),(win_xright_high,win_y_high),(0,255,0),2)
# plt.imshow(out_img)
# plt.show()
# print('left !!!! ',win_xleft_low,win_y_low,win_xleft_high,win_y_high)
# print('right !!!!! ',win_xright_low,win_y_low,win_xright_high,win_y_high)
#識別非零畫素視窗內的x和y
good_left_inds = ( (nonzeroy >= win_y_low) & (nonzeroy < win_y_high)
& (nonzerox >= win_xleft_low) & (nonzerox < win_xleft_high)).nonzero()[0]
good_right_inds = ( (nonzeroy >= win_y_low) & (nonzeroy < win_y_high)
& (nonzerox >= win_xright_low) & (nonzerox < win_xright_high)).nonzero()[0]
#新增這些指標列表
left_lane_inds.append(good_left_inds)
right_lane_inds.append(good_right_inds)
#如果上面大於minpix,重新定位下一個視窗的平均位置
if len(good_left_inds) > minpix:
leftx_current = np.int(np.mean(nonzerox[good_left_inds]))
if len(good_right_inds) > minpix:
rightx_current = np.int(np.mean(nonzerox[good_right_inds]))
#連線索引的陣列
left_lane_inds = np.concatenate(left_lane_inds)
#把list改成numpy格式而已
right_lane_inds = np.concatenate(right_lane_inds)
#提取左和右線畫素位置
leftx = nonzerox[left_lane_inds]
lefty = nonzeroy[left_lane_inds]
rightx = nonzerox[right_lane_inds]
righty = nonzeroy[right_lane_inds]
#最小二乘多項式擬合。(不懂)
left_fit = np.polyfit(lefty, leftx, 2)
right_fit = np.polyfit(righty, rightx, 2)
#畫圖
ploty = np.linspace(0,img.shape[0] -1,img.shape[0]) #用此來建立等差數列
left_fitx = left_fit[0] * ploty ** 2 + left_fit[1] * ploty +left_fit[2]
right_fitx = right_fit[0] * ploty ** 2 +right_fit[1] * ploty + right_fit[2]
#這步的意思是把曲線擬合出來,
out_img[nonzeroy[left_lane_inds], nonzerox[left_lane_inds]] = [255, 0, 0]
out_img[nonzeroy[right_lane_inds], nonzerox[right_lane_inds]] = [0, 0, 255]
if print == True:
plt.figure(figsize=(8,8))
plt.imshow(out_img)
plt.plot(left_fitx, ploty, color='yellow')
plt.plot(right_fitx, ploty, color='yellow')
plt.show()
return out_img,left_fit,right_fit
find_line_imgae,left_fit,right_fit = find_lines(warped_img)
效果如下:
第六步:確定車道和車輛位置對中心的曲率
def curvature(left_fit,right_fit,binary_warped,print_data = True):
ploty = np.linspace(0,binary_warped.shape[0] -1 , binary_warped.shape[0])
y_eval = np.max(ploty)
#y_eval就是曲率,這裡是選擇最大的曲率
ym_per_pix = 30/720#在y維度上 米/畫素
xm_per_pix = 3.7/700#在x維度上 米/畫素
#確定左右車道
leftx = left_fit[0]*ploty**2 + left_fit[1]*ploty + left_fit[2]
rightx = right_fit[0]*ploty**2 + right_fit[1]*ploty + right_fit[2]
#定義新的係數在米
left_fit_cr = np.polyfit(ploty*ym_per_pix, leftx*xm_per_pix, 2)
right_fit_cr = np.polyfit(ploty*ym_per_pix, rightx*xm_per_pix, 2)
#最小二乘法擬合
#計算新的曲率半徑
left_curverad = ((1 + (2*left_fit_cr[0]*y_eval*ym_per_pix + left_fit_cr[1])**2)**1.5) / np.absolute(2*left_fit_cr[0])
right_curverad = ((1 + (2*right_fit_cr[0]*y_eval*ym_per_pix + right_fit_cr[1])**2)**1.5) / np.absolute(2*right_fit_cr[0])
#計算中心點,線的中點是左右線底部的中間
left_lane_bottom = (left_fit[0]*y_eval)**2 + left_fit[0]*y_eval + left_fit[2]
right_lane_bottom = (right_fit[0]*y_eval)**2 + right_fit[0]*y_eval + right_fit[2]
lane_center = (left_lane_bottom + right_lane_bottom)/2.
center_image = 640
center = (lane_center - center_image)*xm_per_pix#轉換成米
if print_data == True:
#現在的曲率半徑已經轉化為米了
print(left_curverad, 'm', right_curverad, 'm', center, 'm')
return left_curverad, right_curverad, center
import glob
import os
new_path = os.path.join("test_images/","*.jpg")
for infile in glob.glob(new_path):
#讀圖
img = plt.imread(infile)
#畸變
undist = undistort(img)
#sobel運算元
x_sobel = abs_sobel_thresh(undist,thresh = (22,100))
#hls顏色閾值
color_transforms = hls_select(undist,thresh=(90,255))
#sobel加hls
color_x_sobel = np.zeros_like(x_sobel)
color_x_sobel[ (color_transforms == 1) | (x_sobel) == 1 ] = 1
#彎曲影象(warped)
print()
print('Image name = ',infile)
warped_img,unpersp, Minv = warp(color_x_sobel)
#畫線
find_line_imgae,left_fit,right_fit = find_lines(warped_img)
#算曲率
curvature(left_fit,right_fit,find_line_imgae)
第七步:將檢測到的巷道邊界扭曲回原始影象
def show_info(img,left_cur,right_cur,center):
#在圖片中顯示出曲率
cur = (left_cur + right_cur) / 2
font = cv2.FONT_HERSHEY_SIMPLEX
# 使用預設字型
cv2.putText(img,'Curvature = %d(m)' % cur,(50,50),font,1,(255,255,255),2)
#照片/新增的文字/左上角座標/字型/字型大小/顏色/字型粗細
#新增文字
if center < 0:
fangxiang = 'left'
else:
fangxiang = 'right'
cv2.putText(img,'the angle is %.2fm of %s'%(np.abs(center),fangxiang),(50,100),font,1,(255,255,255),2)
def draw_lines(undist,warped,left_fit,right_fit,left_cur,right_cur,center,show_img = True):
#建立一個全黑的底層圖去劃線
warp_zero = np.zeros_like(warped).astype(np.uint8)
color_warp = np.dstack((warp_zero,warp_zero,warp_zero))
ploty = np.linspace(0,warped.shape[0]-1,warped.shape[0])
#新增新的多項式在X軸Y軸
left_fitx = left_fit[0] * ploty**2 + left_fit[1]*ploty + left_fit[2]
right_fitx = right_fit[0] * ploty**2 + right_fit[1]*ploty + right_fit[2]
#把X和Y變成可用的形式
pts_left = np.array([np.transpose(np.vstack([left_fitx, ploty]))])
#np.transpose 轉置
pts_right = np.array([np.flipud(np.transpose(np.vstack([right_fitx, ploty])))])
#向上/向下翻轉陣列。
pts = np.hstack((pts_left, pts_right))
#填充影象
cv2.fillPoly(color_warp, np.int_([pts]), (255,0, 0))
#透視變換
newwarp = cv2.warpPerspective(color_warp, Minv, (color_warp.shape[1], color_warp.shape[0]))
#疊加圖層
result = cv2.addWeighted(undist, 1, newwarp, 0.5, 0)
show_info(result, left_cur, right_cur, center)
if show_img == True:
plt.figure(figsize = (10,10))
plt.imshow(result)
plt.show()
return result
import glob
import os
new_path = os.path.join("test_images/","*.jpg")
for infile in glob.glob(new_path):
print('the image is ',infile)
#讀圖
img = plt.imread(infile)
#畸變
undist = undistort(img)
#sobel運算元
x_sobel = abs_sobel_thresh(undist,thresh = (22,100))
#mag_thresh
mag_binary = mag_thresh(undist,thresh =(30,90))
#dir_threshold
dir_binary = dir_threshold(undist, sobel_kernel=15, thresh=(0.7, 1.3))
#hls顏色閾值
color_transforms = hls_select(undist,thresh=(150,255))
#sobel加hls
color_x_sobel = np.zeros_like(x_sobel)
color_x_sobel[ (x_sobel == 1) | (color_transforms == 1) ] = 1
#彎曲影象
warped_img, unpersp, Minv = warp(color_x_sobel)
#畫線
find_line_imgae,left_fit,right_fit = find_lines(warped_img,print = False)
#算曲率
left_curverad, right_curverad, center = curvature(left_fit,right_fit,find_line_imgae,print_data = False)
#畫圖
result = draw_lines(undist,warped_img,left_fit,right_fit,left_curverad,right_curverad,center)
第八步:輸出車道邊界的視覺化顯示和車道曲率和車輛位置的數值估計
def check(left_fit, right_fit):
#Performs a sanity check on the lanes
#1. Check if left and right fit returned a value
if len(left_fit) ==0 or len(right_fit) == 0:
status = False
else:
#Check distance b/w lines
ploty = np.linspace(0, 20, num=10 )
left_fitx = left_fit[0]*ploty**2 + left_fit[1]*ploty + left_fit[2]
right_fitx = right_fit[0]*ploty**2 + right_fit[1]*ploty + right_fit[2]
delta_lines = np.mean(right_fitx - left_fitx)
if delta_lines >= 150 and delta_lines <=430: #apprrox delta in pixels
status = True
else:
status = False
# # Calculate slope of left and right lanes at midpoint of y (i.e. 360)
# L_0 = 2*left_fit[0]*360+left_fit[1]
# R_0 = 2*right_fit[0]*360+right_fit[1]
# delta_slope_mid = np.abs(L_0-R_0)
# # Calculate slope of left and right lanes at top of y (i.e. 720)
# L_1 = 2*left_fit[0]*720+left_fit[1]
# R_1 = 2*right_fit[0]*720+right_fit[1]
# delta_slope_top = np.abs(L_1-R_1)
# #Check if lines are parallel at the middle
# if delta_slope_mid<=0.1:
# status = True
# else:
# status = False
return status
def process_video(img):
global last_left
global last_right
global left_fit
global right_fit
#畸變
undist = undistort(img)
#sobel運算元
x_sobel = abs_sobel_thresh(undist,thresh = (22,100))
#hls顏色閾值
color_transforms = hls_select(undist,thresh=(150,255))
#sobel加hls
color_x_sobel = np.zeros_like(x_sobel)
color_x_sobel[ (x_sobel == 1) | (color_transforms == 1) ] = 1
#彎曲影象
warped_img, unpersp, Minv = warp(color_x_sobel)
#畫線
find_line_imgae,left_fit,right_fit = find_lines(warped_img,print = False)
#check
status = check(left_fit,right_fit)
if status == True:
last_left , last_right = left_fit,right_fit
else:
left_fit,right_fit = last_left,last_right
#算曲率
left_curverad, right_curverad, center = curvature(left_fit,right_fit,find_line_imgae,print_data = False)
#畫圖
result = draw_lines(undist,warped_img,left_fit,right_fit,left_curverad,right_curverad,center,show_img=False)
return result
#Create video file pipeline
output = 'test_video.mp4'
clip1 = VideoFileClip("project_video.mp4")
#clip1 = VideoFileClip("project_video.mp4").subclip(20,28)
out_clip = clip1.fl_image(process_video) #NOTE: this function expects color images!!
%time out_clip.write_videofile(output, audio=False)
HTML("""
<video width="960" height="540" controls>
<source src="{0}">
</video>
""".format(output))
上述所有的圖片和視訊都可在https://github.com/udacity/CarND-Advanced-Lane-Lines下載。
相關推薦
優達學城無人駕駛工程師——P4車道線檢測功能
這次講的是優達學城的無人駕駛工程師的P4專案,利用車前方的攝像頭檢測車道線,下面開始我們的程式碼部分。import numpy as np import cv2 import glob import matplotlib.pyplot as plt import pickle
優達學城無人駕駛工程師——P1尋找車道線
這次介紹的是優達學城的無人駕駛工程師的P1專案,利用車的前攝像頭來識別當前車道的左右兩邊兩條的車道線。測試圖片和視訊在文章最後的連結裡。一開始先倒包#importing some useful packages import matplotlib.pyplot as plt
無人駕駛之高階車道線檢測-AdvanceLane_finding_release
本篇部落格整個專案原始碼:github 引言 前面我們介紹車道線檢測的處理方法:車道線檢測之lanelines-detection 在文章末尾,我們分析了該演算法的魯棒性,當時我們提出了一些解決方法,比如說: 角度濾波器:濾除極小銳角或極大鈍角的線段 選取黃色的色
【備忘】最新優達學城udacity無人駕駛工程師視訊教程
為什麼學習無人駕駛開發?無人駕駛車是現代歷史中最具開創性的進步之一。它們帶來的影響不僅僅在技術、交通或城市規劃領域,而是深入到我們生活中的每一個方面,超乎你的想象。加入這個納米學位專案,你將掌握那些能讓你塑造未來的技術。你將參與一系列互動型實戰專案,包括但不限於計算機視覺、
優達學城《無人駕駛入門》學習筆記——把python翻譯成C++
如果你學習的第一門語言是python,可能和我當初一樣,並沒有什麼特別的感受。但是,後面又學習了C++的話就會發現,python使用起來太方便了!C++的各種條條框框太多了! 作為動態語言,python不需要預先設定資料的型別,非常靈活,而代價就是執行速度慢。
零基礎如何學習優達學城的《無人駕駛入門》?
因為感興趣,而且看好無人駕駛行業,我學習了優達學城的《無人駕駛入門》課程。最近整理了無人駕駛領域的資料,寫成文章分享給大家。作為系列文章的第一篇,我想介紹一下《無人駕駛入門》這門課,課程所需要的先修知識,以及我是如何準備的。 學習這門課的收穫《無人駕駛入門》其實給我帶來了不
優達學城-神經網路之預測共享單車使用情況 程式碼分析
優達學城-神經網路之預測共享單車使用情況 程式碼分析 標籤(): 機器學習 程式碼來自於優達學城深度學習納米學位課程的第一個專案 https://cn.udacity.com/course/deep-learning-nanodegree-foundation–nd101
優達學城-深度學習筆記(一)
優達學城-深度學習筆記(一) 標籤: 機器學習 優達學城-深度學習筆記一 一 神經網路簡介 最大似然概率 交叉熵Cross entropy
優達學城(Udacity)深度學習筆記-1.Python&os學習
歡迎使用Markdown編輯器寫部落格 Python對於檔案操作非常方便,很大一部分是因為os這個庫,在做優達城深度學習作業的時候裡面有一堆os,各種列表推導式混合os.path,一下就繞暈了。這裡做點筆記,方便自己學習&複習。 如上圖,
無人駕駛工程師第二期——P5MPC
P5要重新配置一些環境 主要就是安裝Ipopt和CppAD 我的是Ubuntu14 先按照Udacity給的教程配置 sudo apt-get install gfortran sudo apt-get install unzip wget https://www
如何成為一名無人駕駛工程師
作者 | 劉少山 無人駕駛作為一項新興技術,落地為產品需要大量演算法、工程、產品貫通的AI全棧人才。筆者在最近一年招聘中發現,許多技術方向的同學對人工智慧既愛又畏懼,一方面覺得這是未來,另一方面又覺得很難而不敢觸碰。懂工程的同學做演算法時有很大的畏懼感,而專注演算法的同學又常常容易陷入某個演算法而缺
無人駕駛工程師第二期——P1擴充套件卡爾曼濾波器
這次記錄的是優達學城的無人駕駛工程師第二期的第一個專案,Extended Kalman Filters,這個專案和之前第一期的P3專案比較像,也是需要程式碼和一個程式之間連結,所以一開始的安裝步驟就會比較麻煩,文中也有說在linux上執行會比較容易,所以這篇文章就是介紹我是如
Udacity無人駕駛工程師學習筆記(一)
無人駕駛是當前一個火熱的話題,多個學科的人才開始湧入這個行業,udacity出了這門網課,在學習之餘,我想記錄下相關的知識點,以便於整理歸類,同時藉助這個平臺也能夠與大家一起討論。本人非專業人士,不足之處請多指教! 在第一學期的第一次課程中,
無人駕駛--車道線檢測實戰(附原始碼)
做完專案後寫了個技術小結,供自己回顧也為他人學習提供參考。 另外準備建一個無人駕駛方面的微信交流群,有興趣的朋友可以加我微信:wxl609278502 請註明: 姓名-單位/學校 專案描述: 使用opencv實時處理車載攝像機採集的道路影象
無人駕駛之車道線檢測簡易版
無人駕駛技術近些年發展迅速。無人車若想實現自動駕駛,從視覺的角度上講其要先學會觀察道路,具體來說,就是檢測車道線。包括識別車道線與車的位置關係,是實線還是虛線等。本文將簡單介紹車道線檢測的基本技術,包括Canny Edges、Hough Transform等
【智慧駕駛】車道線檢測中的新IPM(逆透視變換)演算法實驗效果
1、實驗內容 在車道保持LKA功能實現時,需要對車道線進行精準檢測:①、計算曲率半徑,②、保證測距精度。因此需要對相機的透檢視persImg進行IPM逆透視變換,得到俯檢視birdImg,在birdImg中進行車道線特徵檢測、擬合和測距。 基於以下思路,建立了新的IPM模型:對真實世界座
【美團點評】無人駕駛演算法工程師 2017-09-03電話面試
前言 以後關於校招的面經,全部以問題的形式寫在部落格裡面。校招季很忙,沒有那麼多時間去寫部落格,希望大家諒解。 面經 1、自我介紹 2、問簡歷上的專案,一個是模型壓縮方面的,一個是目標檢測方面的;
誰掌控無人駕駛?領域鼻祖"谷歌"專利居然排第10位
text 競賽 -i 判斷 通過 ins 企業 2017年 nom 無人駕駛大勢所趨,無論是科技公司還是傳統車企,都在搶占無人駕駛技術高地。說起誰將引領無人駕駛潮流,人們一般最先想到是科技公司如谷歌、特斯拉,但最近一份以專利數量來衡量無人駕駛技術實力的排行中,谷歌僅排在第十
沈默已久的華為突然宣告殺入無人駕駛領域,司機將全部失業!
5g 汽車 無人汽車 無人駕駛 5G要來了!5G到來後的世界,是一個萬物互聯的天下,手機將失去今天的獨霸天下的地位。而汽車,作為萬物互聯中的重要一個維度,將像今天的智能手機一樣,成為未來爭奪的重要陣地。這個陣地的最前沿入口,是智能駕駛!誰捷足先登,掌握了智能駕駛的技術和數據,誰就將掌握5G時代
現實中的大城市道路 真需要無人駕駛汽車嗎?
無人駕駛汽車相信許多80後都看過一部美國譯制片《霹靂遊俠》,筆者早已忘卻了主人公的名字,但對於那輛有生命的汽車,我卻一直記憶猶新,它的名字叫基恩,外殼堅硬,如銅墻鐵壁,抗得住子彈,甚至能把子彈反彈回去;程序設定基恩會分析路況環境,恰到好處、善解人意地同主人聊天,比之Siri懂事1000倍,自然,基恩肯定能自我