日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

PaddleX助力无人驾驶:基于YOLOv3的车辆检测和车道线分割实战

發布時間:2024/1/1 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 PaddleX助力无人驾驶:基于YOLOv3的车辆检测和车道线分割实战 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【飛槳開發者說】梁瑛平,北京理工大學徐特立學院本科二年級,人工智能開發愛好者。


項目簡介


無人駕駛汽車利用傳感器技術、信號處理技術、通訊技術和計算機技術等,通過集成視覺、激光雷達、超聲傳感器、微波雷達、GPS、里程計、磁羅盤等多種車載傳感器來辨識汽車所處的環境和狀態,并根據所獲得的道路信息、交通信號的信息、車輛位置和障礙物信息做出分析和判斷,向主控計算機發出期望控制,控制車輛轉向和速度,從而實現無人駕駛車輛依據自身意圖和環境的擬人駕駛。

  • 該項目使用PaddleX提供的YOLOv3模型,在 UA-DETRAC 車輛檢測數據集進行訓練;

  • 訓練結果能夠檢測到car,van,bus等不同類型車輛,mAP為0.73;

  • 并使用開源車道檢測算法,實現了無人駕駛部分的視覺感知——車輛檢測和車道線分割;

最終效果


PaddleX工具簡介

PaddleX是飛槳全流程開發工具,集飛槳核心框架、模型庫、工具及組件等深度學習開發所需全部能力于一身,打通深度學習開發全流程,并提供簡明易懂的Python API,方便用戶根據實際生產需求進行直接調用或二次開發,為開發者提供飛槳全流程開發的最佳實踐。目前,該工具代碼已開源于GitHub,同時可訪問PaddleX在線使用文檔,快速查閱使用教程和API文檔說明。

PaddleX代碼GitHub鏈接

https://github.com/PaddlePaddle/PaddleX

PaddleX文檔鏈接

https://paddlex.readthedocs.io/zh_CN/latest/index.html

PaddleX官網鏈接

https://www.paddlepaddle.org.cn/paddle/paddlex


項目過程回放

一、準備PaddleX環境

1. 安裝PaddleX庫

pip?install?paddlex?-i?https://mirror.baidu.com/pypi/simple

2. 設置工作路徑,并使用0號GPU卡

import?matplotlib matplotlib.use('Agg')?import?os os.environ['CUDA_VISIBLE_DEVICES']?=?'0' import?paddlex?as?pdxos.chdir('/home/aistudio/work/')


二、準備數據

1. 數據集簡介

數據集使用 UA-DETRAC 數據集,是一個具有挑戰性的真實多目標檢測和多目標跟蹤基準。該數據集由10小時的視頻組成,這些視頻由中國北京和天津的24個不同地點使用Cannon EOS 550D攝像機拍攝。視頻以每秒 25 幀 (fps) 的速度錄制,分辨率為 960×540 像素。UA-DETRAC 數據集中有超過 140 000 個幀,手動標注了 8250 輛車,總共有 121 萬個標記了邊界框的目標

2. 準備所需文件

PaddleX同時支持VOC和COCO兩種格式的數據,需要的文件有:

  • labels.txt:保存目標類別的文件,不包括背景類;

  • train_list.txt和val_list.txt:保存訓練/測試所需的圖片和標注文件的相對路徑;

!unzip?/home/aistudio/data/data34332/VOC2012.zip?-d?./imgs?=?os.listdir('./VOC2012/JPEGImages') print('total:',?len(imgs)) with?open('./VOC2012/train_list.txt',?'w')?as?f:for?im?in?imgs[:-200]:info?=?'JPEGImages/'+im+'?'info?+=?'Annotations/'+im[:-4]+'.xml\n'f.write(info) with?open('./VOC2012/val_list.txt',?'w')?as?f:for?im?in?imgs[-200:]:info?=?'JPEGImages/'+im+'?'info?+=?'Annotations/'+im[:-4]+'.xml\n'f.write(info)


三、數據預處理

1. 設置圖像數據預處理和數據增強模塊

具體參數見:

https://paddlex.readthedocs.io/zh_CN/latest/apis/transforms/det_transforms.html

