Module code >> skvideo.measure.viideo
Fork me on GitHub

Source code for skvideo.measure.viideo

import numpy as np
import scipy.fftpack
import scipy.io
import scipy.ndimage
import scipy.stats

from ..utils import *


def gauss_window_full(lw, sigma):
    sd = np.float32(sigma)
    lw = int(lw)
    weights = [0.0] * (lw)
    sd *= sd
    center = (lw-1)/2.0
    for ii in range(lw):
        x = ii - center
        tmp = np.exp(-0.5 * np.float32(x * x) / sd)
        weights[ii] = tmp
    weights /= np.sum(weights)
    return weights

[docs]def viideo_score(videoData, blocksize=(18, 18), blockoverlap=(8, 8), filterlength=7): """Computes VIIDEO score. [#f1]_ [#f2]_ Since this is a referenceless quality algorithm, only 1 video is needed. This function provides the score computed by the algorithm. Parameters ---------- videoData : ndarray Reference video, ndarray of dimension (T, M, N, C), (T, M, N), (M, N, C), or (M, N), where T is the number of frames, M is the height, N is width, and C is number of channels. blocksize : tuple (2,) blockoverlap: tuple (2,) Returns ------- score : ndarray The video quality score References ---------- .. [#f1] A. Mittal, M. A. Saad and A. C. Bovik, "VIIDEO Software Release", URL: http://live.ece.utexas.edu/research/quality/VIIDEO_release.zip, 2014. .. [#f2] A. Mittal, M. A. Saad and A. C. Bovik, "A 'Completely Blind' Video Integrity Oracle", submitted to IEEE Transactions in Image Processing, 2014. """ features = viideo_features(videoData, blocksize=blocksize, blockoverlap=blockoverlap, filterlength=filterlength) features = features.reshape(features.shape[0], -1, features.shape[3]) n_len, n_blocks, n_feats = features.shape n_len -= 1 gap = n_len/10 step_size = np.round(gap/2.0) if step_size < 1: step_size = 1 scores = [] for itr in range(0, np.int(n_len+1), np.int(step_size)): f1_cum = [] f2_cum = [] for itr_param in range(itr, np.int(np.min((itr+gap+1, n_len)))): low_Fr1 = features[itr_param, :, 2:14] low_Fr2 = features[itr_param+1, :, 2:14] high_Fr1 = features[itr_param, :, 16:] high_Fr2 = features[itr_param+1, :, 16:] vec1 = np.abs(low_Fr1 - low_Fr2) vec2 = np.abs(high_Fr1- high_Fr2) if len(f1_cum) == 0: f1_cum = vec1 f2_cum = vec2 else: f1_cum = np.vstack((f1_cum, vec1)) f2_cum = np.vstack((f2_cum, vec2)) if len(f1_cum) > 0: A = np.zeros((f1_cum.shape[1]), dtype=np.float32) for i in range(f1_cum.shape[1]): if (np.sum(np.abs(f1_cum[:, i])) != 0) & (np.sum(np.abs(f2_cum[:, i])) != 0): A[i] = scipy.stats.pearsonr(f1_cum[:, i], f2_cum[:, i])[0] scores.append(np.mean(A)) change_score = np.abs(scores - np.roll(scores, 1)) return np.mean(change_score) + np.mean(scores)
[docs]def viideo_features(videoData, blocksize=(18, 18), blockoverlap=(8, 8), filterlength=7): """Computes VIIDEO features. [#f1]_ [#f2]_ Since this is a referenceless quality algorithm, only 1 video is needed. This function provides the raw features used by the algorithm. Parameters ---------- videoData : ndarray Reference video, ndarray of dimension (T, M, N, C), (T, M, N), (M, N, C), or (M, N), where T is the number of frames, M is the height, N is width, and C is number of channels. blocksize : tuple (2,) blockoverlap: tuple (2,) Returns ------- features : ndarray The individual features of the algorithm. References ---------- .. [#f1] A. Mittal, M. A. Saad and A. C. Bovik, "VIIDEO Software Release", URL: http://live.ece.utexas.edu/research/quality/VIIDEO_release.zip, 2014. .. [#f2] A. Mittal, M. A. Saad and A. C. Bovik, "A 'Completely Blind' Video Integrity Oracle", submitted to IEEE Transactions in Image Processing, 2014. """ videoData = vshape(videoData) T, M, N, C = videoData.shape assert C == 1, "viideo called with video having %d channels. Please supply only the luminance channel." % (C,) hf = gauss_window_full(filterlength, filterlength/6.0) blockstrideY = blocksize[0]# - blockoverlap[0] blockstrideX = blocksize[1]# - blockoverlap[1] Mn = np.int(np.round((M+blockoverlap[0])/np.float32(blocksize[0]))) Nn = np.int(np.round((N+blockoverlap[1])/np.float32(blocksize[1]))) # compute every 2 frames features = np.zeros((np.int(T/2), Mn, Nn, 28), dtype=np.float32) for k in range(np.int(T/2)): frame1 = videoData[k*2, :, :, 0].astype(np.float32) frame2 = videoData[k*2+1, :, :, 0].astype(np.float32) diff = frame1 - frame2 for itr in range(0, 2): mscn,_,mu= compute_image_mscn_transform(diff, avg_window=hf, extend_mode='nearest') h, v, d1, d2 = paired_product(mscn) top_pad = blockoverlap[0] left_pad = blockoverlap[1] leftover = M % blocksize[0] bot_pad = 0 if (leftover > 0): bot_pad = blockoverlap[0] + blocksize[0] - leftover leftover = N % blocksize[1] right_pad = 0 if (leftover > 0): right_pad = blockoverlap[1] + blocksize[1] - leftover # pad arrays mscn = np.pad(mscn, ((top_pad, bot_pad), (left_pad, right_pad)), mode='constant') h = np.pad(h, ((top_pad, bot_pad), (left_pad, right_pad)), mode='constant') v = np.pad(v, ((top_pad, bot_pad), (left_pad, right_pad)), mode='constant') d1 = np.pad(d1, ((top_pad, bot_pad), (left_pad, right_pad)), mode='constant') d2 = np.pad(d2, ((top_pad, bot_pad), (left_pad, right_pad)), mode='constant') blockheight = blocksize[0] + blockoverlap[0]*2 blockwidth = blocksize[1] + blockoverlap[1]*2 for j in range(Nn): for i in range(Mn): yp = i*blocksize[0] xp = j*blocksize[1] patch = mscn[yp:yp+blockheight, xp:xp+blockwidth].copy() ph = h[yp:yp+blockheight, xp:xp+blockwidth].copy() pv = v[yp:yp+blockheight, xp:xp+blockwidth].copy() pd1 = d1[yp:yp+blockheight, xp:xp+blockwidth].copy() pd2 = d2[yp:yp+blockheight, xp:xp+blockwidth].copy() shape, _, bl, br, _, _ = aggd_features(patch) shapeh, _, blh, brh, _, _ = aggd_features(ph) shapev, _, blv, brv, _, _ = aggd_features(pv) shaped1, _, bld1, brd1, _, _ = aggd_features(pd1) shaped2, _, bld2, brd2, _, _ = aggd_features(pd2) features[k, i, j, itr*14:(itr+1)*14] = np.array([ shape, (bl + br)/2.0, shapev, blv, brv, shapeh, blh, brh, shaped1, bld1, brd1, shaped2, bld2, brd2, ]) diff = mu return features