1、SSIM算法计算相似度

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

/// <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;  // 变化率,即差异
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
2、颜色直方图计算相似度

C#+OpenCV基础(十七)_计算图片相似度_颜色直方图_02

  

/// <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;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.

 

作者:꧁执笔小白꧂