fbpx

Eulerian Video Magnification

Eulerian Motion Magnification (EVM) буюу Eulerian Video Magnification гэдэг нь видео доторх маш жижигхэн хөдөлгөөн, өнгөний өөрчлөлтийг (нүдээр харах боломжгүй түвшнийг) томруулж, ил тод харагдуулдаг компьютерийн харааны (computer vision) арга техник юм.

Энэ аргыг анх 2012 онд MIT-ийн судлаачид (Hao-Yu Wu, Michael Rubinstein гэх мэт) боловсруулсан бөгөөд одоо “EVM” гэж товчилдог.

Яаж ажилладаг вэ? (Үндсэн зарчим)

EVM-ийн үйл ажиллагааг дараах үндсэн алхмуудад хувааж болно:

  1. Олон хэмжээст задрал (Spatial Decomposition) Видеог Laplacian pyramid (эсвэл Gaussian pyramid) ашиглан олон түвшний (multi-scale) дүрс болгон хуваана. Ингэснээр жижиг, дунд, том хэмжээний бүтцийг тусад нь салгаж авна.
  2. Цаг хугацааны шүүлтүүр (Temporal Filtering) Тухайн spatial band-д хамаарах цаг хугацааны дохиог (time series) шүүнэ. Жишээ нь:
    • Зүрхний цохилтод тохирох 0.8–2.5 Hz
    • Амьсгалд тохирох 0.1–0.5 Hz гэх мэт
  3. Томруулалт (Magnification) Шүүсэн дохиог α (magnification factor) тоогоор томруулна. Энэ коэффициент их байх тусам өөрчлөлт илүү тод харагдана.
  4. Дахин нэгтгэх (Reconstruction) Томруулсан өөрчлөлтийг эх видео руу нэмж, шинэ видео үүсгэнэ.

Эдгээр алхмуудын үр дүнд анхны видеоноос ялгаатай, хөдөлгөөн болон өнгөний өөрчлөлтийг тод томруулсан шинэ видео бий болдог

Анхны ведио: video src
Жишээ турших python код:
# Ашиглагдах сангууд 
import numpy as np
import cv2
import scipy.signal as signal
import matplotlib.pyplot as plt
import requests
#Видео файлыг татаж авах
raw_video= "http://people.csail.mit.edu/mrub/evm/video/baby.mp4"
r = requests.get(raw_video, stream=True)
with open("baby.mp4", "wb") as f:
    for chunk in r.iter_content(chunk_size=1024):
        if chunk:
            f.write(chunk)

#OpenCV ашиглан видеог нээнэ
cap = cv2.VideoCapture("baby.mp4")
fps = cap.get(cv2.CAP_PROP_FPS)

#Видео frame-үүдийг дарааллаар нь уншина
frames = []
while True:
    ret, frame = cap.read()
    if not ret:
        break
    frame = cv2.resize(frame, (424, 240))
    frame = frame[:, 80:320]
    frames.append(frame)

cap.release()

frames = np.array(frames) / 255.0
num_frames, height, width, channels = frames.shape
print("Frames:", frames.shape)
def intensityscale(img):
    img = img - img.min()
    img = img / (img.max() + 1e-8)
    return np.clip(img, 0, 1)

def imshow(img):
    plt.imshow(intensityscale(img))
    plt.axis("off")
#Gaussian pyramid (Видео-г олон хэмжээтэй (scale) болгох функц)
def create_gaussian_pyramid(video, levels=4):
    pyramid = [video]
    for _ in range(1, levels):
        prev = pyramid[-1]
        down = np.array([cv2.pyrDown(f) for f in prev])
        pyramid.append(down)
    return pyramid

#Laplacian pyramid (Хэмжээ тус бүрийн хөдөлгөөн, өөрчлөлтийг ялгах)
def create_laplacian_pyramid(g_pyr):
    lap_pyr = []
    for i in range(len(g_pyr)-1):
        up = np.array([cv2.pyrUp(f) for f in g_pyr[i+1]])
        up = np.array([cv2.resize(up[j], (g_pyr[i].shape[2], g_pyr[i].shape[1]))
                       for j in range(len(up))])
        lap_pyr.append(g_pyr[i] - up)
    lap_pyr.append(g_pyr[-1])
    return lap_pyr
#Хөдөлгөөнийг давтамжаар нь шүүж авах функц
def bandpass_filter(video, low, high, fps, order=3):
    nyq = 0.5 * fps
    b, a = signal.butter(order, [low/nyq, high/nyq], btype='band')
    filtered = signal.filtfilt(b, a, video, axis=0)
    return filtered
#Томруулсан хөдөлгөөнийг буцааж видео болгох функц
def reconstruct_video(original, lap_pyr):
    recon = lap_pyr[-1]
    for level in reversed(lap_pyr[:-1]):
        recon = np.array([cv2.pyrUp(f) for f in recon])
        recon = np.array([cv2.resize(recon[i], (level.shape[2], level.shape[1]))
                          for i in range(len(recon))])
        recon = recon + level
    out = np.clip(original + recon, 0, 1)
    return out
# EVM-ийн бүх шатны pipeline-ийг нэгтгэж буй функц
def run_evm(video, alpha=20, low=0.4, high=3.0):
    g_pyr = create_gaussian_pyramid(video)
    l_pyr = create_laplacian_pyramid(g_pyr)

    filtered_pyr = []
    for level in l_pyr:
        filtered = bandpass_filter(level, low, high, fps)
        filtered_pyr.append(filtered * alpha)

    magnified = reconstruct_video(video, filtered_pyr)
    return magnified, g_pyr, l_pyr
# run_evm()-ээр гарсан видеог AVI файл болгон хадгалаад видео бичлэг үүсгэх
euler_video, gaussian_pyramid, laplacian_pyramid = run_evm(frames)
fourcc = cv2.VideoWriter_fourcc(*"MJPG")
out = cv2.VideoWriter("baby_euler_magnified.avi", fourcc, fps, (width, height))

for f in euler_video:
    out.write((f * 255).astype(np.uint8))

out.release()
EVM үр дүн:

Давуу тал

  • Харьцангуй энгийн, хурдан (Laplacian pyramid эсвэл Gaussian pyramid ашигладаг)

Сул тал

  • Хэт их томруулбал дуу чимээ (noise) ч бас томорно
  • Том хөдөлгөөнтэй видео дээр муу ажилладаг

Leave a Reply