OCR:两帧之间的差异

Posted

技术标签:

【中文标题】OCR:两帧之间的差异【英文标题】:OCR: Difference between two frames 【发布时间】:2015-12-01 16:14:08 【问题描述】:

我正在尝试找到一个简单的解决方案来实现 OPenCV 中的 OCR 算法。我对图像处理很陌生! 我正在播放使用 RLE 算法使用特定编解码器解码的视频。

我想做的是,对于每个解码的帧,我想将其与前一帧进行比较,并存储两帧之间发生变化的像素。

现有的大多数解决方案都会在两个帧之间产生差异,但我只想保留已更改的新像素并将其存储在表格中,然后能够分析每组已更改的像素,而不是分析每次都是整个图像。

我计划使用“blob detection”算法,但在实现之前我被卡住了。

今天,我正在尝试这个:

char *prevFrame;
char *curFrame;
QVector DiffPixel<LONG>;

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

我真的很想拥有“仅更改像素结果”的解决方案。如果我走错路,谁能给我一些提示或纠正我?

编辑:

新问题,如果有多个像素变化区域?是否有可能每块更改的像素有一个表,还是只有一个唯一的表?举个例子:

最好的结果是拥有 2 个矩阵。第一个矩阵带有第一个橙色正方形,第二个矩阵带有第二个橙色正方形。这样,如果我们仅将结果存储在一个矩阵中,其分辨率几乎与全帧相同,它就不必“扫描”几乎整个帧。

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

【问题讨论】:

【参考方案1】:

加载图片后:

img1

img2

您可以应用异或运算来获得差异。结果与输入图像的通道数相同:

异或

然后您可以创建一个二进制掩码 OR-ing 所有通道:

面具

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

差异


更新

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

您会发现一个差异掩码(二值化后所有非零像素都设置为 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;

【讨论】:

这很棒。不过我还有一个问题。如果有多个像素发生变化的区域怎么办?看看我在原始帖子中的编辑。感谢您提供完整的答案 @DylanAlvaro 更新了答案。请让我知道您是否可以。 这个想法非常好,这大约是我想做的。唯一的区别是,如果我将此方案应用于内容非常丰富的高分辨率图像,则会有很多差异,并且轮廓选项卡会很大。我必须找到一种方法来限制这一点。非常感谢您的帮助 @DylanAlvaro 很好,这回答了您的问题,这与高分辨率图像无关。您可以发布另一个问题,发布您使用的实际图像以获得特定答案。如果它回答了您的原始问题,请记住接受/投票。

以上是关于OCR:两帧之间的差异的主要内容,如果未能解决你的问题,请参考以下文章

如何计算强光复合混合模式的逆?

为 OCR 准备复杂图像

位图字体 OCR 库

RabbitMQ与Kafka之间的差异

计算两个时间戳之间的差异并获得 unix 时间戳的差异

虽然找到2张图片之间的差异,但OpenCV差异大于预期