我正在尝试使用本文http://people.csail.mit.edu/mrub/evm/在python中实现简单的欧拉运动放大。我在这里找到了一个c ++实现:https://github.com/kgram007/Eulerian-Motion-Magnification/blob/master/src/EulerianMotionMag.cpp,我正在用它来寻求帮助。 第一步,我已经成功地将每个帧分解为拉普拉斯金字塔。之后,我想使用前一帧使用简单的二阶IIR滤波器对金字塔中的每个级别进行带通滤波。在提供的代码中,作者使用了一个简单的二阶IIR滤波器,但是我的问题是函数temporalIIRFilter总是返回一个全为0的数组,因为使用cuttofFreqHigh和cuttofFreqLow计算时temp1和temp2始终相同。所以我的问题是,为什么在我的代码版本中过滤不起作用,以及我将如何应用时间带通滤波器。我对过滤有一定的了解,但对时间过滤感到困惑,我在代码中找不到任何好的实现,因此我希望能提供一些帮助
这是我的python代码(主要关注点是temporalIIRFilter函数):
import cv2
import matplotlib.pyplot as plt
import numpy as np,sys
from sys import argv
from cv2 import pyrDown,pyrUp
from skimage import img_as_float, color
# makes a laplacean pyramid from image with n levels
def getLapPyramid(img, n):
from cv2 import pyrDown,pyrUp,subtract
currImg = img
gaussPyr = []
for i in range(levels):
currImg = pyrDown(currImg)
gaussPyr.append(currImg)
lapPyr = [gaussPyr[levels - 1]]
for i in range(levels - 1, 0, -1):
size = (gaussPyr[i - 1].shape[1], gaussPyr[i - 1].shape[0])
up = pyrUp(gaussPyr[i], dstsize=size)
lap = gaussPyr[i - 1] - up
lapPyr.append(lap)
return lapPyr
# Reconstructs image from pyramid
def reconstructImgFromPyramid(pyr, n):
from cv2 import pyrDown,pyrUp,add
currImg = pyr[0]
for i in range(1, n):
size = (pyr[i].shape[1], pyr[i].shape[0])
up = pyrUp(currImg, dstsize=size)
currImg = up + pyr[i]
return currImg
def readVid(src):
cap = cv2.VideoCapture(src)
frames = []
while(cap.isOpened()):
ret, frame = cap.read()
if ret == False:
print("end of video")
break
frame = img_as_float(frame)
frames.append(frame)
cap.release()
return frames
levels = 5
frameNum = 0
lowpass1 = []
lowpass2 = []
filtered = []
cuttofFreqHigh = 0.4
cuttofFreqLow = 0.05
lambdac = 16
alpha_ = 20
chromAttenuation = 0.1
exaggerationFactor = 2.0
delta_ = 0
lambda_ = 0
cap = cv2.VideoCapture('baby.mp4')
ret, frame = cap.read()
fourcc = cv2.VideoWriter_fourcc(*'XVID')
writer = cv2.VideoWriter('out.avi', fourcc, 20, (frame.shape[1], frame.shape[1]))
# y[n] = a*y[n - 1] + b*x[n]
def temporalIIRFilter(src, level):
temp1 = (1.0 - cuttofFreqHigh) * lowpass1[level] + cuttofFreqHigh * src
temp2 = (1.0 - cuttofFreqLow) * lowpass2[level] + cuttofFreqLow * src
lowpass1[level] = temp1
lowpass2[level] = temp2
return lowpass1[level] - lowpass2[level]
while(cap.isOpened()):
ret, frame = cap.read()
frame = img_as_float(frame)
if ret == False:
print("end of video")
break
#Spatial filter (convert frame to laplacian pyramid)
laplacianPyr = getLapPyramid(frame, levels)
if frameNum == 0:
lowpass1 = laplacianPyr
lowpass2 = laplacianPyr
filtered = laplacianPyr
else:
#Temporal filtering
for i in range(levels):
filtered[i] = temporalIIRFilter(laplacianPyr[i], i)
print("filtered[i]", filtered[i])
#amplify the motion
delta_ = lambdac / 8.0 / (1.0 + alpha_)
lambda_ = np.sqrt(float(frame.shape[0] * frame.shape[0] + frame.shape[1] * frame.shape[1])) / 3
#amplify
for i in range(levels):
currAlpha = lambda_ / delta_ / 8 - 1
currAlpha = currAlpha * exaggerationFactor
if i == levels or i == 0:
filtered[i] = filtered[i] * 0
else:
filtered[i] = filtered[i] * min(alpha_, currAlpha)
lambda_ = lambda_ / 2
outFrame = reconstructImgFromPyramid(filtered, levels)
frameNum = frameNum + 1
writer.release()
cap.release()
cv2.destroyAllWindows()