SSIMの計算式

SSIM は 2 つの画像の類似性を測る指標である構造類似性尺度であり、ディープラーニングでは、GAN などの生成モデルで生成された画像と実際の画像との類似性を評価するために使用されます。

 この図では、同じ MSE と異なる SSIM 画像の鮮明さが大きく異なることがわかり、SSIM が MSE よりも優れた評価指標であることが直感的にわかります。

SSIMの計算式

SSIM の計算は主に、画像の 3 つの主要な特徴、つまり明るさ、コントラスト、構造によって決定されます。

1.明るさ

画像の明るさは画像のピクセル値を表したもので、単一のピクセル値の場合、ピクセル値が大きいほど白に近づき明るくなり、その逆も同様です。全ピクセルの平均値が大きいほど画像全体が明るくなり、その逆も同様です。

明るさは平均グレースケールで測定され、すべてのピクセルの値を平均することで得られます。

 

 

2. コントラスト

画像のコントラストは、ダイナミック レンジ全体における画像のピクセル値の分布を表したものです。ダイナミック レンジ内の画像のピクセル値の分布が広いほど、コントラストは高くなります。そうでない場合、画像のピクセル値の分布はより厳密になります。分布範囲の説明は、分散または標準偏差の概念に正確に対応します。

 3. 構造

この構造は、ピクセルの線形依存関係の観点から説明されます。共分散を求めることで、対応する構造の項を取得します。

 4. SSIMの最終計算式

 4. トーチは 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()

おすすめ

転載: blog.csdn.net/qq_46644680/article/details/130940867