首页 > 解决方案 > 如何比较两个单词不同的图像?

问题描述

我反复截图一个网页,却无法得到该页面的评分码,想知道页面变化的天气,通常只有页面中的一些单词会发生变化,有时整个页面可能会发生变化改变了。

我用opencvsharp、https://github.com/shimat/opencvsharp、直方图对比了截图,结果显示相似度很高,即使有3个词的差异。

直方图代码:

double compareFacesByHist(Mat img, Mat orgImg)
    {
        Mat tmpImg = new Mat();
        if (img.Size().Equals(orgImg.Size()) == false)
        {
            Cv2.Resize(img, tmpImg, new OpenCvSharp.Size(orgImg.Cols, orgImg.Rows));
        }
        else
        {
            tmpImg = img;
        }


        tmpImg = tmpImg.CvtColor(ColorConversionCodes.BGR2HSV);
        orgImg = orgImg.CvtColor(ColorConversionCodes.BGR2HSV);


        int hBins = 256, sBins = 256;
        int[] histSize = { hBins, sBins };

        Rangef hRanges = new Rangef(0, 180);

        Rangef sRanges = new Rangef(0, 255);

        Rangef[] ranges = { hRanges, sRanges };
        int[] channels = { 0, 1 };
        Mat hist1 = new Mat(), hist2 = new Mat();
        Cv2.CalcHist(new Mat[] { tmpImg }, channels, new Mat(), hist1, 2, histSize, ranges, true, false);
        Cv2.Normalize(hist1, hist1, 0, 1, NormTypes.MinMax, -1, new Mat());
        Cv2.CalcHist(new Mat[] { orgImg }, channels, new Mat(), hist2, 2, histSize, ranges, true, false);
        Cv2.Normalize(hist2, hist2, 0, 1, NormTypes.MinMax, -1, new Mat());

        double similarityValue = Cv2.CompareHist(hist1, hist2, HistCompMethods.Correl);// CV_COMP_CORREL);
        return similarityValue;
    }

一些结果:0.999999999797675 0.999999648350145

我猜直方图只是使用颜色信息来比较两个图像,很难反映文字的变化。我想知道一些更好的方法来比较这种图像。谢谢你。

标签: opencv

解决方案


我使用@nathancy的方式ssim来比较图像,结果比直方图好得多。通过屏幕截图记事本来获取图像进行比较,记事本包含一个编辑文档,其中包括一些句子。

1,完全相同的两个屏幕截图:0.999999295236082

2、在文档中添加几个字:0.996387690483554

3、删除刚才加的字:0.999760811255743

我还在用opencvsharp,ssim方法是从opencv的c++版本翻译过来的。

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

        Mat I1 = new Mat(), I2 = new Mat();
        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 = new Mat(), mu2 = new Mat();   //
        Cv2.GaussianBlur(I1, mu1, new OpenCvSharp.Size(11, 11), 1.5);
        Cv2.GaussianBlur(I2, mu2, new OpenCvSharp.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 = new Mat(), sigma2_2 = new Mat(), sigma12 = new Mat();

        Cv2.GaussianBlur(I1_2, sigma1_2, new OpenCvSharp.Size(11, 11), 1.5);
        sigma1_2 -= mu1_2;

        Cv2.GaussianBlur(I2_2, sigma2_2, new OpenCvSharp.Size(11, 11), 1.5);
        sigma2_2 -= mu2_2;

        Cv2.GaussianBlur(I1_I2, sigma12, new OpenCvSharp.Size(11, 11), 1.5);
        sigma12 -= mu1_mu2;

        ///////////////////////////////// FORMULA ////////////////////////////////
        Mat t1, t2, t3;

        t1 = 2 * mu1_mu2 + C1;
        t2 = 2 * sigma12 + C2;
        t3 = t1.Mul(t2);              // t3 = ((2*mu1_mu2 + C1).*(2*sigma12 + C2))

        t1 = mu1_2 + mu2_2 + C1;
        t2 = sigma1_2 + sigma2_2 + C2;
        t1 = t1.Mul(t2);               // t1 =((mu1_2 + mu2_2 + C1).*(sigma1_2 + sigma2_2 + C2))

        Mat ssim_map = new Mat();
        Cv2.Divide(t3, t1, ssim_map);      // ssim_map =  t3./t1;


        Scalar mssim = Cv2.Mean(ssim_map);// mssim = average of ssim map


        return mssim;
    }

但是,我想获得不同的图像,以便我可以看看它。我可以检查更多情况来验证 ssim。谢谢


推荐阅读