cutcutcodec.core.signal.metric
This module, implemented in C, offers functions for image metric calculation.
Functions
Compute the peak signal to noise ratio of 2 images in C language. |
|
Compute the Structural similarity index measure of 2 images in C language. |
Details
- cutcutcodec.core.signal.metric.psnr()
Compute the peak signal to noise ratio of 2 images in C language.
This function is nearly equivalent to:
import math import numpy as np def psnr(im1: np.ndarray, im2: np.ndarray, weights = None) -> float: if weights is None: weights = [1.0 for _ in range(im1.shape[2])] layers_mse = ((im1 - im2)**2).mean(axis=(0, 1)).tolist() tot = sum(weights) mse = sum(l*w/tot for w, l in zip(weights, layers_mse)) return -10.0*math.log10(mse) if mse > 1e-10 else 100.0
Parameters
- im1, im2np.ndarray
The 2 images to be compared, of shape (height, width, channels). Supported types are float32 and float64.
- threadsint, optional
Defines the number of threads. The value -1 means that the function uses as many calculation threads as there are cores. The default value (0) allows the same behavior as (-1) if the function is called in the main thread, otherwise (1) to avoid nested threads. Any other positive value corresponds to the number of threads used.
Returns
- psnrfloat
The global peak signal to noise ratio, as a ponderation of the mean square error of each channel.
Examples
>>> import numpy as np >>> from cutcutcodec.core.signal.metric import psnr >>> im1 = np.random.random((1080, 1920, 3)) >>> im2 = 0.8*im1 + 0.2*np.random.random((1080, 1920, 3)) >>> round(psnr(im1, im2)) 22 >>>
- cutcutcodec.core.signal.metric.ssim()
Compute the Structural similarity index measure of 2 images in C language.
This fonction is nearly equivalent to these functions:
import cv2 import numpy as np def ssim( im1: np.ndarray, im2: np.ndarray, data_range : float = 1.0, weights = None, sigma: float = 1.5 ) -> float: # get gaussian window r = int(3.5 * sigma + 0.5) # same as skimage.metrics.structural_similarity gauss = np.exp(-(np.arange(-r, r+1)**2) / (2.0 * sigma**2)) gauss_i, gauss_j = np.meshgrid(gauss, gauss, indexing="ij") gauss = gauss_i * gauss_j gauss /= gauss.sum() # compute statistics for all patches mu1 = cv2.filter2D(im1, ddepth=-1, kernel=gauss) mu2 = cv2.filter2D(im2, ddepth=-1, kernel=gauss) mu11, mu22, mu12 = mu1 * mu1, mu2 * mu2, mu1 * mu2 s11 = cv2.filter2D(im1*im1, ddepth=-1, kernel=gauss) - mu11 s22 = cv2.filter2D(im2*im2, ddepth=-1, kernel=gauss) - mu22 s12 = cv2.filter2D(im1*im2, ddepth=-1, kernel=gauss) - mu12 # crop patches mu11, mu22, mu12 = mu11[r:-r, r:-r], mu22[r:-r, r:-r], mu12[r:-r, r:-r] s11, s22, s12 = s11[r:-r, r:-r], s22[r:-r, r:-r], s12[r:-r, r:-r] # ssim formula c1, c2 = (0.01 * data_range)**2, (0.03 * data_range)**2 ssim = ((2.0*mu12 + c1) * (2.0*s12 + c2)) / ((mu11 + mu22 + c1) * (s11 + s22 + c2)) # average if weights is None: weights = [1.0 for _ in range(im1.shape[2])] weights = np.asarray(weights, dtype=im1.dtype) return float((ssim.mean(axis=(0, 1)) * weights).sum() / weights.sum())
Or directly using scikit-image:
from skimage.metrics import structural_similarity def ssim( im1: np.ndarray, im2: np.ndarray, data_range : float = 1.0, weights = None, sigma: float = 1.5 ) -> float: if weights is None: weights = [1.0 for _ in range(im1.shape[2])] ssim = 0.0 for i in range(im1.shape[2]): ssim += structural_similarity( im1[:, :, i], im2[:, :, i], data_range=data_range, sigma=sigma, gaussian_weights=True ) * weights[i] return ssim / sum(weights)
Parameters
- im1, im2np.ndarray
The 2 images to be compared, of shape (height, width, channels). Supported types are float32 and float64.
- data_rangefloat, default=1.0
The data range of the input image (difference between maximum and minimum possible values).
- weightsiterable[float], optional
The relative weight of each channel. By default, all channels have the same weight.
- sigmafloat, default=1.5
The standard deviation of the gaussian.
- threadsint, optional
Defines the number of threads. The value -1 means that the function uses as many calculation threads as there are cores. The default value (0) allows the same behavior as (-1) if the function is called in the main thread, otherwise (1) to avoid nested threads. Any other positive value corresponds to the number of threads used.
Returns
- ssimfloat
The ponderated structural similarity index measure of each layers.
Examples
>>> import numpy as np >>> from cutcutcodec.core.signal.metric import ssim >>> im1 = np.random.random((1080, 1920, 3)) >>> im2 = 0.8*im1 + 0.2*np.random.random((1080, 1920, 3)) >>> round(ssim(im1, im2), 2) 0.95 >>>