Skip to content

Commit 77f1c97

Browse files
committed
Restructured code
1 parent df7432b commit 77f1c97

File tree

7 files changed

+288
-274
lines changed

7 files changed

+288
-274
lines changed

__init__.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
1-
from .utils import *
2-
from .iqa import *
1+
from .ssim import ssim, ms_ssim
2+
from .vif import vif_spatial, vif
3+
from .brisque import brisque
4+
from .niqe import niqe

brisque.py

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from .utils import compute_image_mscn_transform, extract_subband_feats
2+
3+
import numpy as np
4+
import cv2
5+
6+
7+
# TODO: Compare with Matlab
8+
def brisque(image):
9+
y_mscn = compute_image_mscn_transform(image)
10+
half_scale = cv2.resize(image, dsize=(0, 0), fx=0.5, fy=0.5, interpolation=cv2.INTER_LANCZOS4)
11+
y_half_mscn = compute_image_mscn_transform(half_scale)
12+
feats_full = extract_subband_feats(y_mscn)
13+
feats_half = extract_subband_feats(y_half_mscn)
14+
return np.concatenate((feats_full, feats_half))

iqa.py

-203
This file was deleted.

niqe.py

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
2+
from .utils import compute_image_mscn_transform, extract_on_patches
3+
4+
import numpy as np
5+
import scipy.io
6+
import cv2
7+
import os
8+
9+
10+
def niqe(img):
11+
blocksizerow = 96
12+
blocksizecol = 96
13+
h, w = img.shape
14+
15+
module_path = os.path.dirname(__file__)
16+
params = scipy.io.loadmat(os.path.join(module_path, 'niqe_nss_parameters.mat'))
17+
mu_prisparam = params['mu_prisparam']
18+
cov_prisparam = params['cov_prisparam']
19+
if (h < blocksizerow) or (w < blocksizecol):
20+
print("Input frame is too small")
21+
exit(0)
22+
23+
# ensure that the patch divides evenly into img
24+
hoffset = (h % blocksizerow)
25+
woffset = (w % blocksizecol)
26+
27+
if hoffset > 0:
28+
img = img[:-hoffset, :]
29+
if woffset > 0:
30+
img = img[:, :-woffset]
31+
32+
img = img.astype(np.float32)
33+
34+
scale_percent = 50 # percent of original size
35+
width = int(img.shape[1] * scale_percent / 100)
36+
height = int(img.shape[0] * scale_percent / 100)
37+
38+
img2 = cv2.resize(img, (height, width), interpolation=cv2.INTER_CUBIC)
39+
40+
mscn1 = compute_image_mscn_transform(img, extend_mode='nearest')
41+
mscn1 = mscn1.astype(np.float32)
42+
43+
mscn2 = compute_image_mscn_transform(img2, extend_mode='nearest')
44+
mscn2 = mscn2.astype(np.float32)
45+
46+
feats_lvl1 = extract_on_patches(mscn1, blocksizerow, blocksizecol)
47+
feats_lvl2 = extract_on_patches(mscn2, blocksizerow/2, blocksizecol/2)
48+
49+
# stack the scale features
50+
feats = np.hstack((feats_lvl1, feats_lvl2))
51+
52+
mu_distparam = np.mean(feats, axis=0)
53+
cov_distparam = np.cov(feats.T)
54+
55+
invcov_param = np.linalg.pinv((cov_prisparam + cov_distparam)/2)
56+
57+
xd = mu_prisparam - mu_distparam
58+
quality = np.sqrt(np.dot(np.dot(xd, invcov_param), xd.T))[0][0]
59+
60+
return np.hstack((mu_distparam, [quality]))

ssim.py

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
from .utils import moments
2+
3+
import numpy as np
4+
5+
6+
def ssim(img_ref, img_dist, k=11, max_val=1, K1=0.01, K2=0.03, no_lum=False, full=False, padding=None, stride=1):
7+
x = img_ref.astype('float32')
8+
y = img_dist.astype('float32')
9+
mu_x, mu_y, var_x, var_y, cov_xy = moments(x, y, k, stride, padding=padding)
10+
11+
C1 = (max_val*K1)**2
12+
C2 = (max_val*K2)**2
13+
14+
if not no_lum:
15+
l = (2*mu_x*mu_y + C1)/(mu_x**2 + mu_y**2 + C1)
16+
cs = (2*cov_xy + C2)/(var_x + var_y + C2)
17+
18+
ssim_map = cs
19+
if not no_lum:
20+
ssim_map *= l
21+
22+
if (full):
23+
return (np.mean(ssim_map), ssim_map)
24+
else:
25+
return np.mean(ssim_map)
26+
27+
28+
def ms_ssim(img_ref, img_dist, k=11, max_val=1, K1=0.01, K2=0.03, full=False, padding=None, stride=1):
29+
x = img_ref.astype('float32')
30+
y = img_dist.astype('float32')
31+
32+
n_levels = 5
33+
weights = np.array([0.0448, 0.2856, 0.3001, 0.2363, 0.1333])
34+
scores = np.ones((n_levels,))
35+
for i in range(n_levels-1):
36+
if np.min(x.shape) <= k:
37+
break
38+
scores[i] = ssim(x, y, k, max_val, K1, K2, no_lum=True, padding=padding, stride=stride)
39+
x = x[:(x.shape[0]//2)*2, :(x.shape[1]//2)*2]
40+
y = y[:(y.shape[0]//2)*2, :(y.shape[1]//2)*2]
41+
x = (x[::2, ::2] + x[1::2, ::2] + x[1::2, 1::2] + x[::2, 1::2])/4
42+
y = (y[::2, ::2] + y[1::2, ::2] + y[1::2, 1::2] + y[::2, 1::2])/4
43+
44+
if np.min(x.shape) > k:
45+
scores[-1] = ssim(x, y, k, max_val, K1, K2, no_lum=False, padding=padding, stride=stride)
46+
msssim = np.prod(np.power(scores, weights))
47+
if full:
48+
return msssim, scores
49+
else:
50+
return msssim

0 commit comments

Comments
 (0)