OCR:两帧之间的差异

5
我正在尝试找到一种易于实现的解决方案来使用OpenCV的OCR算法。我对图像处理非常新手!我正在使用RLE算法解码特定编解码器的视频。
我的目标是,对于每个解码帧,我想将其与前一个帧进行比较,并存储在两个帧之间发生变化的像素。大多数现有解决方案会给出两个帧之间的差异,但我只想保留已更改的新像素并将其存储在表中,然后能够分析每组已更改的像素,而不是每次分析整个图像。
我计划使用“斑点检测”算法,但在实现之前卡住了。
今天,我正在尝试这样做:
char *prevFrame;
char *curFrame;
QVector DiffPixel<LONG>;

//for each frame
DiffPixel.push_back(curFrame-prevFrame);

enter image description here

我真的想要一个“仅更改像素结果”的解决方案。是否有人可以给我一些提示或纠正我是否走错了路?

编辑:

新问题,如果有多个更改像素区域,那么每个更改像素块是否可能有一个表格,还是只有一个唯一的表格?以下面的例子为例:

Multiple Areas Pixels

最好的结果是有两个mat矩阵。第一个矩阵带有第一个橙色正方形,第二个矩阵带有第二个橙色正方形。这样,如果我们只在一个矩阵中存储结果,分辨率几乎与整个画面相同,就避免了“扫描”几乎整个画面。

这里的主要目标是将需要分析以查找文本的区域(即分辨率)最小化。

1个回答

9

加载图像后:

img1

输入图像描述

img2

输入图像描述

您可以应用XOR运算来获取差异。结果具有与输入图像相同数量的通道:

XOR

输入图像描述

然后,您可以创建一个二进制掩码,将所有通道进行或操作:

mask

输入图像描述

然后,您可以将对应于掩码中非零元素的img2的值复制到白色图像中:

diff

输入图像描述


更新

如果您有多个像素发生变化的区域,例如:

输入图像描述

您会得到一个差异掩码(在将所有非零像素二值化后设置为255):

输入图像描述

然后,您可以提取连接的组件,并在新的黑色初始化的掩码上绘制每个连接组件:

输入图像描述

然后,与之前一样,您可以将对应于每个掩码中非零元素的img2的值复制到白色图像中。

输入图像描述

完整的参考代码。请注意,这是答案的更新版本的代码。您可以在修订历史记录中找到原始代码。

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

int main()
{
    // Load the images
    Mat img1 = imread("path_to_img1");
    Mat img2 = imread("path_to_img2");

    imshow("Img1", img1);
    imshow("Img2", img2);

    // Apply XOR operation, results in a N = img1.channels() image
    Mat maskNch = (img1 ^ img2);

    imshow("XOR", maskNch);

    // Create a binary mask

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

    // Create a black mask
    Mat1b mask(maskNch.rows, maskNch.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 > 0;

    imshow("Mask", mask);

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

    for (int i = 0; i < contours.size(); ++i)
    {
        // Create a black mask
        Mat1b mask_i(mask.rows, mask.cols, uchar(0));
        // Draw the i-th connected component
        drawContours(mask_i, contours, i, Scalar(255), CV_FILLED);

        // Create a black image
        Mat diff_i(img2.rows, img2.cols, img2.type());
        diff_i.setTo(255);

        // Copy into diff only different pixels
        img2.copyTo(diff_i, mask_i);

        imshow("Mask " + to_string(i), mask_i);
        imshow("Diff " + to_string(i), diff_i);
    }

    waitKey();
    return 0;
}

这很棒。不过我还有一个问题。如果有多个区域的像素发生了变化怎么办?请看我在原帖中的编辑。感谢您提供如此完整的答案。 - Robert Jones
@DylanAlvaro更新了答案。请让我知道您是否满意。 - Miki
这个想法非常好,大致上就是我想做的。唯一的区别是,如果我在高分辨率图像上应用这个方案,且内容非常丰富,那么描边选项卡会非常巨大。我必须找到一种限制的方法。谢谢你的帮助。 - Robert Jones
@DylanAlvaro 好的,这回答了你的问题,而不是关于高分辨率图像的问题。你可以发布另一个问题,发布你正在使用的实际图像以获得具体答案。如果它回答了你最初的问题,请记得接受/点赞。 - Miki

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接