HolmesShuan / EDSR-ssim

Different SSIM metrics in CNN-based super resolution algorithms (e.g., EDSR CVPRW2017, RDN CVPR2018, MSRN ECCV2018).
BSD 2-Clause "Simplified" License
38 stars 4 forks source link

error while using ssim in my code, I have modified the code as you said but their is error as it always give ssim value to be 1. #1

Closed nanmehta closed 3 years ago

nanmehta commented 3 years ago

def test(self): torch.set_grad_enabled(False) epoch = self.optimizer.get_last_epoch() self.ckp.write_log('\nEvaluation:') self.ckp.add_log( torch.zeros(1, len(self.loader_test), len(self.scale)) ) self.model.eval() timer_test = utility.timer() if self.args.save_results: self.ckp.begin_background()

results_path = './results/' + cfg['sub_name'] + '/ICCV_now'

    for idx_data, d in enumerate(self.loader_test):
        for idx_scale, scale in enumerate(self.scale):
            d.dataset.set_scale(idx_scale)
            for lr, hr, filename in tqdm(d, ncols=80):
                lr, hr = self.prepare(lr, hr)
                sr = self.model(lr, idx_scale)
                sr = utility.quantize(sr, self.args.rgb_range)
                save_list = [sr]
                self.ckp.log[-1, idx_data, idx_scale] += utility.calc_ssim(sr, hr, scale, self.args.rgb_range, dataset=d)
                print(self.ckp.log)
                if self.args.save_gt:
                    save_list.extend([lr, hr])
                if self.args.save_results:
                    self.ckp.save_results(d, filename[0], save_list, scale)
            self.ckp.log[-1, idx_data, idx_scale] /= len(d)
            best = self.ckp.log.max(0)
            print("best",best)
            self.ckp.write_log(
                '[{} x{}]\tSSIM: {:.3f} (Best: {:.3f} @epoch {})'.format(
                    d.dataset.name,
                    scale,
                    self.ckp.log[-1, idx_data, idx_scale],
                    best[0][idx_data, idx_scale],
                    best[1][idx_data, idx_scale] + 1
                )
            )
HolmesShuan commented 3 years ago

FYI.

def test_ssim(self):
        torch.set_grad_enabled(False)

        epoch = self.optimizer.get_last_epoch()
        self.ckp.write_log('\nEvaluation:')
        self.ckp.add_log(
            torch.zeros(1, len(self.loader_test), len(self.scale))
        )
        self.model.eval()

        timer_test = utility.timer()
        if self.args.save_results: self.ckp.begin_background()
        for idx_data, d in enumerate(self.loader_test):
            for idx_scale, scale in enumerate(self.scale):
                d.dataset.set_scale(idx_scale)
                for lr, hr, filename in tqdm(d, ncols=80):
                    lr, hr = self.prepare(lr, hr)
                    sr = self.model(lr, idx_scale)
                    sr = utility.quantize(sr, self.args.rgb_range)

                    if self.args.rgb_range == 1 or self.args.rgb_range == 1.:
                        sr = sr.mul(255.)
                        hr = hr.mul(255.)

                    save_list = [sr]
                    self.ckp.log[-1, idx_data, idx_scale] += utility.calc_ssim(sr, hr, scale, self.args.rgb_range, dataset=d)
                    if self.args.save_gt:
                        save_list.extend([lr, hr])

                    if self.args.save_results:
                        self.ckp.save_results(d, filename[0], save_list, scale)

                self.ckp.log[-1, idx_data, idx_scale] /= len(d)
                best = self.ckp.log.max(0)
                self.ckp.write_log(
                    '[{} x{}]\tPSNR: {:.6f} (Best: {:.6f} @epoch {})'.format(
                        d.dataset.name,
                        scale,
                        self.ckp.log[-1, idx_data, idx_scale],
                        best[0][idx_data, idx_scale],
                        best[1][idx_data, idx_scale] + 1
                    )
                )

        self.ckp.write_log('Forward: {:.2f}s\n'.format(timer_test.toc()))
        self.ckp.write_log('Saving...')

        if self.args.save_results:
            self.ckp.end_background()

        if not self.args.test_only:
            self.ckp.save(self, epoch, is_best=(best[1][0, 0] + 1 == epoch))

        self.ckp.write_log(
            'Total: {:.2f}s\n'.format(timer_test.toc()), refresh=True
        )

        torch.set_grad_enabled(True)

SSIM

def matlab_style_gauss2D(shape=(3,3),sigma=0.5):
  """
  2D gaussian mask - should give the same result as MATLAB's fspecial('gaussian',[shape],[sigma])
  Acknowledgement : https://stackoverflow.com/questions/17190649/how-to-obtain-a-gaussian-filter-in-python (Author@ali_m)
  """
  m,n = [(ss-1.)/2. for ss in shape]
  y,x = np.ogrid[-m:m+1,-n:n+1]
  h = np.exp( -(x*x + y*y) / (2.*sigma*sigma) )
  h[ h < np.finfo(h.dtype).eps*h.max() ] = 0
  sumh = h.sum()
  if sumh != 0:
    h /= sumh
  return h

