作者主頁:編程千紙鶴
作者簡介:Java領域優質創作者、CSDN博客專家 、CSDN內容合伙人、掘金特邀作者、阿里云博客專家、51CTO特邀作者、多年架構師設計經驗、多年校企合作經驗,被多個學校常年聘為校外企業導師,指導學生畢業設計并參與學生畢業答辯指導,有較為豐富的相關經驗。期待與各位高校教師、企業講師以及同行交流合作
主要內容:Java項目、Python項目、前端項目、PHP、ASP.NET、人工智能與大數據、單片機開發、物聯網設計與開發設計、簡歷模板、學習資料、面試題庫、技術互助、就業指導等
業務范圍:免費功能設計、開題報告、任務書、中期檢查PPT、系統功能實現、代碼編寫、論文編寫和輔導、論文降重、長期答辯答疑輔導、騰訊會議一對一專業講解輔導答辯、模擬答辯演練、和理解代碼邏輯思路等。
收藏點贊不迷路? 關注作者有好處
文末獲取源碼?
項目編號:
一,環境介紹
語言環境:Python3.8
數據庫:Mysql: mysql5.7
開發技術:YOLOV8+Python+PyQT5
開發工具:IDEA或PyCharm
二,項目簡介
車輛行人多目標檢測與追蹤系統
結合了先進的YOLOv8目標檢測技術與ByteTrack多目標跟蹤算法,能夠在實時視頻畫面中準確地檢測并跟蹤行人與車輛。這一系統對于改善交通安全、提高城市監控效率以及增強公共安全管理具有顯著的重要性。本文基于YOLOv8深度學習框架
,通過5607張圖片
,訓練了一個進行車輛與行人
的目標檢測模型,準確率高達94%
;然后結合ByteTrack
多目標跟蹤算法,實現了目標的追蹤效果。最終基于此開發了一款帶UI界面的車輛行人多目標檢測與追蹤系統
,可用于實時檢測場景中的車輛與行人檢測追蹤,可以更加方便的進行功能展示。該系統是基于python
與PyQT5
開發的,支持視頻
以及攝像頭
進行多目標檢測追蹤
,也可選擇指定目標追蹤
,支持保存追蹤結果
視頻。本文提供了完整的Python代碼和使用教程,給感興趣的小伙伴參考學習,完整的代碼資源文件獲取方式見文末。
車輛行人多目標檢測與追蹤系統
結合了先進的YOLOv8目標檢測技術
與ByteTrack多目標跟蹤算法
,能夠在實時視頻畫面中準確地檢測并跟蹤行人與車輛
。這一系統對于改善交通安全、提高城市監控效率以及增強公共安全管理具有顯著的重要性。實時的追蹤可以幫助相關部門快速響應各種交通和安全事件,降低事故發生風險,并為城市交通規劃和管理提供數據支持。
車輛行人多目標檢測與追蹤系統的應用場景主要包括
:
交通監控
:實時監測城市交通流量、行人穿行情況,分析交通擁堵,優化交通信號控制。
事故分析與應對
:在交通事故發生時提供準確的事故記錄,輔助事故原因分析和快速響應。
安全監督
:用于公共場所和重要設施周邊的安全監控,檢測可疑行為,預防犯罪行為的發生。
自動駕駛輔助系統
:整合至自動駕駛系統中,幫助車輛更好地理解周邊環境,避免與行人和其他車輛的碰撞。
城市規劃
:通過長期數據收集分析人流和車流模式,為城市規劃和基礎設施建設提供決策支持。
零售與商業分析
:在商業區域監測人流和車流量,為零售和商業活動的布局提供依據。?
總結來說,車輛行人多目標檢測與追蹤系統的應用可以在多個層面提高城市管理和居民的生活質量。該系統能夠為交通安全和城市安全提供有力支撐,是智慧城市建設和智能交通系統中不可或缺的一部分。通過對實時視頻畫面的深度分析,該系統不僅可以預防和減少交通事故,還能為未來城市的可持續發展提供數據驅動的見解。
三,系統展示
通過網絡上搜集關于車輛行人的各類圖片
,并使用LabelMe標注工具對每張圖片中的目標邊框(Bounding Box)及類別進行標注。一共包含5607張圖片
,其中訓練集包含4485張圖片
,驗證集包含1122張圖片
,部分圖像及標注如下圖所示。
各損失函數作用說明:
定位損失box_loss
:預測框與標定框之間的誤差(GIoU),越小定位得越準;分類損失cls_loss
:計算錨框與對應的標定分類是否正確,越小分類得越準;動態特征損失(dfl_loss)
:DFLLoss是一種用于回歸預測框與目標框之間距離的損失函數。在計算損失時,目標框需要縮放到特征圖尺度,即除以相應的stride,并與預測的邊界框計算Ciou Loss,同時與預測的anchors中心點到各邊的距離計算回歸DFLLoss。這個過程是YOLOv8訓練流程中的一部分,通過計算DFLLoss可以更準確地調整預測框的位置,提高目標檢測的準確性。本文訓練結果如下:
我們通常用PR曲線
來體現精確率和召回率的關系,本文訓練結果的PR曲線如下。mAP
表示Precision和Recall作為兩軸作圖后圍成的面積,m表示平均,@后面的數表示判定iou為正負樣本的閾值。mAP@.5:表示閾值大于0.5的平均mAP,可以看到本文模型兩類目標檢測的mAP@0.5
平均值為0.94
,結果還是非常不錯的。
運行效果
四,核心代碼展示
#?所需加載的模型目錄
path?=?'models/best.pt'
#?需要檢測的圖片地址
img_path?=?"TestFiles/car_data_1_4648.jpg"#?加載預訓練模型
#?conf?0.25?object?confidence?threshold?for?detection
#?iou?0.7?intersection?over?union?(IoU)?threshold?for?NMS
model?=?YOLO(path,?task='detect')
#?model?=?YOLO(path,?task='detect',conf=0.5)#?檢測圖片
results?=?model(img_path)
res?=?results[0].plot()
cv2.imshow("YOLOv8?Detection",?res)
cv2.waitKey(0)class?ByteTrack:"""Initialize?the?ByteTrack?object.Parameters:track_thresh?(float,?optional):?Detection?confidence?thresholdfor?track?activation.track_buffer?(int,?optional):?Number?of?frames?to?buffer?when?a?track?is?lost.match_thresh?(float,?optional):?Threshold?for?matching?tracks?with?detections.frame_rate?(int,?optional):?The?frame?rate?of?the?video."""def?__init__(self,track_thresh:?float?=?0.25,track_buffer:?int?=?30,match_thresh:?float?=?0.8,frame_rate:?int?=?30,):self.track_thresh?=?track_threshself.match_thresh?=?match_threshself.frame_id?=?0self.det_thresh?=?self.track_thresh?+?0.1self.max_time_lost?=?int(frame_rate?/?30.0?*?track_buffer)self.kalman_filter?=?KalmanFilter()self.tracked_tracks:?List[STrack]?=?[]self.lost_tracks:?List[STrack]?=?[]self.removed_tracks:?List[STrack]?=?[]def?update_with_detections(self,?detections:?Detections)?->?Detections:"""Updates?the?tracker?with?the?provided?detections?andreturns?the?updated?detection?results.Parameters:detections:?The?new?detections?to?update?with.Returns:Detection:?The?updated?detection?results?that?now?include?tracking?IDs."""tracks?=?self.update_with_tensors(tensors=detections2boxes(detections=detections))detections?=?Detections.empty()if?len(tracks)?>?0:detections.xyxy?=?np.array([track.tlbr?for?track?in?tracks],?dtype=np.float32)detections.class_id?=?np.array([int(t.class_ids)?for?t?in?tracks],?dtype=int)detections.tracker_id?=?np.array([int(t.track_id)?for?t?in?tracks],?dtype=int)detections.confidence?=?np.array([t.score?for?t?in?tracks],?dtype=np.float32)else:detections.tracker_id?=?np.array([],?dtype=int)return?detectionsdef?update_with_tensors(self,?tensors:?np.ndarray)?->?List[STrack]:"""Updates?the?tracker?with?the?provided?tensors?and?returns?the?updated?tracks.Parameters:tensors:?The?new?tensors?to?update?with.Returns:List[STrack]:?Updated?tracks."""self.frame_id?+=?1activated_starcks?=?[]refind_stracks?=?[]lost_stracks?=?[]removed_stracks?=?[]class_ids?=?tensors[:,?5]scores?=?tensors[:,?4]bboxes?=?tensors[:,?:4]remain_inds?=?scores?>?self.track_threshinds_low?=?scores?>?0.1inds_high?=?scores?<?self.track_threshinds_second?=?np.logical_and(inds_low,?inds_high)dets_second?=?bboxes[inds_second]dets?=?bboxes[remain_inds]scores_keep?=?scores[remain_inds]scores_second?=?scores[inds_second]class_ids_keep?=?class_ids[remain_inds]class_ids_second?=?class_ids[inds_second]if?len(dets)?>?0:"""Detections"""detections?=?[STrack(STrack.tlbr_to_tlwh(tlbr),?s,?c)for?(tlbr,?s,?c)?in?zip(dets,?scores_keep,?class_ids_keep)]else:detections?=?[]"""?Add?newly?detected?tracklets?to?tracked_stracks"""unconfirmed?=?[]tracked_stracks?=?[]??#?type:?list[STrack]for?track?in?self.tracked_tracks:if?not?track.is_activated:unconfirmed.append(track)else:tracked_stracks.append(track)"""?Step?2:?First?association,?with?high?score?detection?boxes"""strack_pool?=?joint_tracks(tracked_stracks,?self.lost_tracks)#?Predict?the?current?location?with?KFSTrack.multi_predict(strack_pool)dists?=?matching.iou_distance(strack_pool,?detections)dists?=?matching.fuse_score(dists,?detections)matches,?u_track,?u_detection?=?matching.linear_assignment(dists,?thresh=self.match_thresh)for?itracked,?idet?in?matches:track?=?strack_pool[itracked]det?=?detections[idet]if?track.state?==?TrackState.Tracked:track.update(detections[idet],?self.frame_id)activated_starcks.append(track)else:track.re_activate(det,?self.frame_id,?new_id=False)refind_stracks.append(track)"""?Step?3:?Second?association,?with?low?score?detection?boxes"""#?association?the?untrack?to?the?low?score?detectionsif?len(dets_second)?>?0:"""Detections"""detections_second?=?[STrack(STrack.tlbr_to_tlwh(tlbr),?s,?c)for?(tlbr,?s,?c)?in?zip(dets_second,?scores_second,?class_ids_second)]else:detections_second?=?[]r_tracked_stracks?=?[strack_pool[i]for?i?in?u_trackif?strack_pool[i].state?==?TrackState.Tracked]dists?=?matching.iou_distance(r_tracked_stracks,?detections_second)matches,?u_track,?u_detection_second?=?matching.linear_assignment(dists,?thresh=0.5)for?itracked,?idet?in?matches:track?=?r_tracked_stracks[itracked]det?=?detections_second[idet]if?track.state?==?TrackState.Tracked:track.update(det,?self.frame_id)activated_starcks.append(track)else:track.re_activate(det,?self.frame_id,?new_id=False)refind_stracks.append(track)for?it?in?u_track:track?=?r_tracked_stracks[it]if?not?track.state?==?TrackState.Lost:track.mark_lost()lost_stracks.append(track)"""Deal?with?unconfirmed?tracks,?usually?tracks?with?only?one?beginning?frame"""detections?=?[detections[i]?for?i?in?u_detection]dists?=?matching.iou_distance(unconfirmed,?detections)dists?=?matching.fuse_score(dists,?detections)matches,?u_unconfirmed,?u_detection?=?matching.linear_assignment(dists,?thresh=0.7)for?itracked,?idet?in?matches:unconfirmed[itracked].update(detections[idet],?self.frame_id)activated_starcks.append(unconfirmed[itracked])for?it?in?u_unconfirmed:track?=?unconfirmed[it]track.mark_removed()removed_stracks.append(track)"""?Step?4:?Init?new?stracks"""for?inew?in?u_detection:track?=?detections[inew]if?track.score?<?self.det_thresh:continuetrack.activate(self.kalman_filter,?self.frame_id)activated_starcks.append(track)"""?Step?5:?Update?state"""for?track?in?self.lost_tracks:if?self.frame_id?-?track.end_frame?>?self.max_time_lost:track.mark_removed()removed_stracks.append(track)self.tracked_tracks?=?[t?for?t?in?self.tracked_tracks?if?t.state?==?TrackState.Tracked]self.tracked_tracks?=?joint_tracks(self.tracked_tracks,?activated_starcks)self.tracked_tracks?=?joint_tracks(self.tracked_tracks,?refind_stracks)self.lost_tracks?=?sub_tracks(self.lost_tracks,?self.tracked_tracks)self.lost_tracks.extend(lost_stracks)self.lost_tracks?=?sub_tracks(self.lost_tracks,?self.removed_tracks)self.removed_tracks.extend(removed_stracks)self.tracked_tracks,?self.lost_tracks?=?remove_duplicate_tracks(self.tracked_tracks,?self.lost_tracks)output_stracks?=?[track?for?track?in?self.tracked_tracks?if?track.is_activated]return?output_stracks#?創建跟蹤器
byte_tracker?=?sv.ByteTrack(track_thresh=0.25,?track_buffer=30,?match_thresh=0.8,?frame_rate=30)
五,相關作品展示
基于Java開發、Python開發、PHP開發、C#開發等相關語言開發的實戰項目
基于Nodejs、Vue等前端技術開發的前端實戰項目
基于微信小程序和安卓APP應用開發的相關作品
基于51單片機等嵌入式物聯網開發應用
基于各類算法實現的AI智能應用
基于大數據實現的各類數據管理和推薦系統
?
?