SSIM calculation formula

SSIM is a structural similarity measure, which is an index to measure the similarity of two images. In deep learning, SSIm is used to evaluate the similarity between images generated by generative models such as (GAN) and real images.

 In the illustration, we can observe that the sharpness of the same MSE and different SSIM pictures is very different. It can be seen intuitively that SSIM is a better evaluation index than MSE.

SSIM calculation formula

The calculation of SSIM is mainly determined by three key features of the picture, namely: brightness, contrast, structure

1. Brightness

The brightness of an image is a description of the pixel value of the image. For a single pixel value, the larger the pixel value, the closer to white and brighter it is, and vice versa. The larger the average value of all pixels, the brighter the entire image, and vice versa.

Brightness is measured in average grayscale, obtained by averaging the values ​​of all pixels:

 

 

2. Contrast

Image contrast is a description of the distribution of image pixel values ​​in the entire dynamic range. The wider the distribution of image pixel values ​​in the dynamic range, the better the contrast; otherwise, the tighter the distribution of image pixel values, the poorer the contrast. The description of the distribution range corresponds exactly to the concept of variance or standard deviation

 3. Structure

The structure is described in terms of linear dependencies of pixels. We obtain the terms of the corresponding structure by finding the covariance:

 4. The final calculation formula of SSIM

 4. Torch implements SSIM

def calculate_ssim(img1, img2, border=0):
    '''calculate SSIM
    the same outputs as MATLAB's
    img1, img2: [0, 255]
    '''
    if not img1.shape == img2.shape:
        raise ValueError('Input images must have the same dimensions.')
    h, w = img1.shape[:2]
    img1 = img1[border:h-border, border:w-border]
    img2 = img2[border:h-border, border:w-border]

    if img1.ndim == 2:
        return ssim(img1, img2)
    elif img1.ndim == 3:
        if img1.shape[2] == 3:
            ssims = []
            for i in range(3):
                ssims.append(ssim(img1, img2))
            return np.array(ssims).mean()
        elif img1.shape[2] == 1:
            return ssim(np.squeeze(img1), np.squeeze(img2))
    else:
        raise ValueError('Wrong input image dimensions.')


def ssim(img1, img2):
    C1 = (0.01 * 255)**2
    C2 = (0.03 * 255)**2

    img1 = img1.astype(np.float64)
    img2 = img2.astype(np.float64)
    kernel = cv2.getGaussianKernel(11, 1.5)
    window = np.outer(kernel, kernel.transpose())

    mu1 = cv2.filter2D(img1, -1, window)[5:-5, 5:-5]  # valid
    mu2 = cv2.filter2D(img2, -1, window)[5:-5, 5:-5]
    mu1_sq = mu1**2
    mu2_sq = mu2**2
    mu1_mu2 = mu1 * mu2
    sigma1_sq = cv2.filter2D(img1**2, -1, window)[5:-5, 5:-5] - mu1_sq
    sigma2_sq = cv2.filter2D(img2**2, -1, window)[5:-5, 5:-5] - mu2_sq
    sigma12 = cv2.filter2D(img1 * img2, -1, window)[5:-5, 5:-5] - mu1_mu2

    ssim_map = ((2 * mu1_mu2 + C1) * (2 * sigma12 + C2)) / ((mu1_sq + mu2_sq + C1) *
                                                            (sigma1_sq + sigma2_sq + C2))
    return ssim_map.mean()

Guess you like

Origin blog.csdn.net/qq_46644680/article/details/130940867