Source code for cvbase.optflow.visualize

from __future__ import division

import numpy as np

from cvbase.decorators import requires_package


[docs]@requires_package('cv2') def show_flow(flow, win_name='', wait_time=0): """Show optical flow Args: flow(ndarray or str): optical flow to be shown win_name(str): the window name wait_time(int): value of waitKey param """ from cvbase.image import rgb2bgr from cvbase.visualize import show_img from cvbase.optflow.io import read_flow flow = read_flow(flow) flow_img = flow2rgb(flow) show_img(rgb2bgr(flow_img), win_name, wait_time)
[docs]def flow2rgb(flow, color_wheel=None, unknown_thr=1e6): """Convert flow map to RGB image Args: flow(ndarray): optical flow color_wheel(ndarray or None): color wheel used to map flow field to RGB colorspace. Default color wheel will be used if not specified unknown_thr(str): values above this threshold will be marked as unknown and thus ignored Returns: ndarray: an RGB image that can be visualized """ assert flow.ndim == 3 and flow.shape[-1] == 2 if color_wheel is None: color_wheel = make_color_wheel() assert color_wheel.ndim == 2 and color_wheel.shape[1] == 3 num_bins = color_wheel.shape[0] dx = flow[:, :, 0].copy() dy = flow[:, :, 1].copy() ignore_inds = (np.isnan(dx) | np.isnan(dy) | (np.abs(dx) > unknown_thr) | (np.abs(dy) > unknown_thr)) dx[ignore_inds] = 0 dy[ignore_inds] = 0 rad = np.sqrt(dx**2 + dy**2) if np.any(rad > np.finfo(float).eps): max_rad = np.max(rad) dx /= max_rad dy /= max_rad [h, w] = dx.shape rad = np.sqrt(dx**2 + dy**2) angle = np.arctan2(-dy, -dx) / np.pi bin_real = (angle + 1) / 2 * (num_bins - 1) bin_left = np.floor(bin_real).astype(int) bin_right = (bin_left + 1) % num_bins w = (bin_real - bin_left.astype(np.float32))[..., None] flow_img = ( 1 - w) * color_wheel[bin_left, :] + w * color_wheel[bin_right, :] small_ind = rad <= 1 flow_img[small_ind] = 1 - rad[small_ind, None] * (1 - flow_img[small_ind]) flow_img[np.logical_not(small_ind)] *= 0.75 flow_img[ignore_inds, :] = 0 return flow_img
[docs]def make_color_wheel(bins=None): """Build a color wheel Args: bins(list or tuple, optional): specify number of bins for each color range, corresponding to six ranges: red -> yellow, yellow -> green, green -> cyan, cyan -> blue, blue -> magenta, magenta -> red. [15, 6, 4, 11, 13, 6] is used for default (see Middlebury). Returns: ndarray: color wheel of shape (total_bins, 3) """ if bins is None: bins = [15, 6, 4, 11, 13, 6] assert len(bins) == 6 RY, YG, GC, CB, BM, MR = tuple(bins) ry = [1, np.arange(RY) / RY, 0] yg = [1 - np.arange(YG) / YG, 1, 0] gc = [0, 1, np.arange(GC) / GC] cb = [0, 1 - np.arange(CB) / CB, 1] bm = [np.arange(BM) / BM, 0, 1] mr = [1, 0, 1 - np.arange(MR) / MR] num_bins = RY + YG + GC + CB + BM + MR color_wheel = np.zeros((3, num_bins), dtype=np.float32) col = 0 for i, color in enumerate([ry, yg, gc, cb, bm, mr]): for j in range(3): color_wheel[j, col:col + bins[i]] = color[j] col += bins[i] return color_wheel.T