1

根据这篇OCR: Difference between two frames,我现在知道如何使用 OpenCV 查找两个图像之间的像素差异。

我想改进此解决方案并将其与内容丰富的高分辨率图像(来自视频)一起使用。上面的示例不适用于大图像,因为该过程很慢(发现太多差异,“findCountours 方法”用 250k 元素填充选项卡,这需要大量时间来处理)。

我的应用程序使用 RLE 解码器来解码视频的压缩帧。一旦帧被解码,我想将当前帧与前一个帧进行比较,以便将两个帧之间的差异存储在“Mat”选项卡中。

所有这些的目标是能够对不同的像素进行分析并检查是否有任何拉丁字符。这使我能够减少要分析的像素数量并节省宝贵的时间。

如果有人有其他想法而不是这个想法来执行此类操作,请随时提出。

谢谢您的帮助。

编辑 1: 计算机屏幕的两个高分辨率图像示例。目前,这些是我试图分析的完美例子。正如我们所看到的,两个大图像之间只有一个窗口,我想分析任何角色的新“挑战”窗口。

第一张图片

第二张图片

编辑 2: 我正在尝试根据分析的数据调整算法。通常在以下两张图片中,我只得到绿线作为差异,根本没有文字(这是最有趣的)。我试图更好地理解事情是如何工作的。

第一张图片

测试Img1

第二张图片

测试Img2

第三张图片结果图

如您所见,我只有那些绿线,而没有文字(在减少 countours[i].size() 时,我最多只能有一个字母)

4

1 回答 1

1

除了您提到的帖子之外,您还需要:

  • 当您对掩码进行二值化时,请使用高于 0 的阈值来消除小的差异。
  • 消除一些噪音。您可以找到所有连接的组件,并删除较小的组件。
  • 找出较大连通分量的面积。您可以使用convexHullfillConvexPoly来获取屏幕上不同对象的蒙版
  • 使用给定的掩码将第二个图像复制到新图像。

结果将如下所示:

在此处输入图像描述

代码:

#include <opencv2/opencv.hpp>
#include <vector>
using namespace std;
using namespace cv;

int main()
{
    Mat3b img1 = imread("path_to_image_1");
    Mat3b img2 = imread("path_to_image_2");

    Mat3b diff;
    absdiff(img1, img2, diff);

    // Split each channel
    vector<Mat1b> masks;
    split(diff, masks);

    // Create a black mask
    Mat1b mask(diff.rows, diff.cols, uchar(0));

    // OR with each channel of the N channels mask
    for (int i = 0; i < masks.size(); ++i)
    {
        mask |= masks[i];
    }

    // Binarize mask
    mask = mask > 100;

    // Results images
    vector<Mat3b> difference_images;

    // Remove small blobs
    //Mat kernel = getStructuringElement(MORPH_RECT, Size(5,5));
    //morphologyEx(mask, mask, MORPH_OPEN, kernel);

    // Find connected components
    vector<vector<Point>> contours;
    findContours(mask.clone(), contours, CV_RETR_EXTERNAL, CHAIN_APPROX_NONE);

    for (int i = 0; i < contours.size(); ++i)
    {
        if (contours[i].size() > 1000)
        {
            Mat1b mm(mask.rows, mask.cols, uchar(0));

            vector<Point> hull;
            convexHull(contours[i], hull);


            fillConvexPoly(mm, hull, Scalar(255));

            Mat3b difference_img(img2.rows, img2.cols, Vec3b(0,0,0));
            img2.copyTo(difference_img, mm);

            difference_images.push_back(difference_img.clone());
        }
    }

    return 0;
}
于 2015-12-15T13:03:20.503 回答