MHI(运动历史图)
MHI最初是由Bobick 和 Davis提出的,在此之前,Bobick 和 Davis 首先提出了二值的运动能量图(Motion Energy Image,MEI),通过描述物体如何移动和运动在空间中发生的位置,来进行基于运动的物体识别。运动能量图显示了运动的轮廓和能量的空间分布。在运动能量图的基础上产生了运动历史图(Motion History Image,MHI)。运动历史图是一种基于视觉的模板方法,通过计算时间段内同一位置的像素变化,将目标运动情况以图像亮度的形式表现出来。它是这样的一种图像:其每个像素的灰度值表示了在一组视频序列中该位置像素的最近的运动情况。最后运动的时刻越接近当前帧,该像素的灰度值越高。因此,MHI图像可以表征人体在一个动作过程中最近的动作情况,这使得MHI被广泛应用于动作识别领域。
公式
设H为运动历史图像素的强度值, H τ ( x , y , t ) H_\tau (x,y,t) Hτ(x,y,t)可以由更新函数计算得出:
H τ ( x , y , t ) = { τ i f Ψ ( x , y , t ) = 1 m a x ( 0 , H τ ( x , y , t − 1 ) − δ ) o t h e r w i s e H_\tau (x,y,t)= \begin{cases} \tau & if\ \Psi (x,y,t)=1\\ max(0,H_\tau(x,y,t-1)-\delta )& otherwise \end{cases} Hτ(x,y,t)={
τmax(0,Hτ(x,y,t−1)−δ)if Ψ(x,y,t)=1otherwise
式中,(x, y)和t为像素点的位置及时间; τ \tau τ为持续时间,从帧数的角度决定了运动的时间范围; δ \delta δ为衰退参数。 Ψ ( x , y , t ) \Psi(x, y, t) Ψ(x,y,t)为更新函数,可由帧间差、图像差分或光流等多种方法定义,其中帧间差法最为常用:
Ψ ( x , y , t ) = { 1 i f D ( x , y , t ) > ξ 0 o t h e r w i s e \Psi (x,y,t)= \begin{cases} 1&if\ D(x,y,t)>\xi \\ 0& otherwise \end{cases} Ψ(x,y,t)={
10if D(x,y,t)>ξotherwise
其中:
D ( x , y , t ) = ∣ I ( x , y , t ) − I ( x , y , t ± Δ ) ∣ D (x,y,t)=\left | I(x,y,t)-I(x,y,t\pm\Delta) \right | D(x,y,t)=∣I(x,y,t)−I(x,y,t±Δ)∣
式中, I ( x , y , t ) I (x, y, t) I(x,y,t)为视频图像序列第t帧坐标(x, y)像素点的强度值, Δ \Delta Δ为帧间距离, ξ \xi ξ 为人为给定的差异阈值,随着视频场景的变化而调整。
实现代码:
import numpy as np import cv2 from time import sleep import queue class MHI: def __init__(self,cap,tau,delta,xi,t): self.tau=tau self.delta=delta self.xi=xi self.t=t self.cap=cap self.data = queue.Queue() ret,frame=cap.read() if ret: for i in range(t): self.data.put(frame) self.H = np.zeros(frame.shape) def getimag(self): ret,frame=cap.read() if not ret: return ret,frame self.data.put(frame) old_frame=self.data.get() a=cv2.addWeighted(old_frame.astype(float),1, frame.astype(float), -1, 0) D= np.fabs(a) Psi= D >=self.xi c=self.H-self.delta H=np.maximum(0,c) H[Psi]=self.tau self.H=H return ret, H.astype("uint8") cap = cv2.VideoCapture(0) # a=MHI(cap,tau=200,xi=20,delta=10,t=1) while cap.isOpened(): _,frame=a.getimag() cv2.imshow("out_win", frame) sleep(0.04) if cv2.waitKey(1) == ord('q'): break cap.release() cv2.destroyAllWindows()
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ji-chu/80314.html