From 606d503f828777b11df4e959d6a5b25b4a86e0c7 Mon Sep 17 00:00:00 2001 From: Daniil Kazantsev Date: Sat, 23 Feb 2019 21:49:04 +0000 Subject: supp created, pillow dependency corrected in yaml --- Readme.md | 2 +- Wrappers/Python/ccpi/supp/__init__.py | 0 Wrappers/Python/ccpi/supp/qualitymetrics.py | 65 ----------------------------- recipe/meta.yaml | 3 +- src/Python/ccpi/supp/__init__.py | 0 src/Python/ccpi/supp/qualitymetrics.py | 65 +++++++++++++++++++++++++++++ 6 files changed, 68 insertions(+), 67 deletions(-) delete mode 100644 Wrappers/Python/ccpi/supp/__init__.py delete mode 100644 Wrappers/Python/ccpi/supp/qualitymetrics.py create mode 100644 src/Python/ccpi/supp/__init__.py create mode 100644 src/Python/ccpi/supp/qualitymetrics.py diff --git a/Readme.md b/Readme.md index 3a39066..92b4273 100644 --- a/Readme.md +++ b/Readme.md @@ -110,7 +110,7 @@ conda install ccpi-regulariser -c ccpi -c conda-forge #### Python (conda-build) ``` export CIL_VERSION=19.02 - conda build Wrappers/Python/conda-recipe --numpy 1.12 --python 3.5 + conda build recipe/ --numpy 1.12 --python 3.5 conda install ccpi-regulariser=${CIL_VERSION} --use-local --force cd demos/ python demo_cpu_regularisers.py # to run CPU demo diff --git a/Wrappers/Python/ccpi/supp/__init__.py b/Wrappers/Python/ccpi/supp/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/Wrappers/Python/ccpi/supp/qualitymetrics.py b/Wrappers/Python/ccpi/supp/qualitymetrics.py deleted file mode 100644 index f44d832..0000000 --- a/Wrappers/Python/ccpi/supp/qualitymetrics.py +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env python2 -# -*- coding: utf-8 -*- -""" -A class for some standard image quality metrics -""" -import numpy as np - -class QualityTools: - def __init__(self, im1, im2): - if im1.size != im2.size: - print ('Error: Sizes of images/volumes are different') - raise SystemExit - self.im1 = im1 # image or volume - 1 - self.im2 = im2 # image or volume - 2 - def nrmse(self): - """ Normalised Root Mean Square Error """ - rmse = np.sqrt(np.sum((self.im2 - self.im1) ** 2) / float(self.im1.size)) - max_val = max(np.max(self.im1), np.max(self.im2)) - min_val = min(np.min(self.im1), np.min(self.im2)) - return 1 - (rmse / (max_val - min_val)) - def rmse(self): - """ Root Mean Square Error """ - rmse = np.sqrt(np.sum((self.im1 - self.im2) ** 2) / float(self.im1.size)) - return rmse - def ssim(self, window, k=(0.01, 0.03), l=255): - from scipy.signal import fftconvolve - """See https://ece.uwaterloo.ca/~z70wang/research/ssim/""" - # Check if the window is smaller than the images. - for a, b in zip(window.shape, self.im1.shape): - if a > b: - return None, None - # Values in k must be positive according to the base implementation. - for ki in k: - if ki < 0: - return None, None - - c1 = (k[0] * l) ** 2 - c2 = (k[1] * l) ** 2 - window = window/np.sum(window) - - mu1 = fftconvolve(self.im1, window, mode='valid') - mu2 = fftconvolve(self.im2, window, mode='valid') - mu1_sq = mu1 * mu1 - mu2_sq = mu2 * mu2 - mu1_mu2 = mu1 * mu2 - sigma1_sq = fftconvolve(self.im1 * self.im1, window, mode='valid') - mu1_sq - sigma2_sq = fftconvolve(self.im2 * self.im2, window, mode='valid') - mu2_sq - sigma12 = fftconvolve(self.im1 * self.im2, window, mode='valid') - mu1_mu2 - - if c1 > 0 and c2 > 0: - num = (2 * mu1_mu2 + c1) * (2 * sigma12 + c2) - den = (mu1_sq + mu2_sq + c1) * (sigma1_sq + sigma2_sq + c2) - ssim_map = num / den - else: - num1 = 2 * mu1_mu2 + c1 - num2 = 2 * sigma12 + c2 - den1 = mu1_sq + mu2_sq + c1 - den2 = sigma1_sq + sigma2_sq + c2 - ssim_map = np.ones(np.shape(mu1)) - index = (den1 * den2) > 0 - ssim_map[index] = (num1[index] * num2[index]) / (den1[index] * den2[index]) - index = (den1 != 0) & (den2 == 0) - ssim_map[index] = num1[index] / den1[index] - mssim = ssim_map.mean() - return mssim, ssim_map diff --git a/recipe/meta.yaml b/recipe/meta.yaml index 61d17bd..527ad32 100644 --- a/recipe/meta.yaml +++ b/recipe/meta.yaml @@ -12,7 +12,8 @@ test: files: - ../test/lena_gray_512.tif requires: - - pillow=4.1.1 + - pillow + - pillow=4.1.1 # [win] requirements: build: diff --git a/src/Python/ccpi/supp/__init__.py b/src/Python/ccpi/supp/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/Python/ccpi/supp/qualitymetrics.py b/src/Python/ccpi/supp/qualitymetrics.py new file mode 100644 index 0000000..f44d832 --- /dev/null +++ b/src/Python/ccpi/supp/qualitymetrics.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python2 +# -*- coding: utf-8 -*- +""" +A class for some standard image quality metrics +""" +import numpy as np + +class QualityTools: + def __init__(self, im1, im2): + if im1.size != im2.size: + print ('Error: Sizes of images/volumes are different') + raise SystemExit + self.im1 = im1 # image or volume - 1 + self.im2 = im2 # image or volume - 2 + def nrmse(self): + """ Normalised Root Mean Square Error """ + rmse = np.sqrt(np.sum((self.im2 - self.im1) ** 2) / float(self.im1.size)) + max_val = max(np.max(self.im1), np.max(self.im2)) + min_val = min(np.min(self.im1), np.min(self.im2)) + return 1 - (rmse / (max_val - min_val)) + def rmse(self): + """ Root Mean Square Error """ + rmse = np.sqrt(np.sum((self.im1 - self.im2) ** 2) / float(self.im1.size)) + return rmse + def ssim(self, window, k=(0.01, 0.03), l=255): + from scipy.signal import fftconvolve + """See https://ece.uwaterloo.ca/~z70wang/research/ssim/""" + # Check if the window is smaller than the images. + for a, b in zip(window.shape, self.im1.shape): + if a > b: + return None, None + # Values in k must be positive according to the base implementation. + for ki in k: + if ki < 0: + return None, None + + c1 = (k[0] * l) ** 2 + c2 = (k[1] * l) ** 2 + window = window/np.sum(window) + + mu1 = fftconvolve(self.im1, window, mode='valid') + mu2 = fftconvolve(self.im2, window, mode='valid') + mu1_sq = mu1 * mu1 + mu2_sq = mu2 * mu2 + mu1_mu2 = mu1 * mu2 + sigma1_sq = fftconvolve(self.im1 * self.im1, window, mode='valid') - mu1_sq + sigma2_sq = fftconvolve(self.im2 * self.im2, window, mode='valid') - mu2_sq + sigma12 = fftconvolve(self.im1 * self.im2, window, mode='valid') - mu1_mu2 + + if c1 > 0 and c2 > 0: + num = (2 * mu1_mu2 + c1) * (2 * sigma12 + c2) + den = (mu1_sq + mu2_sq + c1) * (sigma1_sq + sigma2_sq + c2) + ssim_map = num / den + else: + num1 = 2 * mu1_mu2 + c1 + num2 = 2 * sigma12 + c2 + den1 = mu1_sq + mu2_sq + c1 + den2 = sigma1_sq + sigma2_sq + c2 + ssim_map = np.ones(np.shape(mu1)) + index = (den1 * den2) > 0 + ssim_map[index] = (num1[index] * num2[index]) / (den1[index] * den2[index]) + index = (den1 != 0) & (den2 == 0) + ssim_map[index] = num1[index] / den1[index] + mssim = ssim_map.mean() + return mssim, ssim_map -- cgit v1.2.3