譯者 | 朱先忠
審校 | 重樓
本文使用YOLOv8模型,并借助開源Ultralytics框架和BoT-SORT跟蹤器,實現(xiàn)了對樹上漫步的螞蟻進行計數(shù)。
簡介
計算視頻中的物體是一項具有挑戰(zhàn)性的計算機視覺任務。與靜態(tài)圖像中的物體計數(shù)不同,視頻信息涉及額外的復雜性,因為物體可能在不同的時間移動、被遮擋或出現(xiàn)和消失,這使得計數(shù)過程變得更為復雜。
在本教程中,我們將演示如何使用對象檢測和跟蹤技術(shù)來計數(shù)沿著樹移動的螞蟻。具體地說,我們將利用開源的Ultralytics平臺,并集成用于檢測任務的YOLOv8模型、用于跟蹤任務的BoT-SORT跟蹤器和用于對螞蟻數(shù)量進行計數(shù)的行計數(shù)器。
流程概述
在典型的視頻對象計數(shù)流程中,每一幀都要經(jīng)歷一系列的過程,包括檢測、跟蹤和計數(shù)。以下給出的是針對每個步驟的簡述:
- 檢測:對象檢測器識別并定位每個幀中的對象,并在其周圍生成邊界框。
- 跟蹤:跟蹤器跨幀跟蹤這些對象,為每個對象指定唯一的ID,以確保它們只計數(shù)一次。
- 計數(shù):計數(shù)模塊聚合這些信息并添加每個新對象以提供準確的結(jié)果。
總體流程示意圖如下:
連接對象檢測器、跟蹤器和計數(shù)器可能需要大量編碼。幸運的是,開源的Ultralytics庫(參考文獻1)提供了無縫集成這些組件的方案,從而簡化了這一過程。
1.使用YOLOv8檢測對象
第一步是檢測每一幀中的螞蟻,在它們周圍產(chǎn)生邊界框。在本教程中,我們將使用我預先訓練的YOLOv8檢測器來檢測螞蟻。我使用Grounding DINO模型(引文2:https://towardsdatascience.com/automatic-labeling-of-object-detection-datasets-using-groundingdino-b66c486656fe?sk=7c98df89b60ea49a6de9efd5278f645e)來標注數(shù)據(jù),然后使用標注數(shù)據(jù)來訓練YOLOv8模型。如果你想了解更多關(guān)于訓練YOLO模型的信息,請參閱我之前關(guān)于訓練YOLOv5(https://towardsdatascience.com/the-practical-guide-for-object-detection-with-yolov5-algorithm-74c04aac4843?sk=00d2a9d6dd84d6ac4de153cab3dba7c0)的文章,因為這些概念是相似的。對于您的應用程序,您可以使用預先訓練的模型或訓練自己的自定義模型。
首先,我們需要使用預先訓練的權(quán)重值來初始化檢測器:
from ultralytics import YOLO
# 使用預先訓練的權(quán)重值來初始化YOLOv8模型
model = YOLO("/path/to/your/yolo_model.pt")
稍后,我們將使用檢測器檢測視頻循環(huán)中每幀中的螞蟻,將檢測與跟蹤過程相結(jié)合。
2.使用BoT-SORT跟蹤器跟蹤對象
由于螞蟻在視頻幀中多次出現(xiàn),因此必須跟蹤每只螞蟻并為其分配一個唯一的ID,以確保每只螞蟻只被計數(shù)一次。Ultralytics框架同時支持BoT-SORT跟蹤器(見引文3)和ByteTrack跟蹤器(見引文4)進行跟蹤。
- ByteTrack跟蹤器:提供準確性和速度之間的平衡,降低計算復雜度。它可能無法像BoT-SORT跟蹤器那樣處理遮擋和相機運動。
- BoT-SORT跟蹤器:與ByteTrack跟蹤器相比,提供了更好的跟蹤準確性和穩(wěn)健性,尤其是在具有遮擋和相機運動的挑戰(zhàn)性場景中。它是以更高的計算復雜度和更低的幀速率為代價的。
當然,在這些算法之間的選擇取決于應用程序的特定要求。
BoT-SORT的工作原理是:BoT-SORT是一個多對象跟蹤器,可以同時跟蹤多個對象。它將運動和外觀信息與相機運動補償相結(jié)合。物體的位置是使用卡爾曼濾波器預測的,與現(xiàn)有軌跡的匹配是基于它們的位置和視覺特征。這種方法允許BoT-SORT跟蹤器即使在存在遮擋或相機移動的情況下也能保持準確的軌跡。
配置良好的跟蹤器可以補償探測器的輕微故障。例如,如果對象檢測器暫時無法檢測到螞蟻,跟蹤器可以使用運動和外觀線索來維持螞蟻的軌跡。
檢測器和跟蹤器在視頻循環(huán)內(nèi)的每個幀上迭代使用以產(chǎn)生軌跡。以下是將其集成到視頻處理循環(huán)中的方法:
tracks = model.track(frame, persist=True, tracker=’botsort.yaml’, iou=0.2)
跟蹤器配置是在“botsort.yaml”文件中定義。您可以調(diào)整這些參數(shù)以最適合您的需求。要將tracker更改為ByteTrack,只需將“bytrack.yaml”傳遞給tracker參數(shù)即可。
注意,請確保并集上的交集(IoU)值符合您的應用程序要求;IoU閾值(用于非最大值抑制)確定將多接近的檢測視為同一對象。persistent=True參數(shù)告訴跟蹤器當前幀是序列的一部分,并期望前一幀中的軌跡持續(xù)到當前幀中。
3.計數(shù)對象
現(xiàn)在,我們已經(jīng)檢測到并跟蹤了螞蟻,最后一步是統(tǒng)計視頻中穿過指定線的唯一螞蟻。Ultralytics庫中的ObjectCounter類允許我們定義計數(shù)區(qū)域,該區(qū)域可以是直線或多邊形。在本教程中,我們將使用一條簡單的線作為計數(shù)區(qū)域。這種方法通過確保螞蟻過線時只被計數(shù)一次來減少錯誤,即使它的唯一ID因跟蹤錯誤而改變也沒有問題。
首先,我們在視頻循環(huán)之前初始化ObjectCounter類:
counter = solutions.ObjectCounter(
view_img=True, # 處理過程中顯示圖像
reg_pts=[(512, 320), (512, 1850)], # 興趣點區(qū)域
classes_names=model.names, # YOLO模型的類名
draw_tracks=True, # 為對象繪制跟蹤線
line_thickness=2, # 繪制的線的厚度
)
在視頻循環(huán)中,ObjectCounter將對跟蹤器生成的軌跡進行計數(shù)。線的點以[(x1,y1),(x2,y2)]格式傳遞給reg_pts參數(shù)處的計數(shù)器。當螞蟻邊界框的中心點第一次與線相交時,它會根據(jù)其軌跡方向添加到計數(shù)中。在某個方向上移動的對象被計數(shù)為“in”,而在另一個方向上運動的對象被計算為“Out”。
# 使用對象計數(shù)器對新對象進行計數(shù)
frame = counter.start_counting(frame, tracks)
完整的代碼
現(xiàn)在,我們已經(jīng)實現(xiàn)了計數(shù)組件。接下來,讓我們將代碼與視頻循環(huán)集成到一起,并保存生成的視頻。
#安裝和導入所需庫
%pip install ultralytics
import cv2
from ultralytics import YOLO, solutions
# 定義路徑
path_input_video = '/path/to/your/input_video.mp4'
path_output_video = "/path/to/your/output_video.avi"
path_model = "/path/to/your/yolo_model.pt"
#初始化YOLOv8檢測模型
model = YOLO(path_model)
#初始化對象計數(shù)器
counter = solutions.ObjectCounter(
view_img=True, #處理過程中顯示圖像
reg_pts=[(512, 320), (512, 1850)], # 興趣點區(qū)域
classes_names=model.names, # YOLO模型的類名
draw_tracks=True, # 為對象繪制跟蹤線
line_thickness=2, # 繪制的線的厚度
)
#打開視頻文件
cap = cv2.VideoCapture(path_input_video)
assert cap.isOpened(), "Error reading video file"
#初始化視頻寫入程序以保存生成的視頻
video_writer = cv2.VideoWriter(path_output_video, cv2.VideoWriter_fourcc(*"mp4v"), 30, (1080, 1920))
# 迭代視頻幀
frame_count = 0
while cap.isOpened():
success, frame = cap.read()
if not success:
print("Video frame is empty or video processing has been successfully completed.")
break
# 對當前幀執(zhí)行對象跟蹤
tracks = model.track(frame, persist=True, tracker='botsort.yaml', iou=0.2)
# 使用對象計數(shù)器對幀中的對象進行計數(shù),并獲得標注圖像
frame = counter.start_counting(frame, tracks)
# 將帶標注的幀寫入輸出視頻
video_writer.write(frame)
frame_count += 1
#釋放所有資源
cap.release()
video_writer.release()
cv2.destroyAllWindows()
# 打印計數(shù)結(jié)果
print(f'In: {counter.in_counts}\nOut: {counter.out_counts}\nTotal: {counter.in_counts + counter.out_counts}')
print(f'Saves output video to {path_output_video}')
上面的代碼將對象檢測和跟蹤集成到視頻處理循環(huán)中,以保存標注的視頻。通過使用開源視頻庫OpenCV,我們打開輸入視頻,并為輸出設(shè)置一個視頻編寫器。在每一幀中,我們使用BoT-SORT執(zhí)行對象跟蹤,對對象進行計數(shù),并對幀進行標注。帶標注的幀,包括邊界框、唯一ID、軌跡以及“入”和“出”計數(shù),都將保存到輸出視頻中?!癷n”和“out”計數(shù)可以分別從counter.in_counts和counter.out_counts中檢索,也可以打印在輸出視頻中。
上圖展示了本實驗中一個帶標注的框架。圖中,每只螞蟻都被分配了一個邊界框和一個唯一的ID。螞蟻穿過粉線時會被計數(shù)。圖像的一角顯示了螞蟻“進”和“出”的數(shù)量。
結(jié)束語
在上面帶標注的視頻中,我們正確地統(tǒng)計了總共85只螞蟻,其中34只進入,51只退出。對于精確計數(shù),至關(guān)重要的是檢測器性能良好,跟蹤器配置良好。配置良好的跟蹤器可以補償探測器的失誤,確保跟蹤的連續(xù)性。
在帶標注的視頻中,我們可以看到跟蹤器很好地處理了丟失的檢測,螞蟻周圍的邊界框消失了,并在隨后的幀中返回了正確的ID。此外,為同一對象分配不同ID的跟蹤錯誤(例如,螞蟻#42變成#48)不會影響計數(shù),因為只有越過線的螞蟻才會被計數(shù)。
總之,在本教程中,我們探討了如何使用先進的對象檢測和跟蹤技術(shù)對視頻中的對象進行計數(shù)。我們使用YOLOv8模型檢測螞蟻數(shù)據(jù),并使用BoT-SORT跟蹤器進行穩(wěn)健跟蹤,所有這些部分都與開源Ultralytics庫無縫地集成在一起。
參考文獻
[1]Ultralytics GitHub(Ultralytics開源框架的代碼倉庫):https://github.com/ultralytics/ultralytics。
[2]Grounding DINO:Grounding DINO: Marrying DINO with Grounded Pre-Training for Open-Set Object Detection(將DINO與接地預訓練結(jié)合起來進行開放式物體檢測):https://arxiv.org/pdf/2303.05499。
[3]BoT-SORT: Robust Associations Multi-Pedestrian Tracking(BoT-SORT:魯棒關(guān)聯(lián)多行人跟蹤):https://arxiv.org/pdf/2206.14651。
[4]ByteTrack: Multi-Object Tracking by Associating Every Detection Box(ByteTrack:逐個檢測框關(guān)聯(lián)法進行多目標跟蹤):https://arxiv.org/pdf/2110.06864。
譯者介紹
朱先忠,51CTO社區(qū)編輯,51CTO專家博客、講師,濰坊一所高校計算機教師,自由編程界老兵一枚。
原文標題:Mastering Object Counting in Videos,作者:Lihi Gur Arie
鏈接:
https://towardsdatascience.com/mastering-object-counting-in-videos-3d49a9230bd2。