Skip to content

Commit

Permalink
[Enhance] Align NIQE to MATLAB results (#631)
Browse files Browse the repository at this point in the history
* update NIQE

* update unittest

* update unittest

* update unittest
  • Loading branch information
ckkelvinchan authored Dec 1, 2021
1 parent 711d9b9 commit 9ea4bd3
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 19 deletions.
24 changes: 13 additions & 11 deletions mmedit/core/evaluation/metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from scipy.ndimage.filters import convolve
from scipy.special import gamma

from mmedit.datasets.pipelines.matlab_like_resize import MATLABLikeResize
from .metric_utils import gauss_gradient


Expand Down Expand Up @@ -421,9 +422,10 @@ def niqe_core(img,
num_block_w = math.floor(w / block_size_w)
img = img[0:num_block_h * block_size_h, 0:num_block_w * block_size_w]

distparam = [] # dist param is actually the multiscale features.
distparam = [] # dist param is actually the multiscale features
for scale in (1, 2): # perform on two scales (1, 2)
mu = convolve(img, gaussian_window, mode='nearest')

sigma = np.sqrt(
np.abs(
convolve(np.square(img), gaussian_window, mode='nearest') -
Expand All @@ -443,29 +445,26 @@ def niqe_core(img,
feat.append(compute_feature(block))

distparam.append(np.array(feat))
# matlab bicubic downsample with anti-aliasing
# for simplicity, now we use opencv instead, which will result in
# a slight difference.

# matlab-like bicubic downsample with anti-aliasing
if scale == 1:
h, w = img.shape
img = cv2.resize(
img / 255., (w // 2, h // 2), interpolation=cv2.INTER_LINEAR)
img = img * 255.
resize = MATLABLikeResize(keys=None, scale=0.5)
img = resize._resize(img[:, :, np.newaxis] / 255.)[:, :, 0] * 255.

distparam = np.concatenate(distparam, axis=1)

# fit a MVG (multivariate Gaussian) model to distorted patch features
mu_distparam = np.nanmean(distparam, axis=0)
cov_distparam = np.cov(distparam, rowvar=False) # TODO: use nancov
distparam_no_nan = distparam[~np.isnan(distparam).any(axis=1)]
cov_distparam = np.cov(distparam_no_nan, rowvar=False)

# compute niqe quality, Eq. 10 in the paper
invcov_param = np.linalg.pinv((cov_pris_param + cov_distparam) / 2)
quality = np.matmul(
np.matmul((mu_pris_param - mu_distparam), invcov_param),
np.transpose((mu_pris_param - mu_distparam)))
quality = np.sqrt(quality)

return quality
return np.squeeze(np.sqrt(quality))


def niqe(img, crop_border, input_order='HWC', convert_to='y'):
Expand Down Expand Up @@ -513,6 +512,9 @@ def niqe(img, crop_border, input_order='HWC', convert_to='y'):
if crop_border != 0:
img = img[crop_border:-crop_border, crop_border:-crop_border]

# round to follow official implementation
img = img.round()

niqe_result = niqe_core(img, mu_pris_param, cov_pris_param,
gaussian_window)

Expand Down
16 changes: 8 additions & 8 deletions tests/test_metrics/test_metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,34 +108,34 @@ def test_calculate_niqe():
img = mmcv.imread('tests/data/gt/baboon.png')

result = niqe(img[:, :, 0], crop_border=0, input_order='HW')
np.testing.assert_almost_equal(result, 6.15902, decimal=5)
np.testing.assert_almost_equal(result, 5.62525, decimal=5)
result = niqe(img, crop_border=0, input_order='HWC', convert_to='y')
np.testing.assert_almost_equal(result, 5.85182, decimal=5)
np.testing.assert_almost_equal(result, 5.72957, decimal=5)
result = niqe(img, crop_border=0, input_order='HWC', convert_to='gray')
np.testing.assert_almost_equal(result, 5.89766, decimal=5)
np.testing.assert_almost_equal(result, 5.73154, decimal=5)
result = niqe(
img.transpose(2, 0, 1),
crop_border=0,
input_order='CHW',
convert_to='y')
np.testing.assert_almost_equal(result, 5.85182, decimal=5)
np.testing.assert_almost_equal(result, 5.72957, decimal=5)
result = niqe(
img.transpose(2, 0, 1),
crop_border=0,
input_order='CHW',
convert_to='gray')
np.testing.assert_almost_equal(result, 5.89766, decimal=5)
np.testing.assert_almost_equal(result, 5.73154, decimal=5)

result = niqe(img[:, :, 0], crop_border=6, input_order='HW')
np.testing.assert_almost_equal(result, 6.31046, decimal=5)
np.testing.assert_almost_equal(result, 5.82981, decimal=5)
result = niqe(img, crop_border=6, input_order='HWC', convert_to='y')
np.testing.assert_almost_equal(result, 6.14435, decimal=5)
np.testing.assert_almost_equal(result, 6.10074, decimal=5)
result = niqe(
img.transpose(2, 0, 1),
crop_border=6,
input_order='CHW',
convert_to='y')
np.testing.assert_almost_equal(result, 6.14435, decimal=5)
np.testing.assert_almost_equal(result, 6.10074, decimal=5)


def test_sad():
Expand Down

0 comments on commit 9ea4bd3

Please sign in to comment.