概述
Ultralytics提供了一系列的解決方案,利用YOLO11解決現實世界的問題,包括物體計數、模糊處理、熱力圖、安防系統、速度估計、物體追蹤等多個方面的應用。
YOLO速度估算結合物體檢測和跟蹤技術,使用YOLO11 模型檢測每幀中的物體,跨幀跟蹤這些物體,計算它們在一段時間內的移動情況,然后利用物體在幀間移動的距離和幀頻來估算其速度。可為交通分析、自動駕駛、安全分析等各種場景提供高效的速度估計。本文使用Python實現了簡單的演示界面,可以在圖像中畫線或者框,運行推理,輸出疊加了類別和速度的視頻。
Ultralytics提供了CLI和Python例子,展示如何使用速度估算解決方案。
CLI:
# Run a speed example
yolo solutions speed show=True# Pass a source video
yolo solutions speed source="path/to/video.mp4"# Adjust meter per pixel value based on camera configuration
yolo solutions speed meter_per_pixel=0.05
Python:
import cv2from ultralytics import solutionscap = cv2.VideoCapture("path/to/video.mp4")
assert cap.isOpened(), "Error reading video file"# Video writer
w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS))
video_writer = cv2.VideoWriter("speed_management.avi", cv2.VideoWriter_fourcc(*"mp4v"), fps, (w, h))# Initialize speed estimation object
speedestimator = solutions.SpeedEstimator(show=True, # display the outputmodel="yolo11n.pt", # path to the YOLO11 model file.fps=fps, # adjust speed based on frame per second# max_speed=120, # cap speed to a max value (km/h) to avoid outliers# max_hist=5, # minimum frames object tracked before computing speed# meter_per_pixel=0.05, # highly depends on the camera configuration# classes=[0, 2], # estimate speed of specific classes.# line_width=2, # adjust the line width for bounding boxes
)# Process video
while cap.isOpened():success, im0 = cap.read()if not success:print("Video frame is empty or processing is complete.")breakresults = speedestimator(im0)# print(results) # access the outputvideo_writer.write(results.plot_im) # write the processed frame.cap.release()
video_writer.release()
cv2.destroyAllWindows() # destroy all opened windows
SpeedEstimator參數
基本參數
名稱 | 類型 | 默認值 | 說明 |
---|---|---|---|
model | str | None | YOLO Model 文件路徑. |
fps | float | 30.0 | 視頻幀率. |
max_hist | int | 5 | 跟蹤物體進行速度/方向計算的最多歷史點數. |
meter_per_pixel | float | 0.05 | 縮放因子,用于將像素距離轉換為實際單位。 |
max_speed | int | 120 | 視覺疊加中的最高限速(用于警報)。 |
SpeedEstimator支持使用track參數:
參數 | 類型 | 默認值 | 說明 |
---|---|---|---|
tracker | str | 'botsort.yaml' | 指定要使用的跟蹤算法, bytetrack.yaml 或 botsort.yaml . |
conf | float | 0.3 | 設置檢測的置信度閾值;數值越低,跟蹤的物體越多,但可能會出現誤報。 |
iou | float | 0.5 | 設置交叉重疊 (IoU) 閾值,用于過濾重疊檢測。 |
classes | list | None | 按類別索引篩選結果。例如 classes=[0, 2, 3] 只跟蹤指定的類別(class在COCO數據集定義)。 |
verbose | bool | True | 控制跟蹤結果的顯示,提供被跟蹤物體的可視化輸出。 |
device | str | None | 指定用于推理的設備(例如: cpu , cuda:0 或 0 ). 允許用戶選擇CPU 、特定GPU 或其他計算設備運行模型。 |
可視化參數:
參數 | 類型 | 默認值 | 說明 |
---|---|---|---|
show | bool | False | 如果 True 在一個窗口中顯示注釋的圖像或視頻。有助于在開發或測試過程中提供即時視覺反饋。 |
line_width | None or int | None | 指定邊界框的線寬。如果 None 則根據圖像大小自動調整線寬,使圖像更加清晰。 |
show_conf | bool | True | 在標簽旁顯示每次檢測的置信度得分。讓人了解模型對每次檢測的確定性。 |
show_labels | bool | True | 在可視輸出中顯示每次檢測的標簽。讓用戶立即了解檢測到的物體。 |
GUI演示
這里使用Tkinter編寫一個簡單界面,演示速度估算應用。
從文件菜單打開一個mp4文件,顯示第一幀圖像。
在圖像上畫檢測線或者檢測框。
矩形繪制完成后,可以使用鼠標右鍵拖動改變角度。
然后“開始演示”,物體名稱及其速度疊加在跟蹤物體上方。
如果verbose
為True
,控制臺輸出當前幀的信息。
0: 384x640 15 cars, 24.0ms
Speed: 1.7ms preprocess, 24.0ms inference, 2.2ms postprocess per image at shape (1, 3, 384, 640)
🚀 Results ****: SolutionResults(out_count=9, classwise_count={'car': {'IN': 0, 'OUT': 8}, 'bus': {'IN': 0, 'OUT': 1}, 'truck': {'IN': 0, 'OUT': 0}}, total_tracks=15)
GUI演示程序代碼
本演示程序定義了兩個類:VideoProcessorApp類和VideoProcessor類。
class VideoProcessorApp:def __init__(self, root):self.root = rootself.root.title("視頻處理應用演示")self.root.geometry("900x700")# 設置中文字體self.font = ('SimHei', 10)# 視頻和圖像處理相關變量self.cap = Noneself.video_path = ""self.original_frame = Noneself.current_frame = Noneself.processed_frames = []self.is_playing = Falseself.is_processing = Falseself.is_paused = Falseself.draw_mode = None # 'line' 或 'rectangle'self.start_point = Noneself.end_point = Noneself.drawing = Falseself.output_file = ""self.rect_angle = 0 # 矩形旋轉角度self.rect_center = None # 矩形中心點self.rect_points = None # 矩形四個頂點self.pause_event = threading.Event()self.video_processor = Noneself._dt_buffer = []self._last_time = time.perf_counter()self.count = 0self.count_read = 0self.frame_reading_done = False # 標志位self.object_count = {}# 多線程相關self.frame_queue = Queue(maxsize=60)self.result_queue = Queue(maxsize=60)self.writer_queue = Queue(maxsize=60)self.stop_threads = False# 創建界面組件self.create_menu()self.create_widgets()# 綁定鼠標事件self.canvas.bind("<Button-1>", self.on_mouse_click)self.canvas.bind("<B1-Motion>", self.on_mouse_drag)self.canvas.bind("<ButtonRelease-1>", self.on_mouse_release)self.canvas.bind("<Button-3>", self.on_right_click)self.canvas.bind("<B3-Motion>", self.on_right_drag)self.canvas.bind("<ButtonRelease-3>", self.on_right_release)
VideoProcessor類專門處理視頻幀,其中調用了solutions.SpeedEstimator類:
self.speedestimator = solutions.SpeedEstimator(show=False,model="yolo11n.pt",region=pts,fps=fps, # adjust speed based on fpsclasses=[2,5,7],verbose = False,)
由于讀寫視頻文件和進行神經網絡推理均需要較大的計算量,本演示代碼使用多線程分別處理讀、寫、顯示和推理,以最大化利用計算機資源,提高處理速度。
def start_processing(self):if self.cap is None or not self.cap.isOpened():messagebox.showerror("錯誤", "請先打開視頻文件")returnif self.video_processor is None:messagebox.showerror("錯誤", "請先繪制線條或矩形")returnif self.is_processing:messagebox.showinfo("提示", "正在處理視頻,請等待")returnself.processed_frames.clear()self.is_processing = Trueself.is_playing = Trueself.is_paused = Falseself.stop_threads = Falseself.process_button.config(state=tk.DISABLED)self.pause_button.config(state=tk.NORMAL)self.stop_button.config(state=tk.NORMAL)self.pause_event.set()# 啟動多線程self.reader_thread = threading.Thread(target=self.frame_reader)self.processor_thread = threading.Thread(target=self.frame_processor)self.display_thread = threading.Thread(target=self.result_display)self.writer_thread = threading.Thread(target=self.video_writer_worker)# 設置線程優先級try:self.reader_thread.priority = 'ABOVE_NORMAL'self.processor_thread.priority = 'HIGH'self.writer_thread.priority = 'ABOVE_NORMAL'except:pass# 啟動線程self.reader_thread.start()self.processor_thread.start()self.display_thread.start()self.writer_thread.start()
其中的推理線程代碼如下:
def frame_processor(self):"""專用模型推理線程"""while not self.stop_threads:if self.is_paused:time.sleep(0.01)continuetry:start_time = time.time()frame = self.frame_queue.get(timeout=0.1)processed, self.object_count = self.video_processor.process_frame(frame)self.count += 1if not self.stop_threads:self.result_queue.put(processed, timeout=0.1)except Empty:continueexcept Exception as e:print(f"Frame processor error: {str(e)}")break
依據計算機視覺技術估算的速度并非精確的速度,不同的圖像和其他因素,會造成不同的估算速度差異,在實際應用中,需要使用測速雷達等設備進行標定,調整計算參數,才能有實用價值。