概述
在數(shù)據(jù)驅(qū)動和定位的世界中,對數(shù)據(jù)進行解釋、可視化和決策的能力變得日益重要。這表明,使用正確的工具和技術(shù)可能是項目成功的關(guān)鍵。在計算機視覺領(lǐng)域,存在許多技術(shù)來解釋從視頻(包括錄像、流媒體或?qū)崟r視頻)中獲取的數(shù)據(jù),特別是在評估需要分析交通強度或某些對象(如人、車輛、動物等)行為的區(qū)域時,熱力圖是一個極其有效的選擇。
物體運動熱力圖可以展示物體在一段時間內(nèi)的運動軌跡和活動強度。這種圖表通常通過顏色的變化來表示不同區(qū)域的運動熱度,顏色的深淺代表了物體在該區(qū)域的運動頻率或者速度的快慢。在物理學和計算機視覺領(lǐng)域,熱力圖可以用于分析和理解物體的運動模式,例如人流監(jiān)控、交通流量分析或者運動員的運動軌跡分析。
在傳統(tǒng)的計算機視覺圖像處理,使用OpenCV庫背景減除法來識別和追蹤視頻中的移動物體,然后將這些信息累積起來,形成熱力圖??梢杂行У赝怀鲲@示物體運動的高頻區(qū)域,幫助研究者或分析師更好地理解物體的運動模式,但傳統(tǒng)的計算機視覺圖像處理在一些場景變化比較的情況下,性能并不理想。
在多目標跟蹤(MOT)領(lǐng)域,Tracking-by-detection它可以依賴于目標檢測器來識別視頻中的每個目標,然后使用跟蹤算法來關(guān)聯(lián)檢測結(jié)果,形成目標的連續(xù)軌跡。這種方法的關(guān)鍵在于如何有效地關(guān)聯(lián)來自不同幀的檢測框,以便為每個目標創(chuàng)建準確且連貫的軌跡。
Yolov8集成了BYTE方法,BYTE是一種創(chuàng)新的數(shù)據(jù)關(guān)聯(lián)方法,它旨在提高多目標跟蹤的準確性和連貫性。BYTE方法通過利用檢測框和跟蹤軌跡之間的相似性,可以在保留高置信度檢測結(jié)果的同時,從低置信度檢測結(jié)果中去除背景噪聲,并挖掘出真正的物體。這對于處理遮擋、模糊等困難樣本特別有效,因為這些情況下的目標檢測往往更加具有挑戰(zhàn)性。
BYTE能夠降低漏檢率并提高軌跡的連貫性??梢暂p松地應用于多種現(xiàn)有的state-of-the-art MOT方法中,并且能夠提升這些方法的IDF1指標,這表明了其強大的通用性和有效性。
基于BYTE方法,提出的跟蹤方法ByteTrack進一步展示了其在MOT任務(wù)中的潛力。ByteTrack在保持高運行速度(30 FPS)的同時,在MOT17基準測試上取得了顯著的性能提升,包括80.3的MOTA(Multiple Object Tracking Accuracy)、77.3的IDF1和63.1的HOTA(High Order Track Accuracy)。這些結(jié)果表明,ByteTrack在處理多目標跟蹤任務(wù)時,不僅能夠準確地關(guān)聯(lián)檢測框,還能夠有效地處理目標間的交互和復雜場景,從而實現(xiàn)高精度的軌跡跟蹤。
實現(xiàn)效果:
基于yolov8與OpenCV實現(xiàn)目標物體運動熱力圖
基于Yolov8的運動熱力圖
1.環(huán)境安裝
conda create -n yolov8 python=3.8
activate ylolv8
pip install ultralytics
2.下載模型
可以從官網(wǎng)上下載需要的模型,官網(wǎng)提供了幾種不同尺寸的模型:
3.項目實踐步驟
這里以一段航拍視頻為例,視頻是用俯視的一個三叉路口,目標是創(chuàng)建一個熱力圖來展示這三條路汽車流量密集熱力圖。實現(xiàn)步驟如下:
目標檢測:首先,需要對視頻進行分析,識別出視頻中的車輛以及它們在每幀中的位置
軌跡跟蹤:通過多目標跟蹤BYTE方法,關(guān)聯(lián)視頻中連續(xù)幀中檢測到的車輛,形成每個車輛的軌跡。
數(shù)據(jù)關(guān)聯(lián):利用檢測框和跟蹤軌跡之間的相似性,去除背景噪聲,挖掘出真正的車輛,降低漏檢并提高軌跡的連貫性。
熱力圖生成:將檢測到的車輛位置信息匯總,并使用熱力圖庫來生成熱力圖。熱力圖通過顏色的深淺來表示車輛密度的高低。
4.代碼實踐
導入需要的庫
from collections import defaultdict
import cv2
import numpy as np
from ultralytics import YOLO
調(diào)用Yolo目標檢測的模型,
model = YOLO('yolov8s.pt')
讀取視頻
videopath = 'video.mp4'
cap = cv2.VideoCapture(videopath)
現(xiàn)在創(chuàng)建一個空字典來存儲跟蹤位置(‘track_history’)和一個字典來存儲每個對象的最后推斷位置(‘last_positions’)。
track_history = defaultdict(lambda: [])
last_positions = {}
在計算機視覺和視頻分析中,涉及點跟蹤或?qū)ο筮\動的場景時,需要計算兩個點之間的歐幾里得距離。歐幾里得距離是兩點之間的直線距離,可以通過勾股定理來計算。在二維空間中,如果兩點的坐標分別是 p 1 ( x 1 , y 1 ) p1(x_1, y_1) p1(x1?,y1?)和 p 2 ( x 2 , y 2 ) p2(x_2, y_2) p2(x2?,y2?),那么它們之間的歐幾里得距離 d d d可以通過以下公式計算:
d = ( x 2 ? x 1 ) 2 + ( y 2 ? y 1 ) 2 d = \sqrt{(x_2 - x_1)^2 + (y_2 - y_1)^2} d=(x2??x1?)2+(y2??y1?)2?
在Python中,你可以很容易地實現(xiàn)這個計算,以下是一個簡單的函數(shù)示例:
def calculate_distance(p1, p2):
return np.sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2)
這個函數(shù)euclidean_distance
接受兩個點作為輸入,每個點由其在二維空間中的(x, y)
坐標定義。函數(shù)計算并返回這兩個點之間的直線距離。
在視頻分析中,你可能需要比較連續(xù)視頻幀中的對象位置,以確定它們是否為同一個對象,或者評估對象的運動速度。通過計算連續(xù)幀中對象位置的歐幾里得距離,可以對對象的運動進行量化分析。如果距離很小,這可能表明對象幾乎沒有移動;如果距離較大,這可能表明對象在兩幀之間有顯著的移動。這種方法有助于過濾掉靜止的對象(如停放的車輛),只關(guān)注移動的對象。
首先,使用numpy
庫初始化一個熱力圖,該圖是一個三維矩陣,其所有元素初始值都為零。這個矩陣具有三個“層”,分別對應RGB顏色通道。
import numpy as np
# 初始化熱力圖,尺寸與視頻幀的高和寬相匹配,具有三個顏色通道
heatmap = np.zeros((int(cap.get(4)), int(cap.get(3)), 3), dtype=np.float32)
接下來,進入一個while
循環(huán),該循環(huán)將持續(xù)運行,直到視頻處理完畢。
while cap.isOpened():
success, frame = cap.read()
if not success:
break # 如果無法讀取幀,則退出循環(huán)
對于成功讀取的每一幀,我們利用YOLO模型進行對象檢測和跟蹤。這里使用了跟蹤和持久性算法,這對于處理視頻幀序列非常有效。由于本例專注于車輛交通記錄,我們只定義了兩類對象。
if success:
# 利用YOLO模型對幀進行對象檢測和跟蹤
results = model.track(frame, persist=True, classes=2)
對于每一次有效的檢測,更新熱力圖,記錄對象的邊界框坐標。
# 假設(shè)results['boxes']和results['track_ids']包含了檢測結(jié)果的邊界框和跟蹤ID
for box, track_id in zip(results['boxes'], results['track_ids']):
x_center, y_center, width, height = box
current_position = (float(x_center), float(y_center))
使用calculate_distance
函數(shù)來檢查對象是否在移動,并根據(jù)移動的距離更新熱力圖。
last_position = last_positions.get(track_id)
if last_position and calculate_distance(last_position, current_position) > 5:
# 如果對象移動的距離超過最小值,則在熱力圖上進行記錄
heatmap[top_left_y:bottom_right_y, top_left_x:bottom_right_x] += 1
# 更新對象的最后位置記錄
last_positions[track_id] = current_position
為了提升視覺效果,對熱力圖應用高斯模糊濾鏡。
# 對熱力圖應用高斯模糊,以增強視覺效果
heatmap_blurred = cv2.GaussianBlur(heatmap, (15, 15), 0)
隨后,對熱力圖進行歸一化處理,并應用顏色映射,以便在原始視頻幀上進行疊加。
# 歸一化熱力圖并應用顏色映射,以便在視頻幀上疊加
heatmap_norm = cv2.normalize(heatmap_blurred, None, 0, 255, cv2.NORM_MINMAX, dtype=cv2.CV_8U)
heatmap_color = cv2.applyColorMap(heatmap_norm, cv2.COLORMAP_JET)
最后,在while
循環(huán)中,添加了一個退出鍵的檢查,以便用戶可以通過按鍵退出程序。視頻處理完成后,釋放視頻捕獲對象,并關(guān)閉所有OpenCV創(chuàng)建的窗口。
# 添加退出鍵檢查,允許用戶通過按鍵退出程序
if cv2.waitKey(1) & 0xFF == ord("q"):
break
# 視頻處理完成后,釋放資源并關(guān)閉窗口
cap.release()
cv2.destroyAllWindows()
通過上述步驟,能夠創(chuàng)建一個動態(tài)的熱力圖,它不僅能夠檢測和跟蹤視頻中的對象,還能直觀地展示對象的移動情況。
整體代碼實現(xiàn)如下:文章來源:http://www.zghlxwxcb.cn/news/detail-861569.html
from collections import defaultdict
import cv2
import numpy as np
from ultralytics import YOLO
def calculate_distance(p1, p2):
return np.sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2)
def create_history(input_video,output_video,model_path):
model = YOLO(model_path)
cap = cv2.VideoCapture(input_video)
track_history = defaultdict(lambda: [])
last_positions = {}
heatmap = np.zeros((int(cap.get(4)), int(cap.get(3)), 3), dtype=np.float32)
fps = int(cap.get(5))
videoWriter = None
while cap.isOpened():
success, frame = cap.read()
if not success:
break
results = model.track(frame, persist=True, classes=2)
boxes = results[0].boxes.xywh.cpu()
track_ids = results[0].boxes.id.int().cpu().tolist()
for box, track_id in zip(boxes, track_ids):
x_center, y_center, width, height = box
current_position = (float(x_center), float(y_center))
top_left_x = int(x_center - width / 2)
top_left_y = int(y_center - height / 2)
bottom_right_x = int(x_center + width / 2)
bottom_right_y = int(y_center + height / 2)
top_left_x = max(0, top_left_x)
top_left_y = max(0, top_left_y)
bottom_right_x = min(heatmap.shape[1], bottom_right_x)
bottom_right_y = min(heatmap.shape[0], bottom_right_y)
track = track_history[track_id]
track.append(current_position)
if len(track) > 1200:
track.pop(0)
last_position = last_positions.get(track_id)
if last_position and calculate_distance(last_position, current_position) > 5:
heatmap[top_left_y:bottom_right_y, top_left_x:bottom_right_x] += 1
last_positions[track_id] = current_position
heatmap_blurred = cv2.GaussianBlur(heatmap, (15, 15), 0)
heatmap_norm = cv2.normalize(heatmap_blurred, None, 0, 255, cv2.NORM_MINMAX, dtype=cv2.CV_8U)
heatmap_color = cv2.applyColorMap(heatmap_norm, cv2.COLORMAP_JET)
alpha = 0.7
cv_dst = cv2.addWeighted(frame, 1 - alpha, heatmap_color, alpha, 0)
cv_resize = cv2.resize(cv_dst,(640,360))
if videoWriter is None:
fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')
videoWriter = cv2.VideoWriter(output_video, fourcc, fps, (cv_resize.shape[1], cv_resize.shape[0]))
videoWriter.write(cv_resize)
cv2.imshow("Traffic Heatmap",cv_resize)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
cap.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
model_path = "yolov8s.pt"
create_history('11.mp4','21.mp4',model_path)
實現(xiàn)效果:文章來源地址http://www.zghlxwxcb.cn/news/detail-861569.html
到了這里,關(guān)于Yolov8項目實踐——基于yolov8與OpenCV實現(xiàn)目標物體運動熱力圖的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!