opencv-python == 3.4.2.16
opencv-contrib-python == 3.4.2.16
numpy == 1.19.3
核心思路是,通過高斯混合差值算法,計算相鄰幀圖像的差值,得到二值圖像,利用二值圖像進行累積求和,得到累積二值圖,並將累計二值圖轉為偽彩色圖像,與原圖像進行融合,得到運動軌跡熱力圖。
cap = cv2.VideoCapture('TownCentreXVID.avi')
,用於讀取視頻的每一幀
初始化累積二值圖像accum_image
,用於累積每一幀的背景差分二值圖的和
filter = background_subtractor.apply(frame)
,用於計算差值,去除背景
# 1.二值化
ret, th1 = cv2.threshold(filter, threshold, maxValue, cv2.THRESH_BINARY)
# 2.累積二值圖
accum_image = cv2.add(accum_image, th1)
# 3.賦予偽彩色
color_image_video = cv2.applyColorMap(accum_image, cv2.COLORMAP_HOT)
# 4.圖像融合
video_frame = cv2.addWeighted(frame, 0.7, color_image_video, 0.7, 0)
使用cv2.imshow()
和cv2.imwrite()
顯示和保存圖像
只需要更改第五行中的視頻文件路徑
import numpy as np
import cv2
import copy
def main():
capture = cv2.VideoCapture('TownCentreXVID.avi')
background_subtractor = cv2.bgsegm.createBackgroundSubtractorMOG() # 基於高斯混合的背景差分算法,原理可參考https://blog.csdn.net/qq_30815237/article/details/87120195
length = int(capture.get(cv2.CAP_PROP_FRAME_COUNT))
first_iteration_indicator = 1
for i in range(0, length):
ret, frame = capture.read()
frame = cv2.resize(frame,dsize=None,fx=0.3,fy=0.3)
# 第一幀作為初始化
if first_iteration_indicator == 1:
first_frame = copy.deepcopy(frame)
height, width = frame.shape[:2]
accum_image = np.zeros((height, width), np.uint8)
first_iteration_indicator = 0
else:
filter = background_subtractor.apply(frame)
threshold = 2
maxValue = 2
ret, th1 = cv2.threshold(filter, threshold, maxValue, cv2.THRESH_BINARY)
# 差分圖的累積計算圖,用於繪制熱力背景
accum_image = cv2.add(accum_image, th1)
# 為二值圖添加偽色彩
color_image_video = cv2.applyColorMap(accum_image, cv2.COLORMAP_HOT)
# 圖像融合
video_frame = cv2.addWeighted(frame, 0.7, color_image_video, 0.7, 0)
cv2.imshow('frame',frame) # 原圖
cv2.imshow('diff-bkgnd-frame',filter) # 背景差分圖,通過高斯混合差分算法得到的差分圖
cv2.imshow('mask',accum_image)
cv2.imshow('result',video_frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
color_image = cv2.applyColorMap(accum_image, cv2.COLORMAP_HOT)
result_overlay = cv2.addWeighted(first_frame, 0.7, color_image, 0.7, 0)
# 保存最終圖
cv2.imwrite('diff-overlay.jpg', result_overlay)
# 釋放
capture.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
main()
1.https://towardsdatascience.com/build-a-motion-heatmap-videousing-opencv-with-python-fd806e8a2340
2.https://blog.csdn.net/qq_30815237/article/details/87120195