Module code >> skvideo.motion.gme
Fork me on GitHub

Source code for skvideo.motion.gme

Implementation of global motion estimators.


import numpy as np
import os
import scipy.ndimage
import scipy.spatial

from ..utils import *

def _hausdorff_distance(E_1, E_2):
    # binary structure
    diamond = np.array([[0, 1, 0], [1, 1, 1], [0, 1, 0]])

    # extract only 1-pixel border line of objects
    E_1_per = E_1^scipy.ndimage.morphology.binary_erosion(E_1, structure=diamond)
    E_2_per = E_2^scipy.ndimage.morphology.binary_erosion(E_2, structure=diamond)

    A = scipy.ndimage.morphology.distance_transform_edt(~E_2_per)[E_1_per].max()
    B = scipy.ndimage.morphology.distance_transform_edt(~E_1_per)[E_2_per].max()
    return np.max((A, B))

[docs]def globalEdgeMotion(frame1, frame2, r=6, method='hamming'): """Global motion estimation using edge features Given two frames, find a robust global translation vector found using edge information. Parameters ---------- frame1 : ndarray first input frame, shape (1, M, N, C), (1, M, N), (M, N, C) or (M, N) frame2 : ndarray second input frame, shape (1, M, N, C), (1, M, N), (M, N, C) or (M, N) r : int Search radius for measuring correspondences. method : string "hamming" --> use Hamming distance when measuring edge correspondence distances. The distance used in the census transform. [#f1]_ "hausdorff" --> use Hausdorff distance when measuring edge correspondence distances. [#f2]_ Returns ---------- globalMotionVector : ndarray, shape (2,) The motion to minimize edge distances by moving frame2 with respect to frame1. References ---------- .. [#f1] Ramin Zabih and John Woodfill. Non-parametric local transforms for computing visual correspondence. Computer Vision-ECCV, 151-158, 1994. .. [#f2] Kevin Mai, Ramin Zabih, and Justin Miller. Feature-based algorithms for detecting and classifying scene breaks. Cornell University, 1995. """ frame1 = vshape(frame1) frame2 = vshape(frame2) assert(frame1.shape == frame2.shape) T, M, N, C = frame1.shape assert C == 1, "called with frames having %d channels. Please supply only the luminance channel." % (C,) # if type bool, then these are edge maps. No need to convert them if frame1.dtype != np.bool: E_1 = canny(frame1) else: E_1 = frame1 if frame2.dtype != np.bool: E_2 = canny(frame2) else: E_2 = frame2 distances = [] displacements = [] for dx in range(-r, r+1, 1): for dy in range(-r, r+1, 1): cimage = np.roll(E_2, dx, axis=0) cimage = np.roll(cimage, dy, axis=1) # smallest distance between a point of points found in cimage if method == 'hamming': distance = scipy.spatial.distance.hamming(np.ravel(cimage), np.ravel(E_1)) elif method == 'hausdorff': distance = _hausdorff_distance(cimage, E_2) else: raise Notimplemented # compute # of bit flip distance distances.append(distance) displacements.append([dx, dy]) idx = np.argmin(distances) return displacements[idx]