如何比较单词不同的两个图像



我反复拍摄网页的屏幕截图,而我无法获得页面的分数代码,并且想知道页面是否发生了变化,通常,只有页面中的某些单词会更改,有时整个页面可能会更改。

我使用 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.9999999997976750.9999999648350145

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

取两个图像的像素差并做一个求和(本质上是一个平均绝对误差(。
如果您得到的值非常接近 0,则没有任何变化,否则会有变化。

我用@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。 谢谢

最新更新