Пример #1
0
    def compare(self, image: np.ndarray, reference: np.ndarray) -> float:
        # This implementations is based on
        # https://docs.opencv.org/2.4/doc/tutorials/highgui/video-input-psnr-ssim/video-input-psnr-ssim.html
        _, max_pixel_value = _utilities._get_image_dtype_range(image.dtype)
        C1 = (self._k1 * max_pixel_value)**2.0
        C2 = (self._k2 * max_pixel_value)**2.0
        image = image.astype(compimg.config.intermediate_dtype)
        reference = reference.astype(compimg.config.intermediate_dtype)
        x = image
        y = reference
        y_squared = reference * reference
        x_squared = image * image
        x_times_y = image * reference
        x_mean = kernels.convolve(x, _SSIM_GAUSSIAN_KERNEL_11X11)
        y_mean = kernels.convolve(y, _SSIM_GAUSSIAN_KERNEL_11X11)
        x_mean_squared = x_mean * x_mean
        y_mean_squared = y_mean * y_mean
        sigma_x_squared = kernels.convolve(x_squared,
                                           _SSIM_GAUSSIAN_KERNEL_11X11)
        sigma_x_squared -= x_mean_squared
        sigma_y_squared = kernels.convolve(y_squared,
                                           _SSIM_GAUSSIAN_KERNEL_11X11)
        sigma_y_squared -= y_mean_squared
        sigma_x_y = kernels.convolve(x_times_y, _SSIM_GAUSSIAN_KERNEL_11X11)
        sigma_x_y -= x_mean * y_mean

        t1 = 2 * x_mean * y_mean + C1
        t2 = 2 * sigma_x_y + C2
        t3 = t1 * t2

        t1 = x_mean_squared + y_mean_squared + C1
        t2 = sigma_x_squared + sigma_y_squared + C2
        t1 = t1 * t2
        ssim_map = t3 / t1
        return np.mean(ssim_map)
Пример #2
0
def test_convolve_work_correctly_on_one_channel_image():
    image = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype=np.uint8)
    kernel = kernels.BOX_BLUR_3X3

    filtered_image = kernels.convolve(image, kernel)
    assert filtered_image.shape == (1, 1)
    assert filtered_image[0][0] == 5.0
Пример #3
0
def test_convolve_work_correctly_on_three_channels():
    image = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype=np.uint8)
    image = image.reshape((3, 3, 1))
    image = np.concatenate((image, image, image), axis=2)
    kernel = kernels.BOX_BLUR_3X3

    filtered_image = kernels.convolve(image, kernel)
    assert filtered_image.shape == (1, 1, 3)
    assert np.array_equal(filtered_image[0][0], [5.0, 5.0, 5.0])
Пример #4
0
    def compare(self, image: np.ndarray, reference: np.ndarray) -> float:
        _, max_pixel_value = _utilities._get_image_dtype_range(image.dtype)
        C1 = (self._k1 * max_pixel_value)**2.0
        C2 = (self._k2 * max_pixel_value)**2.0
        C3 = C2 / 2.0
        image = image.astype(compimg.config.intermediate_dtype)
        reference = reference.astype(compimg.config.intermediate_dtype)
        x = image
        y = image
        x_mean = kernels.convolve(x, _SSIM_GAUSSIAN_KERNEL_11X11)
        y_mean = kernels.convolve(y, _SSIM_GAUSSIAN_KERNEL_11X11)
        x_mean_squared = x_mean * x_mean
        y_mean_squared = y_mean * y_mean

        sobel_image = self._apply_sobel(image)
        sobel_reference = self._apply_sobel(reference)
        # sx means sobel_x
        sx_squared = sobel_image * sobel_image
        sy_squared = sobel_reference * sobel_reference
        sxy = sobel_reference * sobel_image
        sx_mean = kernels.convolve(sobel_image, _SSIM_GAUSSIAN_KERNEL_11X11)
        sy_mean = kernels.convolve(sobel_reference,
                                   _SSIM_GAUSSIAN_KERNEL_11X11)
        sx_mean_squared = sx_mean * sx_mean
        sy_mean_squared = sy_mean * sy_mean

        sigma_sx_squared = kernels.convolve(sx_squared,
                                            _SSIM_GAUSSIAN_KERNEL_11X11)
        sigma_sx_squared -= sx_mean_squared
        sigma_sy_squared = kernels.convolve(sy_squared,
                                            _SSIM_GAUSSIAN_KERNEL_11X11)
        sigma_sy_squared -= sy_mean_squared
        sigma_sxy = kernels.convolve(sxy, _SSIM_GAUSSIAN_KERNEL_11X11)
        sigma_sxy -= sx_mean * sy_mean
        luminance = (2 * x_mean * y_mean + C1) / (x_mean_squared +
                                                  y_mean_squared + C1)
        contrast = (2 * np.sqrt(sigma_sx_squared) * np.sqrt(sigma_sy_squared) +
                    C2) / (sigma_sx_squared + sigma_sy_squared + C2)
        structure = (sigma_sxy + C3) / (
            np.sqrt(sigma_sx_squared) * np.sqrt(sigma_sy_squared) + C3)
        return np.mean(luminance * contrast * structure)
Пример #5
0
 def _apply_sobel(self, array: np.ndarray) -> np.ndarray:
     array = EdgePad(1).apply(array)
     array1 = kernels.convolve(array, kernels.HORIZONTAL_SOBEL_3x3)
     array2 = kernels.convolve(array, kernels.VERTICAL_SOBEL_3x3)
     return array1 + array2
Пример #6
0
def test_convolve_raises_when_kernel_is_not_2d_array():
    image = np.zeros((10, 10))
    kernel = np.array(np.ones((4, 4, 3)))
    with pytest.raises(KernelNot2DArray):
        kernels.convolve(image, kernel)
Пример #7
0
def test_convolve_raises_when_kernel_is_not_odd_shape():
    image = np.zeros((10, 10))
    kernel = np.array(np.ones((4, 4)))
    with pytest.raises(KernelShapeNotOddError):
        kernels.convolve(image, kernel)
Пример #8
0
def test_convolve_raises_when_kernel_is_bigger():
    image = np.zeros((2, 2))
    kernel = kernels.BOX_BLUR_3X3
    with pytest.raises(KernelBiggerThanImageError):
        kernels.convolve(image, kernel)