from?paddlex.det?import?transforms train_transforms?=?transforms.Compose([transforms.MixupImage(mixup_epoch=250),transforms.RandomDistort(),transforms.RandomExpand(),transforms.RandomCrop(),transforms.Resize(target_size=608,?interp='RANDOM'),transforms.RandomHorizontalFlip(),transforms.Normalize(), ])eval_transforms?=?transforms.Compose([transforms.Resize(target_size=608,?interp='CUBIC'),transforms.Normalize(), ])

2. 定義數據迭代器

訓練集總共有6000張圖片,我們選取5800訓練,剩余200張進行測試。

base?=?'./VOC2012/'train_dataset?=?pdx.datasets.VOCDetection(data_dir=base,file_list=base+'train_list.txt',label_list=base+'labels.txt',transforms=train_transforms,shuffle=True) eval_dataset?=?pdx.datasets.VOCDetection(data_dir=base,file_list=base+'val_list.txt',label_list=base+'labels.txt',transforms=eval_transforms)2020-05-11?07:57:15?[INFO]????Starting?to?read?file?list?from?dataset...2020-05-11?07:57:16?[INFO]????5800?samples?in?file?./VOC2012/train_list.txt creating?index...index?created!2020-05-11?07:57:17?[INFO]????Starting?to?read?file?list?from?dataset...2020-05-11?07:57:17?[INFO]????200?samples?in?file?./VOC2012/val_list.txt creating?index...index?created!

參數說明:

  • data_dir (str): 數據集所在的目錄路徑。

  • file_list (str): 描述數據集圖片文件和對應標注文件的文件路徑(文本內每行路徑為相對data_dir的相對路徑)。

  • label_list (str): 描述數據集包含的類別信息文件路徑。

  • transforms (paddlex.det.transforms): 數據集中每個樣本的預處理/增強算子,詳見paddlex.det.transforms。

  • num_workers (int|str):數據集中樣本在預處理過程中的線程或進程數。默認為’auto’。當設為’auto’時,根據系統的實際CPU核數設置num_workers: 如果CPU核數的一半大于8,則num_workers為8,否則為CPU核數的一半。

  • buffer_size (int): 數據集中樣本在預處理過程中隊列的緩存長度,以樣本數為單位。默認為100。

  • parallel_method (str): 數據集中樣本在預處理過程中并行處理的方式,支持’thread’線程和’process’進程兩種方式。默認為’thread’(Windows和Mac下會強制使用thread,該參數無效)。

  • shuffle (bool): 是否需要對數據集中樣本打亂順序。默認為False。


四、定義YOLOv3模型并開始訓練

1. YOLOv3簡介:

論文地址:

https://arxiv.org/abs/1804.02767

‘Sometimes you just kinda phone it in for a year, you know?’

作者說他一年大部分時間去刷 Twitter 了,然后玩了(play around)一陣子 GAN,正好剩下一點時間,就改進了一下 YOLO 算法,提出了 YOLO v3。YOLOv3添加了ResNet中提出的殘差結果和FPN中提出的通過上采樣得到的特征金字塔結果。它最顯著特征是它可以三種不同的比例進行檢測,最終輸出是通過在特征圖上應用1 x 1內核生成的。在YOLO v3中,通過在網絡中三個不同位置的三個不同大小的特征圖上使用1 x 1大小的卷積來完成檢測。

num_classes?=?len(train_dataset.labels) print('class?num:',?num_classes) model?=?pdx.det.YOLOv3(num_classes=num_classes,?backbone='DarkNet53') model.train(num_epochs=4,train_dataset=train_dataset,train_batch_size=4,eval_dataset=eval_dataset,learning_rate=0.000125,lr_decay_epochs=[400,?800],save_interval_epochs=2,log_interval_steps=200,save_dir='./yolov3_darknet53',use_vdl=True) class?num:?42020-05-11?08:15:15?[INFO]????Load?pretrain?weights?from?./yolov3_darknet53/pretrain/DarkNet53.2020-05-11?08:15:16?[INFO]????There?are?260?varaibles?in?./yolov3_darknet53/pretrain/DarkNet53?are?loaded.

