C++ OCR&;OpenCV:高分辨率图像上两帧之间的差异

C++ OCR&;OpenCV:高分辨率图像上两帧之间的差异,c++,opencv,ocr,run-length-encoding,C++,Opencv,Ocr,Run Length Encoding,根据这篇文章,我现在知道了如何使用OpenCV查找两幅图像之间的像素差异 我希望改进此解决方案,并将其用于内容丰富的高分辨率图像(来自视频)。上面的示例不适用于大图像,因为处理速度太慢(发现太多差异,“findCountours方法”使用250k元素填充选项卡,这需要花费大量时间来处理) 我的应用程序使用RLE解码器对视频的压缩帧进行解码。一旦该帧被解码,我想将当前帧与前一帧进行比较,以便将两帧之间的差异存储在“Mat”选项卡中 所有这些的目标是能够对不同的像素进行分析,并检查是否存在任何拉丁字

根据这篇文章,我现在知道了如何使用OpenCV查找两幅图像之间的像素差异

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

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

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

如果有人有其他想法而不是这个来执行这样的操作,请随意提出

谢谢你的帮助

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

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

第一张图片

第二张图片

第三张图片


正如你所见,我只有那些绿线,而没有文本(在减少计数[I].size()时,我最多只能有一个字母)

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

  • 对遮罩进行二值化时,请使用高于0的阈值来消除细微差异
  • 消除一些噪音。您可以找到所有连接的组件,并删除较小的组件
  • 找出较大连接组件的面积。您可以使用
    convxhull
    fillconvxpoly
    获取屏幕上不同对象的掩码
  • 使用给定的掩码将第二个图像复制到新图像
结果如下所示:

代码:

#包括
#包括
使用名称空间std;
使用名称空间cv;
int main()
{
Mat3b img1=imread(“路径到图像1”);
Mat3b img2=imread(“路径到图像2”);
Mat3b-diff;
absdiff(img1、img2、diff);
//分割每个通道
矢量掩模;
分割(差异、遮罩);
//创建一个黑色的面具
Mat1b掩模(不同行、不同列、uchar(0));
//或使用N个通道掩码中的每个通道
对于(int i=0;i100;
//结果图像
矢量差分图像;
//去除小斑点
//Mat kernel=getStructuringElement(变形,大小(5,5));
//形态学(遮罩,遮罩,形态开放,内核);
//查找连接的组件
矢量等值线;
findContours(mask.clone()、轮廓、CV\u RETR\u外部、链\u近似\u无);
对于(int i=0;i1000)
{
Mat1b毫米(掩模行,掩模列,uchar(0));
向量壳;
凸形外壳(轮廓[i],外壳);
填充凸多边形(毫米,外壳,标量(255));
Mat3b差分_img(img2.rows,img2.cols,Vec3b(0,0,0));
img2.copyTo(差值_img,mm);
差分图像。向后推(差分img.clone());
}
}
返回0;
}

我不确定这是否有助于解决您的问题,根据我的经验,openCV无法以全分辨率(至少在windows中)处理视频。您可以发布两张图像吗?还是高分辨率图像的公共链接?@Miki我刚刚编辑了我的post@Engine我不知道你所说的“不能以全分辨率处理视频”是什么意思。我刚刚接触OpenCV,所以可能会错过一些东西。我能够在视频的整个帧上执行操作,但这对我来说太长了,因为它发现了一帧和另一帧之间的太多差异。这里的目标是找到一种方法,只在屏幕上出现的新窗口上执行操作,而不是在整个框架上执行操作。这非常有效,速度非常快,完全符合我的要求。谢谢你的帮助,Miki!不过我还有一个问题。Wy您是否对轮廓[i].size()进行了过滤,以仅保留具有1000个或更多元素的轮廓?这是不是一种消除帧间所有“小”差异,只保留大匹配的方法?1000是一个平均数吗?@DylanAlvaro用于去除小斑点,即周长(某种程度上)小于1000的斑点。您可以使用任何其他足够大的值,或者根据图像中的一些统计信息计算它。此“掩码=掩码>100;”将消除两个图像之间的微小差异(<100)。您的其他图像与最初的图像非常不同,值得再问一个问题。
#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;
}