本日は画像品質を評価する評価指標の一つであるMSE(Mean Squared Error: 最小二乗誤差)を紹介し、画像のMSEを計算するプログラムを紹介したいと思います。
MSE(Mean Squared Error: 最小二乗誤差)
最小二乗誤差は、正解値と評価したい値の差の二乗から計算される評価指標です。もし、評価したい対象と正解が完全に一致する場合、MSEは0となります。
MSEは以下の式で計算されます。

画像処理であればNは画像のピクセル数が対応します。以下に4画素の画像でMSEを計算する場合の計算例を示します。

MSEは単なる画素値の差の二乗をベースとした指標のため、人間の視覚的な感覚と、劣化具合が必ずしも一致しないという問題はありますが、非常に簡単に計算することが可能です。
以下で、MSEを計算するプログラムを見ていきます。
画像のMSE測定プログラム(Python+OpenCV)
ソースコード全体
動作環境:OpenCV 4.5.5
今回は確認の意味も込めて、NumpyとOpenCVそれぞれでMSEを計算するプログラムを書きました。今回はグレースケール画像で実験しています。カラー画像はこちらの記事を参照ください。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import numpy as np
import cv2
print(cv2.__version__)
def AddGaussianNoise(image, mean, sigma):
noise = np.random.normal(mean, sigma, np.shape(image))
noisy_image = image + noise
noisy_image[noisy_image > 255] = 255
noisy_image[noisy_image < 0] = 0
noisy_image = noisy_image.astype(np.uint8) # Float -> Uint
return noisy_image
# Loading image data (GreyScale)
gt_image = cv2.imread('data/lenna.png', cv2.IMREAD_GRAYSCALE)
# Adding Gaussian Noise
noisy_image = AddGaussianNoise(gt_image, 0, 10)
# Saving image
cv2.imwrite('noisy_image.jpg',noisy_image)
cv2.imwrite('gt_image.jpg',gt_image)
# Calculate MSE with numpy (GreyScale)
error = np.sum((noisy_image.astype(float) - gt_image.astype(float)) ** 2)
MSE_numpy = error / (float(noisy_image.shape[0] * noisy_image.shape[1]))
print(MSE_numpy);
# Calculate MSE with OpenCV (GreyScale)
MSE_opencv, _ = cv2.quality.QualityMSE_compute(noisy_image, gt_image)
print(MSE_opencv[0])
入力データとしては、以下の画像を用いました。
gt_imageがGroundTruthの画像(正解画像)であり、noisy_imageがノイズが付与された画像となります。画像にはガウシアンノイズを付与しています。

ガウシアンノイズに関してはこちらの記事を参照してください。
実行結果
1) ノイズレベル σ=30
■ 正解画像

■ ノイズ画像

■ MSE測定結果
MSE_numpy : 877.3797314049586
MSE_opencv : 877.3797314049588
NumpyとOpenCVで測定結果が一致することがわかりました。
また、ガウシアンノイズレベルσ=30のため、多くの画素が30以内の誤差となります。MSEは大体30×30=900よりやや小さい値となり、概ね感覚的にも正しそうです。
2) ノイズレベル σ=100
■ 正解画像

■ ノイズ画像

■ MSE測定結果
MSE_numpy : 6273.029256198347
MSE_opencv : 6273.029256198348
ノイズを大きくするとMSEの値も大きくなることがわかります。
まとめ
今回はMSEを用いて画像を評価する方法を紹介しました。今後は他の評価方法についても紹介したいと思います。