參數說明:

  • num_classes (int): 類別數。默認為80。

  • backbone (str): YOLOv3的backbone網絡,取值范圍為[‘DarkNet53’, ‘ResNet34’, ‘MobileNetV1’, ‘MobileNetV3_large’]。默認為’MobileNetV1’。

  • anchors (list|tuple): anchor框的寬度和高度,為None時表示使用默認值 [[10, 13], [16, 30], [33, 23], [30, 61], [62, 45], [59, 119], [116, 90], [156, 198], [373, 326]]。

  • anchor_masks (list|tuple): 在計算YOLOv3損失時,使用anchor的mask索引,為None時表示使用默認值 [[6, 7, 8], [3, 4, 5], [0, 1, 2]]。

  • ignore_threshold (float): 在計算YOLOv3損失時,IoU大于ignore_threshold的預測框的置信度被忽略。默認為0.7。

  • nms_score_threshold (float): 檢測框的置信度得分閾值,置信度得分低于閾值的框應該被忽略。默認為0.01。

  • nms_topk (int): 進行NMS時,根據置信度保留的最大檢測框數。默認為1000。

  • nms_keep_topk (int): 進行NMS后,每個圖像要保留的總檢測框數。默認為100。

  • nms_iou_threshold (float): 進行NMS時,用于剔除檢測框IOU的閾值。默認為0.45。

  • label_smooth (bool): 是否使用label smooth。默認值為False。

  • train_random_shapes (list|tuple): 訓練時從列表中隨機選擇圖像大小。默認值為[320, 352, 384, 416, 448, 480, 512, 544, 576, 608]。


五、評估模型

使用 evaluate 方法進行模型評估,最終mAP為0.73左右。


六、加載模型用于測試

image_name?=?'./test6.jpg' result?=?model.predict(image_name) pdx.det.visualize(image_name,?result,?threshold=0.5,?save_dir='./output/')

檢測結果:


七、定義車道線檢測模型

這里使用了開源的項目:

https://github.com/Sharpiless/advanced_lane_detection

該車道檢測算法流程為:

(1)給定一組棋盤圖像(在camera_cal文件夾內),計算相機校準矩陣和失真系數。

(2)根據校準矩陣和失真系數對原始圖像應用失真校正。

(3)使用顏色變換,漸變等創建閾值二進制圖像。

(4)應用透視變換以校正二進制圖像(“鳥瞰”)。

(5)檢測圖像中車道像素并擬合,以找到車道邊界。

(6)將檢測到的車道邊界矯正到原始圖像。

具體實現如下:

