用于图像序列的时间带通滤波器,以放大运动

时间:2018-08-15 16:12:14

标签: python opencv image-processing signal-processing

我正在尝试使用本文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()

0 个答案:

没有答案