├── README.md └── brisque_features.py /README.md: -------------------------------------------------------------------------------- 1 | # IQA-python 2 | Python code to compute features of classic Image Quality Assessment models 3 | -------------------------------------------------------------------------------- /brisque_features.py: -------------------------------------------------------------------------------- 1 | # Python code for BRISQUE model 2 | # Original paper title: No-Reference Image Quality Assessment in the Spatial Domain 3 | # Link: http://ieeexplore.ieee.org/document/6272356/ 4 | import cv2 5 | import numpy as np 6 | from scipy import ndimage 7 | import math 8 | 9 | def get_gaussian_filter(): 10 | [m,n] = [(ss - 1.0) / 2.0 for ss in (shape,shape)] 11 | [y,x] = np.ogrid[-m:m+1,-n:n+1] 12 | window = np.exp( -(x*x + y*y) / (2.0*sigma*sigma) ) 13 | window[window < np.finfo(window.dtype).eps*window.max() ] = 0 14 | sum_window = window.sum() 15 | if sum_window != 0: 16 | window = np.divide(window, sum_window) 17 | return window 18 | 19 | def lmom(X): 20 | (rows, cols) = X.shape 21 | if cols == 1: 22 | X = X.reshape(1,rows) 23 | n = rows 24 | X.sort() 25 | b = np.zeros(3) 26 | b0 = X.mean() 27 | for r in range(1,4): 28 | Num = np.prod(np.tile(np.arange(r+1,n+1), (r,1))-np.tile(np.arange(1,r+1).reshape(r,1),(1,n-r)),0) 29 | Num = Num.astype(np.float) 30 | Den = np.prod(np.tile(n, (1, r)) - np.arange(1,r+1), 1) 31 | b[r-1] = 1.0/n * sum(Num/Den * X[0,r:]) 32 | L = np.zeros(4) 33 | L[0] = b0 34 | L[1] = 2*b[0] - b0 35 | L[2] = 6*b[1] - 6*b[0] + b0 36 | L[3] = 20*b[2] - 30*b[1] + 12*b[0] - b0 37 | return L 38 | 39 | def compute_features(im): 40 | im = im.astype(np.float) 41 | window = get_gaussian_filter() 42 | scalenum = 2 43 | feat = [] 44 | for itr_scale in range(scalenum): 45 | mu = cv2.filter2D(im, cv2.CV_64F, window, borderType=cv2.BORDER_CONSTANT) 46 | mu_sq = mu * mu 47 | sigma = np.sqrt(abs(cv2.filter2D(im*im, cv2.CV_64F, window, borderType=cv2.BORDER_CONSTANT) - mu_sq)) 48 | structdis = (im-mu)/(sigma+1) 49 | structdis_col_vector = np.reshape(structdis.transpose(), (structdis.size,1)) 50 | L = lmom(structdis.reshape(structdis.size,1)) 51 | feat = np.append(feat,[L[1], L[3]]) 52 | shifts = [[0,1], [1,0], [1,1], [-1,1]] 53 | for itr_shift in shifts: 54 | shifted_structdis = np.roll(structdis, itr_shift[0], axis=0) 55 | shifted_structdis = np.roll(shifted_structdis, itr_shift[1], axis=1) 56 | 57 | shifted_structdis_col_vector = np.reshape(shifted_structdis.T, (shifted_structdis.size,1)) 58 | pair = structdis_col_vector * shifted_structdis_col_vector 59 | L = lmom(pair.reshape(pair.size,1)) 60 | feat = np.append(feat, L) 61 | im = cv2.resize(im, (0,0), fx=0.5, fy=0.5, interpolation=cv2.INTER_CUBIC) 62 | return feat 63 | 64 | 65 | im = ndimage.imread('example.bmp', flatten=True) 66 | feat = compute_features(im) 67 | print feat 68 | --------------------------------------------------------------------------------