OCR:两帧之间的差异
OCR: Difference between two frames
我正在尝试找到一个简单的解决方案来实现来自 OPenCV 的 OCR 算法。我对图像处理很陌生!
我正在播放使用 RLE 算法.
的特定编解码器解码的视频
我想做的是,对于每个解码帧,我想将它与前一帧进行比较,并存储两帧之间发生变化的像素。
现有的大多数解决方案都给出了两个帧之间的差异,但我只想保留已更改的新像素并将其存储在 table 中,然后能够分析每组像素已经改变而不是每次都分析整个图像。
我计划使用“blobs 检测”算法,但在实施之前我遇到了困难。
今天,我正在尝试这个:
char *prevFrame;
char *curFrame;
QVector DiffPixel<LONG>;
//for each frame
DiffPixel.push_back(curFrame-prevFrame);
我真的想要 "Only changed pixel result" 解决方案。如果我走错了路,谁能给我一些提示或纠正我?
编辑:
新问题,如果有多个像素变化区域怎么办?是否有可能每个更改像素块有一个 table 还是只有一个唯一的 table ?举个例子:
最好的结果是有 2 个 mat 矩阵。第一个矩阵带有第一个橙色方块,第二个矩阵带有第二个橙色方块。这样,如果我们仅将结果存储在一个矩阵中且分辨率几乎与全帧相同,则可以避免 "scan" 几乎整个帧。
这里的主要目标是最小化区域(也称为分辨率)以分析查找文本。
加载图片后:
img1
img2
您可以应用异或运算来获得差异。结果与输入图像的通道数相同:
异或
然后您可以创建一个二进制掩码OR-ing所有通道:
面具
您可以将对应于蒙版中 non-zero 元素的 img2
的值复制到白色图像:
差异
更新
如果您有多个像素发生变化的区域,例如:
你会发现一个差异掩码(二值化后所有 non-zero 像素都设置为 255)如:
然后您可以提取连通分量并在新的 black-initialized 掩码上绘制每个连通分量:
然后,和以前一样,您可以将每个遮罩中 non-zero 个元素对应的 img2
的值复制到白色图像。
完整代码供参考。请注意,这是 updated 版本答案的代码。您可以在修订历史中找到原始代码。
#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;
}
我正在尝试找到一个简单的解决方案来实现来自 OPenCV 的 OCR 算法。我对图像处理很陌生! 我正在播放使用 RLE 算法.
的特定编解码器解码的视频我想做的是,对于每个解码帧,我想将它与前一帧进行比较,并存储两帧之间发生变化的像素。
现有的大多数解决方案都给出了两个帧之间的差异,但我只想保留已更改的新像素并将其存储在 table 中,然后能够分析每组像素已经改变而不是每次都分析整个图像。
我计划使用“blobs 检测”算法,但在实施之前我遇到了困难。
今天,我正在尝试这个:
char *prevFrame;
char *curFrame;
QVector DiffPixel<LONG>;
//for each frame
DiffPixel.push_back(curFrame-prevFrame);
我真的想要 "Only changed pixel result" 解决方案。如果我走错了路,谁能给我一些提示或纠正我?
编辑:
新问题,如果有多个像素变化区域怎么办?是否有可能每个更改像素块有一个 table 还是只有一个唯一的 table ?举个例子:
最好的结果是有 2 个 mat 矩阵。第一个矩阵带有第一个橙色方块,第二个矩阵带有第二个橙色方块。这样,如果我们仅将结果存储在一个矩阵中且分辨率几乎与全帧相同,则可以避免 "scan" 几乎整个帧。
这里的主要目标是最小化区域(也称为分辨率)以分析查找文本。
加载图片后:
img1
img2
您可以应用异或运算来获得差异。结果与输入图像的通道数相同:
异或
然后您可以创建一个二进制掩码OR-ing所有通道:
面具
您可以将对应于蒙版中 non-zero 元素的 img2
的值复制到白色图像:
差异
更新
如果您有多个像素发生变化的区域,例如:
你会发现一个差异掩码(二值化后所有 non-zero 像素都设置为 255)如:
然后您可以提取连通分量并在新的 black-initialized 掩码上绘制每个连通分量:
然后,和以前一样,您可以将每个遮罩中 non-zero 个元素对应的 img2
的值复制到白色图像。
完整代码供参考。请注意,这是 updated 版本答案的代码。您可以在修订历史中找到原始代码。
#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;
}