import?numpy?as?np import?cv2,?pickle,?glob,?os import?matplotlib.pyplot?as?plt import?matplotlib.image?as?mpimg import?toolsfrom?moviepy.editor?import?VideoFileClip from?IPython.display?import?HTML #?code?adopted?from:?https://github.com/t-lanigan/vehicle-detection-and-tracking/blob/master/road_sensor.py class?GlobalObjects:def?__init__(self):self.__set_folders()self.__set_hyper_parameters()self.__set_perspective()self.__set_kernels()self.__set_mask_regions()def?__set_folders(self):#?Use?one?slash?for?paths.self.camera_cal_folder?=?'camera_cal/'self.test_images?=?glob.glob('test_images/*.jpg')self.output_image_path?=?'output_images/test_'self.output_movie_path?=?'output_movies/done_'def?__set_hyper_parameters(self):self.img_size???=?(1280,?720)?#?(x,y)?values?for?img?size?(cv2?uses?this)self.img_shape??=?(self.img_size[1],?self.img_size[0])?#?(y,x)?As?numpy?spits?outreturndef?__set_kernels(self):"""Kernels?used?for?image?processing"""self.clahe?=?cv2.createCLAHE(clipLimit=2.0,?tileGridSize=(8,8))def?__set_perspective(self):"""The?src?points?draw?a?persepective?trapezoid,?the?dst?points?drawthem?as?a?square.??M?transforms?x,y?from?trapezoid?to?square?fora?birds-eye?view.??M_inv?does?the?inverse."""src?=?np.float32([[(.42?*?self.img_shape[1],.65?*?self.img_shape[0]?),(.58?*?self.img_shape[1],?.65?*?self.img_shape[0]),(0?*?self.img_shape[1],self.img_shape[0]),(1?*?self.img_shape[1],?self.img_shape[0])]])dst?=?np.float32([[0,0],[self.img_shape[1],0],[0,self.img_shape[0]],[self.img_shape[1],self.img_shape[0]]])self.M?=?cv2.getPerspectiveTransform(src,?dst)self.M_inv?=?cv2.getPerspectiveTransform(dst,?src)def?__set_mask_regions(self):"""These?are?verticies?used?for?clipping?the?image."""self.bottom_clip?=?np.int32(np.int32([[[60,0],?[1179,0],?[1179,650],?[60,650]]]))self.roi_clip?=??np.int32(np.int32([[[640,?425],?[1179,550],?[979,719],[299,719],?[100,?550],?[640,?425]]])) class?LaneFinder(object):"""The?mighty?LaneFinder?takes?in?a?video?from?the?front?camera?of?a?self?driving?carand?produces?a?new?video?with?the?traffic?lanes?highlighted?and?statistics?about?wherethe?car?is?relative?to?the?center?of?the?lane?shown."""????def?__init__(self):self.g?????????????=?GlobalObjects()????????self.thresholder???=?tools.ImageThresholder()self.distCorrector?=?tools.DistortionCorrector(self.g.camera_cal_folder)self.histFitter????=?tools.HistogramLineFitter()self.laneDrawer????=?tools.LaneDrawer()self.leftLane??????=?tools.Line()self.rightLane?????=?tools.Line()returndef?__image_pipeline(self,?img):"""The?pipeline?for?processing?images.?Globals?g?are?added?to?functions?that?needaccess?to?global?variables."""resized?????=?self.__resize_image(img)undistorted?=?self.__correct_distortion(resized)warped??????=?self.__warp_image_to_biv(undistorted)thresholded?=?self.__threshold_image(warped)lines???????=?self.__get_lane_lines(thresholded)result??????=?self.__draw_lane_lines(undistorted,?thresholded,?include_stats=False)return?resultdef?__draw_lane_lines(self,?undistorted,?thresholded,?include_stats):lines?=?{'left_line':?self.leftLane,'right_line':?self.rightLane?}return?self.laneDrawer.draw_lanes(undistorted,thresholded,lines,self.g.M_inv,include_stats)def?__get_lane_lines(self,?img):self.leftLane????=?self.histFitter.get_line(img,?self.leftLane,?'left')self.rightLane???=?self.histFitter.get_line(img,?self.rightLane,?'right')return?Truedef?__mask_region(self,?img,?vertices):"""Masks?a?region?specified?by?clockwise?vertices."""mask?=?np.zeros_like(img)???if?len(img.shape)?>?2:channel_count?=?img.shape[2]??#?i.e.?3?or?4?depending?on?your?imageignore_mask_color?=?(255,)?*?channel_countelse:ignore_mask_color?=?255cv2.fillConvexPoly(mask,?vertices,?ignore_mask_color)masked_image?=?cv2.bitwise_and(img,?mask)return?masked_image?def?__resize_image(self,?img):"""Image?is?resized?to?the?selected?size?for?the?project."""return?cv2.resize(img,?self.g.img_size,?interpolation?=?cv2.INTER_CUBIC)def?__correct_distortion(self,?img):return?self.distCorrector.undistort(img)def?__threshold_image(self,?img):return?self.thresholder.get_thresholded_image(img)def?__warp_image_to_biv(self,?img):return?cv2.warpPerspective(img,?self.g.M,?self.g.img_size)def?test_one_image(self,?pt):image?=?(mpimg.imread(pt))return?self.__image_pipeline(image)


八、最終效果

%matplotlib?inline obj?=?LaneFinder() result?=?obj.test_one_image('./output/visualize_test6.jpg')print(type(result),?result.shape)plt.figure(figsize=(15,12)) plt.imshow(result) plt.savefig('result.png') plt.show()