def calc_ssim(X, Y, scale, rgb_range, dataset=None, sigma=1.5, K1=0.01, K2=0.03, R=255):
  '''
  X : y channel (i.e., luminance) of transformed YCbCr space of X
  Y : y channel (i.e., luminance) of transformed YCbCr space of Y
  Please follow the setting of psnr_ssim.m in EDSR (Enhanced Deep Residual Networks for Single Image Super-Resolution CVPRW2017).
  Official Link : https://github.com/LimBee/NTIRE2017/tree/db34606c2844e89317aac8728a2de562ef1f8aba
  The authors of EDSR use MATLAB's ssim as the evaluation tool, 
  thus this function is the same as ssim.m in MATLAB with C(3) == C(2)/2. 
  '''
  # print(X, Y)

  gaussian_filter = matlab_style_gauss2D((11, 11), sigma)

  if dataset and dataset.dataset.benchmark:
    shave = scale
    if X.size(1) > 1:
        gray_coeffs = [65.738, 129.057, 25.064]
        convert = X.new_tensor(gray_coeffs).view(1, 3, 1, 1) / 256
        X = X.mul(convert).sum(dim=1)
        Y = Y.mul(convert).sum(dim=1)
  else:
    shave = scale + 6

  X = X[..., shave:-shave, shave:-shave].squeeze().cpu().numpy().astype(np.float64) 
  Y = Y[..., shave:-shave, shave:-shave].squeeze().cpu().numpy().astype(np.float64)

  window = gaussian_filter

  ux = signal.convolve2d(X, window, mode='same', boundary='symm')
  uy = signal.convolve2d(Y, window, mode='same', boundary='symm')

  uxx = signal.convolve2d(X*X, window, mode='same', boundary='symm')
  uyy = signal.convolve2d(Y*Y, window, mode='same', boundary='symm')
  uxy = signal.convolve2d(X*Y, window, mode='same', boundary='symm')

  vx = uxx - ux * ux
  vy = uyy - uy * uy
  vxy = uxy - ux * uy

  C1 = (K1 * R) ** 2
  C2 = (K2 * R) ** 2

  A1, A2, B1, B2 = ((2 * ux * uy + C1, 2 * vxy + C2, ux ** 2 + uy ** 2 + C1, vx + vy + C2))
  D = B1 * B2
  S = (A1 * A2) / D
  mssim = S.mean()

  return mssim
nanmehta commented 3 years ago

yes sir I have copied this code in utility.py and modified the test code also as I have shown in the above text.

But my ssim is always coming 1

This is the result , I am getting [Set14 x4] SSIM: 1.000 (Best: 1.000 @epoch 1) Forward: 23.66s

Saving... Total: 23.99s

HolmesShuan commented 3 years ago

It is weird. What about the PSNR results?

There is a typo in my code:

self.ckp.write_log(
                    '[{} x{}]\tPSNR: {:.6f} (Best: {:.6f} @epoch {})'.format(
                        d.dataset.name,
                        scale,
                        self.ckp.log[-1, idx_data, idx_scale],
                        best[0][idx_data, idx_scale],
                        best[1][idx_data, idx_scale] + 1
                    )

where PSNR should be SSIM.

My environment is as follow:

Package               Version               Location
--------------------- --------------------- ---------------------------------------------
absl-py               0.9.0
astor                 0.8.1
certifi               2018.11.29
chardet               3.0.4
cycler                0.10.0
Cython                0.29.7
decorator             4.4.0
detail                4.0
easydict              1.9
future                0.18.2
gast                  0.3.3
google-pasta          0.2.0
grpcio                1.28.1
h5py                  2.10.0
idna                  2.8
imageio               2.5.0
Keras-Applications    1.0.8
Keras-Preprocessing   1.1.0
kiwisolver            1.0.1
kmeans-pytorch        0.3
Markdown              3.2.1
matplotlib            3.0.3
networkx              2.3
ninja                 1.9.0
nose                  1.3.7
numpy                 1.16.3
opencv-contrib-python 3.4.2.17
opencv-python         4.3.0.36
Pillow                5.4.1
pip                   20.1
protobuf              3.11.3
pyparsing             2.4.0
python-dateutil       2.8.0
PyWavelets            1.0.3
PyYAML                5.3.1
quantizer-cpp         0.0.0
rawpy                 0.14.0
requests              2.21.0
scikit-image          0.15.0
scipy                 1.2.1
setuptools            41.0.0
six                   1.12.0
tensorboard           1.15.0
tensorflow-estimator  1.14.0
termcolor             1.1.0
thop                  0.0.31.post2005241907
torch                 1.6.0+cu101
torchvision           0.7.0+cu101
tqdm                  4.31.1
urllib3               1.24.2
Werkzeug              1.0.1
wheel                 0.33.1
wrapt                 1.12.1
xlrd                  1.2.0
nanmehta commented 3 years ago

Thanks, sir, the problem is solved.

Tomchenshi commented 2 years ago

Thanks, sir, the problem is solved.

Hi, sir, how did u solve this problem?