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