前言
本項(xiàng)目效果展示視頻:
https://www.bilibili.com/video/BV14d4y177vE/?spm_id_from=333.999.0.0&vd_source=8c532ded7c7c9041f04e35940d11fdae
1、本項(xiàng)目通過yolov8/yolov7/yolov5和deepsort實(shí)現(xiàn)了一個(gè)自動駕駛領(lǐng)域的追尾前車碰撞預(yù)警系統(tǒng),可為一些同學(xué)的課設(shè)、大作業(yè)等提供參考。分別實(shí)現(xiàn)了自行車、汽車、摩托車、公交車、卡車的實(shí)時(shí)目標(biāo)檢測、跟車距離測量、車輛間的相對速度測量、基于人腦反應(yīng)時(shí)間和車輛剎停時(shí)間的碰撞預(yù)警功能。最終效果如下,紅色框代表易發(fā)生碰撞追尾的高風(fēng)險(xiǎn)目標(biāo),黃色框代表中風(fēng)險(xiǎn)目標(biāo),綠色框代表低風(fēng)險(xiǎn)目標(biāo)。
2、可訓(xùn)練自己的數(shù)據(jù)集,可以換成yolov8/yolov7/yolov5各種版本的權(quán)重。
一、項(xiàng)目環(huán)境配置
不熟悉pycharm的anaconda的大兄弟請先看這篇csdn博客,了解pycharm和anaconda的基本操作。
https://blog.csdn.net/ECHOSON/article/details/117220445
anaconda安裝完成之后請切換到國內(nèi)的源來提高下載速度 ,命令如下:
conda config --remove-key channels
conda config --add channels https://mirrors.ustc.edu.cn/anaconda/pkgs/main/
conda config --add channels https://mirrors.ustc.edu.cn/anaconda/pkgs/free/
conda config --add channels https://mirrors.bfsu.edu.cn/anaconda/cloud/pytorch/
conda config --set show_channel_urls yes
pip config set global.index-url https://mirrors.ustc.edu.cn/pypi/web/simple
首先創(chuàng)建python3.8的虛擬環(huán)境,請?jiān)诿钚兄袌?zhí)行下列操作:
conda create -n yolov8 python==3.8.5
conda activate yolov8
1、pytorch安裝(gpu版本和cpu版本的安裝)
實(shí)際測試情況是yolov8/yolov7/yolov5在CPU和GPU的情況下均可使用,不過在CPU的條件下訓(xùn)練那個(gè)速度會令人發(fā)指,所以有條件的小伙伴一定要安裝GPU版本的Pytorch,沒有條件的小伙伴最好是租服務(wù)器來使用。GPU版本安裝的具體步驟可以參考這篇文章:https://blog.csdn.net/ECHOSON/article/details/118420968。
需要注意以下幾點(diǎn):
1、安裝之前一定要先更新你的顯卡驅(qū)動,去官網(wǎng)下載對應(yīng)型號的驅(qū)動安裝
2、30系顯卡只能使用cuda11的版本
3、一定要創(chuàng)建虛擬環(huán)境,這樣的話各個(gè)深度學(xué)習(xí)框架之間不發(fā)生沖突
我這里創(chuàng)建的是python3.8的環(huán)境,安裝的Pytorch的版本是1.8.0,命令如下:
conda install pytorch==1.8.0 torchvision torchaudio cudatoolkit=10.2 # 注意這條命令指定Pytorch的版本和cuda的版本
conda install pytorch==1.8.0 torchvision==0.9.0 torchaudio==0.8.0 cpuonly # CPU的小伙伴直接執(zhí)行這條命令即可
安裝完畢之后,我們來測試一下GPU是否可以有效調(diào)用:
2、pycocotools的安裝
pip install pycocotools-windows
3、其他包的安裝
另外的話大家還需要安裝程序其他所需的包,包括opencv,matplotlib這些包,不過這些包的安裝比較簡單,直接通過pip指令執(zhí)行即可,我們cd到y(tǒng)olov8代碼的目錄下,直接執(zhí)行下列指令即可完成包的安裝。
pip install -r requirements.txt
二、車輛檢測、實(shí)時(shí)跟蹤測速算法及代碼解讀
1、主函數(shù)各參數(shù)含義
如下代碼所示,可根據(jù)自己需求更改。使用yolov8s/yolov7s/yolov5s.pt、yolov8m/yolov7m/yolov5m.pt、yolov8l/yolov7l/yolov5.pt、yolov8x/yolov7x/yolov5.pt預(yù)訓(xùn)練權(quán)重均可,也可以使用自己訓(xùn)練好的權(quán)重,本項(xiàng)目中調(diào)用的是yolov8s.pt。
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--weights', nargs='+', type=str, default='yolov5s.pt', help='model.pt path(s)')
parser.add_argument('--source', type=str, default='data/videos/test.mp4', help='source') # file/folder, 0 for webcam
parser.add_argument('--img-size', type=int, default=640, help='inference size (pixels)')
parser.add_argument('--conf-thres', type=float, default=0.25, help='object confidence threshold')
parser.add_argument('--iou-thres', type=float, default=0.45, help='IOU threshold for NMS')
parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
parser.add_argument('--view-img', action='store_true', help='display results',default=True)
parser.add_argument('--save-txt', action='store_true', help='save results to *.txt')
parser.add_argument('--save-conf', action='store_true', help='save confidences in --save-txt labels')
parser.add_argument('--nosave', action='store_true', help='do not save images/videos') # store_true為保存視頻或者圖片,路徑為runs/detect
parser.add_argument('--classes', nargs='+', type=int, help='filter by class: --class 0, or --class 0 2 3')
parser.add_argument('--agnostic-nms', action='store_true', help='class-agnostic NMS')
parser.add_argument('--augment', action='store_true', help='augmented inference')
parser.add_argument('--update', action='store_true', help='update all models')
parser.add_argument('--project', default='runs/detect', help='save results to project/name') # 結(jié)果視頻的保存路徑
parser.add_argument('--name', default='exp', help='save results to project/name')
parser.add_argument('--exist-ok', action='store_true', help='existing project/name ok, do not increment')
parser.add_argument("--config_deepsort", type=str, default="deep_sort/configs/deep_sort.yaml")
2、算法實(shí)現(xiàn)
使用yolov5和deepsort分別實(shí)現(xiàn)車輛的目標(biāo)檢測、跟蹤,再利用檢測和跟蹤的結(jié)果實(shí)時(shí)計(jì)算車速。首先使用提前設(shè)定好的車輛真實(shí)寬度和檢測出來的車輛像素寬度求出真實(shí)距離和像素距離的比值,再使用每輛車的前后兩幀框的中心坐標(biāo)計(jì)算出兩幀之間移動的像素距離。利用這個(gè)比值和像素距離做映射,就可以求出兩幀之間車輛移動的真實(shí)距離。然后距離除以兩幀之間的時(shí)間,就是速度了。本測速算法中將車輛真實(shí)移動距離與像素移動距離看成是線性關(guān)系,僅在監(jiān)控相機(jī)軸線與車輛移動方向垂直時(shí)才能成立,并且檢測出來的車輛框在空間上會產(chǎn)生一定形變,使得真實(shí)距離和像素距離的映射關(guān)系不準(zhǔn)確。有興趣的同學(xué)可以在代碼中加入透視變換,將圖像變成類似于遙感數(shù)據(jù)的俯瞰圖,實(shí)現(xiàn)測速后再將圖像變換為原始圖像視角。
3、核心代碼
我的項(xiàng)目將測速代碼封裝到了Estimated_speed()函數(shù)里面,有詳細(xì)注釋,調(diào)用即可。需要注意的是,由于本項(xiàng)目測試視頻為行車記錄儀視角所拍攝,拍攝設(shè)備本身也在移動,此處測得的車速為車輛之間的相對速度。
def Estimated_speed(locations, fps, width):
present_IDs = []
prev_IDs = []
work_IDs = []
work_IDs_index = []
work_IDs_prev_index = []
work_locations = [] # 當(dāng)前幀數(shù)據(jù):中心點(diǎn)x坐標(biāo)、中心點(diǎn)y坐標(biāo)、目標(biāo)序號、車輛類別、車輛像素寬度
work_prev_locations = [] # 上一幀數(shù)據(jù),數(shù)據(jù)格式相同
speed = []
for i in range(len(locations[1])):
present_IDs.append(locations[1][i][2]) # 獲得當(dāng)前幀中跟蹤到車輛的ID
for i in range(len(locations[0])):
prev_IDs.append(locations[0][i][2]) # 獲得前一幀中跟蹤到車輛的ID
for m, n in enumerate(present_IDs):
if n in prev_IDs: # 進(jìn)行篩選,找到在兩幀圖像中均被檢測到的有效車輛ID,存入work_IDs中
work_IDs.append(n)
work_IDs_index.append(m)
for x in work_IDs_index: # 將當(dāng)前幀有效檢測車輛的信息存入work_locations中
work_locations.append(locations[1][x])
for y, z in enumerate(prev_IDs):
if z in work_IDs: # 將前一幀有效檢測車輛的ID索引存入work_IDs_prev_index中
work_IDs_prev_index.append(y)
for x in work_IDs_prev_index: # 將前一幀有效檢測車輛的信息存入work_prev_locations中
work_prev_locations.append(locations[0][x])
for i in range(len(work_IDs)):
speed.append(
math.sqrt((work_locations[i][0] - work_prev_locations[i][0]) ** 2 + # 計(jì)算有效檢測車輛的速度,采用線性的從像素距離到真實(shí)空間距離的映射
(work_locations[i][1] - work_prev_locations[i][1]) ** 2) * # 當(dāng)視頻拍攝視角并不垂直于車輛移動軌跡時(shí),測算出來的速度將比實(shí)際速度低
width[work_locations[i][3]] / (work_locations[i][4]) * fps / 5 * 3.6 * 2)
for i in range(len(speed)):
speed[i] = [round(speed[i], 1), work_locations[i][2]] # 將保留一位小數(shù)的單位為km/h的車輛速度及其ID存入speed二維列表中
return speed
另外,我的項(xiàng)目中將每輛車的中心坐標(biāo)軌跡和車速分別寫入了根目錄下的track.txt和speed.txt,實(shí)現(xiàn)了每輛車的速度和軌跡信息記錄。
# 將每幀檢測出來的目標(biāo)中心坐標(biāo)和車輛ID寫入txt中,實(shí)現(xiàn)軌跡跟蹤
if len(location) != 0:
with open('track.txt', 'a+') as track_record:
track_record.write('frame:%s\n' % str(frame_idx))
for j in range(len(location)):
track_record.write('id:%s,x:%s,y:%s\n' % (str(location[j][2]), str(location[j][0]), str(location[j][1])))
print('done!')
locations.append(location)
print(len(locations))
# 每五幀寫入一次測速的數(shù)據(jù),進(jìn)行測速
if len(locations) == 5:
if len(locations[0]) and len(locations[-1]) != 0:
locations = [locations[0], locations[-1]]
speed = Estimated_speed(locations, fps, width)
with open('speed.txt', 'a+') as speed_record:
for sp in speed:
speed_record.write('id:%s %skm/h\n' % (str(sp[1]), str(sp[0]))) # 將每輛車的速度寫入項(xiàng)目根目錄下的speed.txt中
locations = []
4、效果展示
如圖所示,每個(gè)目標(biāo)車輛測出來的速度和行駛軌跡的中心坐標(biāo)分別存儲在兩個(gè)txt里面,id值用于區(qū)分不同的車輛,frame值代表視頻的第幾幀,x、y分別表示橫縱坐標(biāo)值。
三、跟車距離測量算法及代碼解讀
1、主函數(shù)各參數(shù)含義
foc = 500.0 # 鏡頭焦距,單位為mm
real_hight_bicycle = 26.04 # 自行車高度,注意單位是英寸
real_hight_car = 59.08 # 汽車高度
real_hight_motorcycle = 47.24 # 摩托車高度
real_hight_bus = 125.98 # 公交車高度
real_hight_truck = 137.79 # 卡車高度
# 自定義函數(shù),單目測距
def detect_distance_car(h):
dis_inch = (real_hight_car * foc) / (h - 2)
dis_cm = dis_inch * 2.54
dis_cm = int(dis_cm)
dis_m = dis_cm/100
return dis_m
2、算法實(shí)現(xiàn)
車輛距離計(jì)算公式:D = (F*W)/P,其中D是目標(biāo)到攝像機(jī)的距離(即車輛距離), F是相機(jī)焦距, W是目標(biāo)的寬度或者高度, P是指目標(biāo)在圖像中所占據(jù)的x方向像素的寬或者y方向像素的高(由目標(biāo)檢測結(jié)果可獲取)。首先需要設(shè)置好鏡頭焦距,這個(gè)參數(shù)可以通過在網(wǎng)上查詢拍攝設(shè)備的參數(shù)獲取,我這里用的測試視頻使用行車記錄儀拍攝,焦距為500mm,然后分別設(shè)置好自行車、汽車、摩托車、公交車和卡車的實(shí)際高度(單位為英寸),利用該公式就能計(jì)算出前車距離。本質(zhì)上就是通過車輛現(xiàn)實(shí)尺寸和像素尺寸實(shí)現(xiàn)了一個(gè)距離映射。
3、效果展示
如圖所示,1.6km/h代表這輛車相對拍攝設(shè)備行駛的相對速度,car代表目標(biāo)類別為汽車,0.83為目標(biāo)的置信度,2.42m為測得的跟車距離。
四、前車碰撞預(yù)警(追尾預(yù)警)算法及代碼解讀
1、算法實(shí)現(xiàn)
首先通過detect.py函數(shù)里的time_person變量設(shè)置人腦反應(yīng)后的剎車時(shí)間,單位為s,即人開始反應(yīng)后踩下剎車到車輛剎停的時(shí)間,這個(gè)時(shí)間與車輛本身的速度有關(guān),后續(xù)可通過車機(jī)系統(tǒng)接口讀取該速度,實(shí)現(xiàn)更好的預(yù)警效果。這里我們的預(yù)設(shè)值為3s。
time_person = 3 # 設(shè)置人腦反應(yīng)后的剎車時(shí)間,單位為s,即從人反應(yīng)后踩下剎車到車輛剎停的時(shí)間,這個(gè)時(shí)間與車輛本身的速度有關(guān),后續(xù)可通過車機(jī)系統(tǒng)接口讀取該速度,實(shí)現(xiàn)更好的預(yù)警效果
再調(diào)用plot_one_box()函數(shù),將前述變量 time_person、所測得的車輛目標(biāo)速度、類別名稱等值傳入。
plot_one_box(xyxy, im0, speed, outputs, time_person, label=label, color=[0, 0, 255], line_thickness=3, name=names[int(cls)]) # 調(diào)用函數(shù)進(jìn)行不同類別的測距,并繪制目標(biāo)框
plot_one_box()函數(shù)在plots.py中的定義如下,首先根據(jù)不同的標(biāo)簽名稱調(diào)用不同的函數(shù)計(jì)算跟車距離,再利用測出來的速度和距離計(jì)算時(shí)間t,與預(yù)先設(shè)定的人腦反應(yīng)后的剎車時(shí)間time_person在draw_speed()函數(shù)中進(jìn)行比較,并返回一個(gè)標(biāo)記值flag。若時(shí)間t小于time_person的1/2,則判定為高風(fēng)險(xiǎn),并將車輛目標(biāo)繪制為紅色框進(jìn)行預(yù)警;若時(shí)間t介于time_person和time_person的1/2之間,則判定為低風(fēng)險(xiǎn),并將車輛目標(biāo)繪制為黃色框進(jìn)行預(yù)警;若時(shí)間t大于time_person,則并將車輛目標(biāo)繪制為綠色框,判定為無風(fēng)險(xiǎn)。
def plot_one_box(x, img, speed, outputs, time_person, color=None, label=None, line_thickness=3, name=None):
# Plots one bounding box on image img
tl = line_thickness or round(0.002 * (img.shape[0] + img.shape[1]) / 2) + 1 # line/font thickness
color = color or [random.randint(0, 255) for _ in range(3)]
c1, c2 = (int(x[0]), int(x[1])), (int(x[2]), int(x[3]))
# w = int(x[2]) - int(x[0]) # 框的寬
h = int(x[3]) - int(x[1]) # 框的高
dis_m = 1.00
if name == 'bicycle': # 根據(jù)標(biāo)簽名稱調(diào)用不同函數(shù)計(jì)算距離
dis_m = detect_distance_bicycle(h)
elif name == 'car':
dis_m = detect_distance_car(h)
elif name == 'motorcycle':
dis_m = detect_distance_motorcycle(h)
elif name == 'bus':
dis_m = detect_distance_bus(h)
elif name == 'truck':
dis_m = detect_distance_truck(h)
label += f' {dis_m}m' # 在標(biāo)簽后追加距離
# 利用測出來的速度和距離計(jì)算時(shí)間,與預(yù)先設(shè)定的人腦反應(yīng)后的剎車時(shí)間進(jìn)行比較,
flag=''
if len(outputs) > 0:
bbox_xyxy = outputs[:, :4]
identities = outputs[:, -2]
img, flag = draw_speed(img, speed, bbox_xyxy, identities, time_person, dis_m)
if flag == "High risk": # 根據(jù)判定的不同風(fēng)險(xiǎn)等級,繪制不同顏色的目標(biāo)框,起到預(yù)警的作用
cv2.rectangle(img, c1, c2, [0, 0, 255], thickness=tl, lineType=cv2.LINE_AA)
if label:
tf = max(tl - 1, 1) # font thickness
t_size = cv2.getTextSize(label, 0, fontScale=tl / 3, thickness=tf)[0]
c2 = c1[0] + t_size[0], c1[1] - t_size[1] - 3
cv2.rectangle(img, c1, c2, [0, 0, 255], -1, cv2.LINE_AA) # filled
cv2.putText(img, label, (c1[0], c1[1] - 2), 0, tl / 3, [225, 255, 255], thickness=tf, lineType=cv2.LINE_AA)
elif flag == "Low risk":
cv2.rectangle(img, c1, c2, [0, 215, 255], thickness=tl, lineType=cv2.LINE_AA)
if label:
tf = max(tl - 1, 1) # font thickness
t_size = cv2.getTextSize(label, 0, fontScale=tl / 3, thickness=tf)[0]
c2 = c1[0] + t_size[0], c1[1] - t_size[1] - 3
cv2.rectangle(img, c1, c2, [0, 215, 255], -1, cv2.LINE_AA) # filled
cv2.putText(img, label, (c1[0], c1[1] - 2), 0, tl / 3, [225, 255, 255], thickness=tf, lineType=cv2.LINE_AA)
else:
cv2.rectangle(img, c1, c2, [48, 128, 20], thickness=tl, lineType=cv2.LINE_AA)
if label:
tf = max(tl - 1, 1) # font thickness
t_size = cv2.getTextSize(label, 0, fontScale=tl / 3, thickness=tf)[0]
c2 = c1[0] + t_size[0], c1[1] - t_size[1] - 3
cv2.rectangle(img, c1, c2, [48, 128, 20], -1, cv2.LINE_AA) # filled
cv2.putText(img, label, (c1[0], c1[1] - 2), 0, tl / 3, [225, 255, 255], thickness=tf, lineType=cv2.LINE_AA)
2、效果展示
如圖所示,正前方有四輛車由于跟車距離過近和相對速度過快,觸發(fā)了系統(tǒng)的預(yù)警功能,目標(biāo)框分別顯示為紅色和黃色,起到對駕駛員或自動駕駛系統(tǒng)進(jìn)行提醒的作用。還有目標(biāo)由于距離過遠(yuǎn),對車輛的行車安全不構(gòu)成威脅,所以顯示為綠色框。
五、總結(jié)及源碼獲取
1、總結(jié)
本項(xiàng)目基于深度目標(biāo)檢測和跟蹤技術(shù),結(jié)合了一些圖像邏輯后處理算法,實(shí)現(xiàn)了車輛檢測、跟蹤、測速、車間距離的測量和前車碰撞預(yù)警的功能,檢測準(zhǔn)確率較高,算法實(shí)時(shí)性較好,對于自動駕駛車輛的交通安全和環(huán)境感知具有一定參考意義和實(shí)用價(jià)值。
2、項(xiàng)目資源獲取(yolov8/yolov7/yolov5版本均可提供)
項(xiàng)目內(nèi)容:
包含完整word版本說明文檔,可用于寫論文、課設(shè)報(bào)告的參考。
資源獲?。?mark hidden color="red">文章來源:http://www.zghlxwxcb.cn/news/detail-741539.html
獲取整套代碼、測試視頻、訓(xùn)練好的權(quán)重和說明文檔(有償)
上交碩士,技術(shù)夠硬,也可以指導(dǎo)深度學(xué)習(xí)畢設(shè)、大作業(yè)等。
-----------QQ---- 3582584734 -----------
文章來源地址http://www.zghlxwxcb.cn/news/detail-741539.html
到了這里,關(guān)于yolov8/yolov5-車輛測距+前車碰撞預(yù)警(追尾預(yù)警)+車輛檢測識別+車輛跟蹤測速(算法-畢業(yè)設(shè)計(jì))的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!