본문 바로가기
AI/Deep Learning

PSNR과 SSIM 설명

by 알푼 2024. 2. 6.
728x90
728x90

이미지 관련 분야에 자주 등장하지만, super resolution을 공부하면서 PSNR와 SSIM을 접하게 되었다. 

PSNR(Peak Signal to Noise Ratio)SSIM(Structure Similarity Index Map)은 super resolution에서 SOTA(State of the art)를 평가하기 위해 사용하는데, 쉽게 생각하면 이미지가 얼마나 적게 손실되었는가를 나타낸다. 즉 이미지의 품질을 나타내는 지표라고 볼 수 있다.

 

PSNR

PSNR을 화질의 손실량을 평가하기 위해 사용하며, 아래와 같이 계산할 수 있다.

$PSNR = 10\;log_{10}(\cfrac{MAX_{i}^{2}}{MSE})$

$MSE = \cfrac{\sum_{M,N}[I_{1}(m, n)-I_{2}(m,n)]^{2}}{M\times N}$

 

이렇게 표현할 수 있으며, 추후에 다시 설명하겠지만 사실 $MAX_{i}^{2}$ 가 일반적인 상황에서 거의 고정값이나 다름 없으므로 MSE 작을수록 좋다. 따라서 PSNR은 클 수록 좋은 값이 된다.

 

다음은 이해를 돕기 위한 파이썬 코드이다.

 

아래와 같이 origin 이미지와 compressed 이미지를 가상으로 생성해 보면 다음과 같다.

origin_img = np.array([[137, 167,  83,  95, 159],
                       [114, 103,  89, 221, 124],
                       [ 55, 122, 171,  96, 221],
                       [167, 247, 108,  30, 114],
                       [ 15, 251, 215, 240, 171]])

compressed_img = np.array([[122, 187,  83,  90, 110],
                           [140, 109,  91, 221, 100],
                           [ 55, 156, 211,  33, 201],
                           [165, 217, 158,  50, 114],
                           [ 18, 257, 200, 220, 176]])

 

임의로 생성한 이미지라고 가정하고 이를 출력해보면 아래와 같다. 그리고 여기서 MSE를 구하면 되는데, 각각에 대응되는 픽셀값을 빼주고 이를 제곱한다. (ex. $(① - ①')^{2}$) 그러면 총 25개 픽셀의 차이의 제곱값을 구할 수 있는데, 이 25개 값들의 평균이 MSE가 된다. 또한 PSNR을 계산하기 위해서 $MAX_{i}^{2}$ 값을 알아야 하는데 0~255 scale 이므로 255가 된다. 일반적으로 8비트 이미지의 경우 max값은 255가 된다.

 

mse = np.mean((origin_img - compressed_img) ** 2)
max_pixel_value = 255.

 

PSNR 식을 전개해보면 다음과 같다.

$PSNR = 20\;log_{10}(\cfrac{MAX_{i}}{\sqrt{MSE}})$

                  $= 20\;log_{10}(MAX_{i}) - 10\;log_{10}(MSE)$

 

어떤 것으로 계산할지는 크게 관계는 없다. 결과적으로 아래와 같이 최종적인 PSNR 값을 구할 수 있다.

psnr = 20 * np.log10(max_pixel_value / np.sqrt(mse))
print(psnr)
20.077970442490425

 

 

SSIM

PSNR이 수치적인 차이를 나타낸다면, SSIM은 인간이 느끼는 시각적 품질을 평가한다.

$SSIM(x,y) = [l(x, y)]^{\alpha} \;\cdot\;[c(x,y)]^{\beta}\;\cdot\;[s(x,y)]^\gamma$

 

여기서 $l, c, s$ 는 각각 다음과 같다.

 

$l$ : Luminance (휘도, 빛의 밝기)

$c$ : Contrast (명암, 깊이감)

$s$ : Structural (구조)

 

$l(x,y) = \cfrac{2\mu_{x}\mu_{y}+c_{1}}{\mu_{x}^{2} + \mu_{y}^{2} + c_{1}}$

$c(x,y) = \cfrac{2\sigma_{x}\sigma_{y}+c_{2}}{\sigma_{x}^{2} + \sigma_{y}^{2} + c_{2}}$

$s(x,y) = \cfrac{\sigma_{xy}+c_{3}}{\sigma_{x}\sigma_{y} + c_{3}}$

 

여기서 C는 상수로

$c_{1} = (0.01\times L)^{2}$

$c_{2} = (0.03\times L)^{2}$

$c_{3} = C_{2}/2$

 

일반적으로 이렇게 표현하며 $L$은 픽셀 값의 범위이다. 

 

이 순서대로 쭉 코드를 짜보면 아래와 같은 결과를 얻을 수 있다.

 

c1 = 0.01 ** 2
c2 = 0.03 ** 2
c3 = c2/2

mu1 = np.mean(origin_img)
mu2 = np.mean(compressed_img)

sigma1 = np.var(origin_img)
sigma2 = np.var(compressed_img)

# covariance
sigma12 = np.cov(origin_img.ravel(), compressed_img.ravel())[0, 1]

luminance = (2 * mu1 * mu2 + c1) / (mu1**2 + mu2**2 + c1)
contrast = (2 * sigma12 + c2) / (sigma1 + sigma2 + c2)
structural = (sigma12 + c3) / (np.sqrt(sigma1) * np.sqrt(sigma2) + c3)

ssim = luminance * contrast * structural
print(ssim)
0.9261494958100474

 

728x90
반응형

'AI > Deep Learning' 카테고리의 다른 글

AutoEncoder(AE)  (0) 2023.08.25
Deep Neural Network (DNN)  (0) 2023.05.17
퍼셉트론(perceptron)과 Multilayer Perceptron(MLP)  (0) 2023.05.16

댓글