C#+OpenCV基础(十七)_计算图片相似度

1、SSIM算法计算相似度

/// <summary>
/// 两张图片的相似度(SSIM算法)
/// </summary>
/// <param name="mat1">图片1</param>
/// <param name="mat2">图片2</param>
/// <returns></returns>
public static Scalar CompareDetection_SSIM(Mat mat1, Mat mat2)
{
    // 将两个图片处理成同样大小,否则会有错误: The operation is neither 'array op array' (where arrays have the same size and the same number of channels), nor 'array op scalar', nor 'scalar op array'
    var image2 = new Mat();
    Cv2.Resize(mat2, image2, new OpenCvSharp.Size(mat1.Width, mat1.Height));

    double C1 = 6.5025, C2 = 58.5225;
    var validImage1 = new Mat();
    var validImage2 = new Mat();
    mat1.ConvertTo(validImage1, MatType.CV_32F); //数据类型转换为 float,防止后续计算出现错误
    image2.ConvertTo(validImage2, MatType.CV_32F);

    Mat image1_1 = validImage1.Mul(validImage1); //图像乘积
    Mat image2_2 = validImage2.Mul(validImage2);
    Mat image1_2 = validImage1.Mul(validImage2);

    Mat gausBlur1 = new Mat(), gausBlur2 = new Mat(), gausBlur12 = new Mat();
    Cv2.GaussianBlur(validImage1, gausBlur1, new OpenCvSharp.Size(11, 11), 1.5); //高斯卷积核计算图像均值
    Cv2.GaussianBlur(validImage2, gausBlur2, new OpenCvSharp.Size(11, 11), 1.5);
    Cv2.GaussianBlur(image1_2, gausBlur12, new OpenCvSharp.Size(11, 11), 1.5);

    //Mat imageAvgProduct = gausBlur1.Mul(gausBlur2);  // 均值乘积
    Mat u1Squre = gausBlur1.Mul(gausBlur1);          // 计算图1的均值的平方
    Mat u2Squre = gausBlur2.Mul(gausBlur2);          // 计算图2的均值的平方

    Mat squreAvg1 = new Mat(), squreAvg2 = new Mat();
    Cv2.GaussianBlur(image1_1, squreAvg1, new OpenCvSharp.Size(11, 11), 1.5);  // 图像1的平方的均值
    Cv2.GaussianBlur(image2_2, squreAvg2, new OpenCvSharp.Size(11, 11), 1.5);  // 图像2的平方的均值

    Mat imageConvariance = gausBlur12 - gausBlur1.Mul(gausBlur2);  // 计算协方差
    Mat imageVariance1 = squreAvg1 - gausBlur1.Mul(gausBlur1);     // 计算图1的方差
    Mat imageVariance2 = squreAvg2 - gausBlur2.Mul(gausBlur2);     // 计算图2的方差

    var member = ((2 * gausBlur1.Mul(gausBlur2) + C1).Mul(2 * imageConvariance + C2));
    var denominator = ((u1Squre + u2Squre + C1).Mul(imageVariance1 + imageVariance2 + C2));

    Mat ssim = new Mat();
    Cv2.Divide(member, denominator, ssim);

    var sclar = Cv2.Mean(ssim);

    return sclar;  // 变化率,即差异
}

2、颜色直方图计算相似度

  

/// <summary>
/// 两张图片的相似度(颜色直方图)
/// 图片相似度识别(精度不高,速度较快,可用于以图搜图)
/// </summary>
/// <param name="imgFile1"></param>
/// <param name="imgFile2"></param>
/// <returns></returns>
public static double Compare_Hist(Mat matA, Mat matB)
{
    // 拆分通道
    Cv2.Split(matA, out Mat[] matA_S);
    Cv2.Split(matB, out Mat[] matB_S);

    //直方图的像素范围   
    Rangef[] histRange = { new Rangef(0, 256) };

    //直方图数组大小
    int[] histSize = { 256 };

    //直方图输出数组
    Mat hist_A = new Mat();
    Mat hist_B = new Mat();

    bool uniform = true, accumulate = false;
    Cv2.CalcHist(matA_S, new int[] { 0, 1, 2 }, null, hist_A, 1, histSize, histRange, uniform, accumulate);
    Cv2.CalcHist(matB_S, new int[] { 0, 1, 2 }, null, hist_B, 1, histSize, histRange, uniform, accumulate);

    //归一化,排除图像分辨率不一致的影响
    Cv2.Normalize(hist_A, hist_A, 0, 1, NormTypes.MinMax, -1, null);
    Cv2.Normalize(hist_B, hist_B, 0, 1, NormTypes.MinMax, -1, null);

    //相关性比较
    var res = Cv2.CompareHist(hist_A, hist_B, HistCompMethods.Correl);
    return res;
}

 

posted @   ꧁执笔小白꧂  阅读(299)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 一文读懂知识蒸馏
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
历史上的今天:
2023-07-11 Element-动态控制el-table的行的显示与隐藏
2019-07-11 javascript修改css样式表
点击右上角即可分享
微信分享提示