这次讲的是优达学城的无人驾驶工程师的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 cornersret, corners = cv2.findChessboardCorners(gray, (9,6), None)print('number:',fname,'ret = ',ret)# If found, add object points, image pointsif ret == True:objpoints.append(objp)imgpoints.append(corners)# Draw and display the cornerscv2.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])] = 1return binary_outputdef mag_thresh(img, sobel_kernel=3, thresh=(0, 255)):# Apply the following steps to img# 1) Convert to grayscalegray = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)# 2) Take the gradient in x and y separatelsobel_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.uint8scale_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 metbinary_output = np.zeros_like(magnitude)# 6) Return this mask as your binary_output imagebinary_output[(magnitude >= thresh[0]) & (magnitude <= thresh[1])] = 1return binary_outputdef dir_threshold(img, sobel_kernel=3, thresh=(0, np.pi/2)):# Grayscalegray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)# Calculate the x and y gradientssobelx = 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 resultabsgraddir = 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 imagereturn binary_outputdef hls_select(img, thresh=(0, 255)):# 1) Convert to HLS color spacehls = cv2.cvtColor(img,cv2.COLOR_RGB2HLS)# 2) Apply a threshold to the S channels_channel = hls[:,:,2]# 3) Return a binary image of threshold resultbinary_output = np.zeros_like(s_channel)binary_output[(s_channel > thresh[0]) & (s_channel <thresh[1])] = 1return 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/47953843unpersp = 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.htmlnonzeroy = np.array(nonzero[0])nonzerox = np.array(nonzero[1])#为每个窗口当前位置更新leftx_current = leftx_baserightx_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_heightwin_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和ygood_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 = 640center = (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加hlscolor_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) / 2font = 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_threshmag_binary = mag_thresh(undist,thresh =(30,90))#dir_thresholddir_binary = dir_threshold(undist, sobel_kernel=15, thresh=(0.7, 1.3))#hls颜色阈值color_transforms = hls_select(undist,thresh=(150,255))#sobel加hlscolor_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 valueif len(left_fit) ==0 or len(right_fit) == 0:status = Falseelse:#Check distance b/w linesploty = 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 pixelsstatus = Trueelse: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 = Falsereturn status
def process_video(img):global last_left global last_rightglobal left_fitglobal 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加hlscolor_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)#checkstatus = check(left_fit,right_fit)if status == True:last_left , last_right = left_fit,right_fitelse: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车道线检测功能相关推荐

  1. 【自动驾驶技术】优达学城无人驾驶工程师学习笔记(六)——Github与Markdown相关教程

    Github与Markdown相关教程 本博文为笔者关于优达学城无人驾驶工程师课程中计算机视觉基础部分的学习笔记,该部分为实现车道线图像识别功能的基础课程,关于本课程的详细说明请参考优达学城官网. 优 ...

  2. 【自动驾驶技术】优达学城无人驾驶工程师学习笔记(七)——计算机视觉基础

    计算机视觉基础目录 前言 颜色选择(Color Selection) 理论基础 代码实践 区域筛选(Region Masking) 理论基础 代码实践 Canny边缘检测 问题背景 Canny边缘检测 ...

  3. 优达学城无人驾驶工程师——P5车辆检测功能

    这次讲的是优达学城无人驾驶工程师第一期的最后一个项目,车辆检测功能,代码如下. 导包 import cv2 import numpy as np import matplotlib.pyplot as ...

  4. 优达学城无人驾驶工程师——P1寻找车道线

    这次介绍的是优达学城的无人驾驶工程师的P1项目,利用车的前摄像头来识别当前车道的左右两边两条的车道线.测试图片和视频在文章最后的链接里. 一开始先倒包 #importing some useful p ...

  5. 优达学城无人驾驶工程师——P2交通路牌识别

    这次是P2项目--交通路牌识别,用到的是简单的卷积网络,2层的卷积层加上4层全连接层,因为用的数据集的图片大小是32x32的,所以不用很复杂的神经网络. 数据地址在这里:https://s3-us-w ...

  6. 优达学城计算机视觉pkl,优达学城机器学习工程师纳米学位项目介绍

    本文由 meelo 原创,请务必以链接形式注明 本文地址,简书同步更新地址 一对一的项目辅导是优达学城纳米学位的一大亮点.本文将简要介绍优达学城机器学习工程师纳米学位的6个项目.项目覆盖了机器学习的主 ...

  7. 优达学城 数据工程师 2020

    虽然优达学城(中国)已经退出,但是优达学城的课程质量还是可以的,并且多门课程相辅相成,比如数据科学类就包含了数据工程师,数据科学家,数据分析,以及使用python语言的编程,所以还是很有价值的,并且英 ...

  8. 学习优达学城《无人驾驶入门》,你可能会关心的问题

    优达学城的<无人驾驶入门>是一门学习无人驾驶的基础课程,我在<零基础如何学习优达学城的<无人驾驶入门>?>中介绍了学习这门课的先修知识,这篇文章来说一说对于这门课, ...

  9. 无人驾驶8: 粒子滤波定位(优达学城项目)

    优达学城无人车定位的项目实现: 粒子滤波算法流程图 粒子滤波的伪代码: step1:初始化 理论上说,当粒子数量足够多时,能准确地呈现贝叶斯后验分布,如果粒子太少,可能漏掉准确位置,粒子数量太多,会拖 ...

最新文章

  1. servlet的 session什么时候用_抖音什么时候用dou+
  2. 求补码表示为10000000的真值
  3. Deseq2的理论基础
  4. mysql mybatis配置_mybatis详解 与配置mybatis+spring+mysql.doc
  5. .Net Core 之 MSBuild 介绍
  6. AUTOSAR从入门到精通100讲(七)-CAN总线简介及特点
  7. cocos2dx3.2文件结构和代码结构
  8. 可输入可下拉的输入选择框
  9. 让目标检测和实例分割互相帮助,地平线实习生论文被AAAI 2020收录
  10. docker 安装azkaban_docker总结
  11. BeautifulSoup库用法总结
  12. 对于NAS,IP SAN以及iSCSCI SAN存储的一些认识和理解
  13. Cocos2dx--Cocos2dx与Android平台的跨平台调用
  14. Echarts教程篇:概览
  15. IFIX组态----安全与权限配置
  16. 如何将OGG文件转换成MP3?
  17. 标识符的命名规则及命名规范
  18. 齐次线性方程组与非齐次线性方程组的区别
  19. 企业邮箱能帮企业带来哪些好处?
  20. bzoj4238: 电压

热门文章

  1. 数据指标体系的构建思路
  2. 光场相机模拟程序解读
  3. Ledger-复式记账的一个功能强大的命令行工具
  4. 【OpenCV 4】图像卷积操作(Blur)
  5. 卷积神经网络输出结果都一样
  6. 生活简单案例,分析管理中的深奥道理
  7. google 确定某点海拔高_如何查询某个地点的海拔高度,详情介绍
  8. 【8082端口被占用】
  9. IT“咏叹调”之--你公司哪个部门是“老大”?
  10. 输入圆形半径,求圆形的周长和圆形的面积,并将结果输出