Skip to main content

SSIM算法

SSIM(结构相似性指数)是一种用于衡量两幅图像相似性的指标。它考虑了图像的亮度、对比度和结构三个方面。SSIM 的取值范围在 -1 到 1 之间,1 表示两幅图像完全相同,-1 表示两幅图像完全不同。

应用场景

  • 图像质量评价:SSIM 用于评估图像压缩、去噪、增强等图像处理操作的效果。通过比较原始图像和处理后的图像之间的 SSIM 值,可以量化图像处理算法的性能。
  • 视频质量评价:在视频编解码、传输和存储中,SSIM 用于评估视频质量。通过计算视频帧之间的 SSIM 值,可以量化视频的整体质量,检测编解码引起的失真等问题。
  • 医学图像分析:在医学领域,SSIM 被用于比较医学图像,如磁共振图像或CT扫描。这有助于评估图像质量,确保在不同扫描条件下获取的图像之间的一致性。
  • 视频监控:在视频监控系统中,SSIM 可以用于检测视频中的异常事件。通过比较当前帧与先前帧之间的 SSIM 值,可以发现图像中的变化,例如移动物体或异常活动。
  • 图像检索: 在图像检索任务中,SSIM 可以用作图像相似性的度量。通过计算两幅图像之间的 SSIM 值,可以排序图像库中的图像,以便更有效地进行图像检索。
  • 图像编辑: 在图像编辑应用中,SSIM 可以用于比较原始图像与编辑后的图像之间的相似性。这有助于评估编辑效果,并支持自动化图像编辑工具的开发。
  • 游戏图像元素转换:在游戏中可以把装备图标元素转换为标签,达到识别的目的

代码

需要安装opencv和scikit-image
pip install scikit-image
来自ChatGPT3.5
from skimage.metrics import structural_similarity as ssim
import cv2

# Load your images
image1 = cv2.imread('image1.jpg')
image2 = cv2.imread('image2.jpg')

# Convert images to grayscale if necessary
gray1 = cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(image2, cv2.COLOR_BGR2GRAY)

# Calculate SSIM
ssim_value = ssim(gray1, gray2)

print(f'SSIM: {ssim_value}')
C#代码
public Scalar CompareSSIM(Mat image1, Mat image2)
{
// 确保图像大小相同
Cv2.Resize(image2, image2, new OpenCvSharp.Size(image1.Size().Width, image1.Size().Height));

double C1 = 6.5025, C2 = 58.5225;

var validImage1 = new Mat();
var validImage2 = new Mat();

// 将图像数据类型转换为 CV_32F,防止溢出
image1.ConvertTo(validImage1, MatType.CV_32F);
image2.ConvertTo(validImage2, MatType.CV_32F);

// 计算图像的平方
Mat image1Squared = validImage1.Mul(validImage1);
Mat image2Squared = validImage2.Mul(validImage2);
Mat image1TimesImage2 = validImage1.Mul(validImage2);

// 使用高斯滤波计算图像的均值
Mat gaussianBlur1 = new Mat(), gaussianBlur2 = new Mat(), gaussianBlur12 = new Mat();
Cv2.GaussianBlur(validImage1, gaussianBlur1, new OpenCvSharp.Size(11, 11), 1.5);
Cv2.GaussianBlur(validImage2, gaussianBlur2, new OpenCvSharp.Size(11, 11), 1.5);
Cv2.GaussianBlur(image1TimesImage2, gaussianBlur12, new OpenCvSharp.Size(11, 11), 1.5);

// 计算图像的均值乘积、各自均值的平方
Mat imageAvgProduct = gaussianBlur1.Mul(gaussianBlur2);
Mat u1Squared = gaussianBlur1.Mul(gaussianBlur1);
Mat u2Squared = gaussianBlur2.Mul(gaussianBlur2);

// 计算图像协方差和方差
Mat imageCovariance = gaussianBlur12 - gaussianBlur1.Mul(gaussianBlur2);
Mat imageVariance1 = u1Squared - gaussianBlur1.Mul(gaussianBlur1);
Mat imageVariance2 = u2Squared - gaussianBlur2.Mul(gaussianBlur2);

// 计算 SSIM 公式的分子和分母
Mat ssimNumerator = ((2 * gaussianBlur1.Mul(gaussianBlur2) + C1).Mul(2 * imageCovariance + C2));
Mat ssimDenominator = ((u1Squared + u2Squared + C1).Mul(imageVariance1 + imageVariance2 + C2));

// 计算 SSIM
Mat ssim = new Mat();
Cv2.Divide(ssimNumerator, ssimDenominator, ssim, 1, MatType.CV_32F);

// 计算 SSIM 的均值
Scalar ssimScalar = Cv2.Mean(ssim);

return ssimScalar;
}