小結

  • 本項目使用PaddleX提供的高層接口,快速、高效地完成了無人駕駛任務中車輛檢測部分的模型訓練和部署。最大的感受就是Paddle為開發者提供了很好的開發環境。通過Python API方式完成全流程使用或集成,該模型提供全面、靈活、開放的深度學習功能,有更高的定制化空間以及更低門檻的方式快速完成產業模型部署,并提供了應用層的軟件和可視化服務。

  • 數據集選擇和模型選擇。訓練集最終選擇了UA-DETRAC 數據集,并且我也將該訓練集轉換到了VOC格式并在AI Studio上公開。模型最終選擇了PaddleX提供的YOLOv3,該算法不僅在COCO、VOC等公開數據集上表現出色,并且實踐證明在別的任務中,YOLOv3也具有比其他算法更好的泛化能力。

  • 開發過程:開發最初效果并不理想,在UA-DETRAC數據集上的mAP僅有0.64左右。這里嘗試了調整學習率、批次大小等超參數,并使用了不同的數據增強方法,但是提升效果微乎其微。最終查閱原論文發現,YOLOv3使用了K-means的方法獲取預選框大小。修改并訓練后,檢測精度得到了很好的提升(mAP為0.79左右)。

  • 人工設置anchor大小的弊端:

    修改前anchor使用默認值。這些anchor雖然能夠提供不同尺寸和長寬比的ROI,但是針對特定任務,有一些大小的anchor并不能很好地表征目標,甚至會額外增加不必要的計算量。比如針對小目標檢測,較大的anchor幾乎不會被選取為正樣本。而且如果anchor的尺寸和目標的尺寸差異較大,則會影響模型的檢測效果。

    YOLO的作者Joseph Redmon等建議使用K-means聚類來代替人工設計,通過對訓練集的真值框進行聚類,自動生成一組更加適合數據集的anchor大小,可以使網絡的檢測效果更好。

    K-means算法獲取anchor大小:

    Joseph Redmon希望anchor能夠滿足與目標框盡可能相似并且距離盡可能相近,所以他提出了選取anchor大小的度量d:

    其中IOU表示真值框和預選框的交并比。

    因此,最終算法步驟為:

  • 隨機選取K個box作為初始anchor;

  • 使用IOU度量,將每個box分配給與其距離最近的anchor;

  • 計算每個簇中所有box寬和高的均值,更新anchor;

  • 重復2、3步,直到anchor不再變化,或者達到了最大迭代次數。

  • 在UA-DETRAC數據集上得到的anchor大小為:

    (13,11),(17,15),(23,17),(29,23),

    (41,29),(68,33),(51,46),(93,57),(135,95)

    相關代碼參考:

    https://github.com/ybcc2015/DeepLearning-Utils/tree/master/Anchor-Kmeans

    def?iou(boxes,?anchors):#?計算IOUw_min?=?np.minimum(boxes[:,?0,?np.newaxis],?anchors[np.newaxis,?:,?0])h_min?=?np.minimum(boxes[:,?1,?np.newaxis],?anchors[np.newaxis,?:,?1])inter?=?w_min?*?h_minbox_area?=?boxes[:,?0]?*?boxes[:,?1]anchor_area?=?anchors[:,?0]?*?anchors[:,?1]union?=?box_area[:,?np.newaxis]?+?anchor_area[np.newaxis]return?inter?/?(union?-?inter)def?fit(self,?boxes):if?self.n_iter?>?0:self.n_iter?=?0np.random.seed(self.random_seed)n?=?boxes.shape[0]#?初始化隨機anchor大小self.anchors_?=?boxes[np.random.choice(n,?self.k,?replace=True)]self.labels_?=?np.zeros((n,))while?True:self.n_iter?+=?1if?self.n_iter?>?self.max_iter:breakself.ious_?=?self.iou(boxes,?self.anchors_)distances?=?1?-?self.ious_cur_labels?=?np.argmin(distances,?axis=1)#?如果anchor大小不再變化,則表示已收斂,終止迭代if?(cur_labels?==?self.labels_).all():break#?更新anchor大小for?i?in?range(self.k):self.anchors_[i]?=?np.mean(boxes[cur_labels?==?i],?axis=0)self.labels_?=?cur_labels

    此案例應用的目標檢測場景,還可以通過飛槳目標檢測套件PaddleDetection來實現,這里提供了更專業的端到端開發套件和工具,歡迎感興趣的小伙伴動手實踐一把。

    PaddleDetection GitHub項目地址:

    https://github.com/PaddlePaddle/PaddleDetection

    更多資源

    如在使用過程中有問題,可加入飛槳官方QQ群進行交流:703252161。

    飛槳PaddleX技術交流QQ群:1045148026

    如果您想詳細了解更多飛槳的相關內容,請參閱以下文檔。

    官網地址:

    https://www.paddlepaddle.org.cn

    更多PaddleX的應用方法,歡迎訪問項目地址:

    GitHub:?

    https://github.com/PaddlePaddle/PaddleX

    Gitee:?

    https://gitee.com/paddlepaddle/PaddleX

    飛槳開源框架項目地址:

    GitHub:

    https://github.com/PaddlePaddle/Paddle

    Gitee:?

    https://gitee.com/paddlepaddle/Paddle

    END

    總結

    以上是生活随笔為你收集整理的PaddleX助力无人驾驶:基于YOLOv3的车辆检测和车道线分割实战的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。