OpenCV实现的SSIM

本文介绍了如何利用OpenCV库实现结构相似性指数(SSIM)这一图像质量评估方法。通过详细步骤,展示了在OpenCV中计算SSIM的过程。
摘要由CSDN通过智能技术生成

图像质量评价指标SSIM的OpenCV实现

来自于 :path-to-opencv\sources\doc\tutorials\videoio\video-input-psnr-ssim


Scalar getMSSIM( const Mat& i1, const Mat& i2)
{
 const double C1 = 6.5025, C2 = 58.5225;
 /***************************** INITS **********************************/
 int d     = CV_32F;


 Mat I1, I2;
 i1.convertTo(I1, d);           // cannot calculate on one byte large values
 i2.convertTo(I2, d);


 Mat I2_2   = I2.mul(I2);        // I2^2
 Mat I1_2   = I1.mul(I1);        // I1^2
 Mat I1_I2  = I1.mul(I2);        // I1 * I2


 /***********************PRELIMINARY COMPUTING ******************************/


 Mat mu1, mu2;   //
 GaussianBlur(I1, mu1, Size(11, 11), 1.5);
 GaussianBlur(I2, mu2, Size(11, 11), 1.5);


 Mat mu1_2   =   mu1.mul(mu1);
 Mat mu2_2   =   mu2.mul(mu2);
 Mat mu1_mu2 =   mu1.mul(mu2);


 Mat sigma1_2, sigma2_2, sigma12;


 GaussianBlur(I1_2, sigma1_2, Siz
以下是使用OpenCV库和C语言实现SSIM的示例代码: ``` #include <stdio.h> #include <stdlib.h> #include <math.h> #include <opencv/cv.h> #include <opencv/highgui.h> double calculate_ssim(IplImage* original, IplImage* processed) { int i, j, k; int width, height, channels; double C1, C2, ssim; double mu_original, mu_processed, sigma_original, sigma_processed, sigma_original_processed; double* data_original = NULL; double* data_processed = NULL; double* temp_original = NULL; double* temp_processed = NULL; double* temp_original_processed = NULL; double* temp_original_squared = NULL; double* temp_processed_squared = NULL; // 计算基本参数 width = original->width; height = original->height; channels = original->nChannels; C1 = (0.01 * 255) * (0.01 * 255); C2 = (0.03 * 255) * (0.03 * 255); // 分配内存 data_original = (double*)malloc(width * height * channels * sizeof(double)); data_processed = (double*)malloc(width * height * channels * sizeof(double)); temp_original = (double*)malloc(width * height * channels * sizeof(double)); temp_processed = (double*)malloc(width * height * channels * sizeof(double)); temp_original_processed = (double*)malloc(width * height * channels * sizeof(double)); temp_original_squared = (double*)malloc(width * height * channels * sizeof(double)); temp_processed_squared = (double*)malloc(width * height * channels * sizeof(double)); // 将图像数据复制到double类型数组中 for (i = 0; i < height; i++) { for (j = 0; j < width; j++) { for (k = 0; k < channels; k++) { data_original[i * width * channels + j * channels + k] = (double)(original->imageData[i * original->widthStep + j * channels + k]); data_processed[i * width * channels + j * channels + k] = (double)(processed->imageData[i * processed->widthStep + j * channels + k]); } } } // 计算均值 cvSetData(original, temp_original, channels); cvSetData(processed, temp_processed, channels); cvSetData(original_processed, temp_original_processed, channels); cvSetData(original_squared, temp_original_squared, channels); cvSetData(processed_squared, temp_processed_squared, channels); cvAvgSdv(original, &mu_original, &sigma_original, NULL); cvAvgSdv(processed, &mu_processed, &sigma_processed, NULL); // 计算方差和协方差 for (i = 0; i < height; i++) { for (j = 0; j < width; j++) { for (k = 0; k < channels; k++) { temp_original[i * width * channels + j * channels + k] = data_original[i * width * channels + j * channels + k] - mu_original; temp_processed[i * width * channels + j * channels + k] = data_processed[i * width * channels + j * channels + k] - mu_processed; temp_original_squared[i * width * channels + j * channels + k] = temp_original[i * width * channels + j * channels + k] * temp_original[i * width * channels + j * channels + k]; temp_processed_squared[i * width * channels + j * channels + k] = temp_processed[i * width * channels + j * channels + k] * temp_processed[i * width * channels + j * channels + k]; temp_original_processed[i * width * channels + j * channels + k] = temp_original[i * width * channels + j * channels + k] * temp_processed[i * width * channels + j * channels + k]; } } } cvAvgSdv(original_squared, &sigma_original, NULL, NULL); cvAvgSdv(processed_squared, &sigma_processed, NULL, NULL); cvAvgSdv(original_processed, &sigma_original_processed, NULL, NULL); // 计算SSIM ssim = ((2 * mu_original * mu_processed + C1) * (2 * sigma_original_processed + C2)) / ((mu_original * mu_original + mu_processed * mu_processed + C1) * (sigma_original + sigma_processed + C2)); // 释放内存 free(data_original); free(data_processed); free(temp_original); free(temp_processed); free(temp_original_processed); free(temp_original_squared); free(temp_processed_squared); return ssim; } int main() { IplImage* original = NULL; IplImage* processed = NULL; double ssim = 0.0; // 读取图像 original = cvLoadImage("original.jpg", CV_LOAD_IMAGE_COLOR); processed = cvLoadImage("processed.jpg", CV_LOAD_IMAGE_COLOR); // 计算SSIM ssim = calculate_ssim(original, processed); // 打印SSIM值 printf("SSIM: %f\n", ssim); // 释放内存 cvReleaseImage(&original); cvReleaseImage(&processed); return 0; } ``` 在此示例中,我们使用OpenCV库和C语言来计算两个图像之间的结构相似性指数(SSIM)。我们首先将图像数据复制到double类型数组中,然后计算均值、方差和协方差。最后,我们将这些值用于计算SSIM指数。您可以通过更改原始图像和处理图像的文件名来测试此代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值