C++ OCR&;OpenCV:高分辨率图像上两帧之间的差异
根据这篇文章,我现在知道了如何使用OpenCV查找两幅图像之间的像素差异 我希望改进此解决方案,并将其用于内容丰富的高分辨率图像(来自视频)。上面的示例不适用于大图像,因为处理速度太慢(发现太多差异,“findCountours方法”使用250k元素填充选项卡,这需要花费大量时间来处理) 我的应用程序使用RLE解码器对视频的压缩帧进行解码。一旦该帧被解码,我想将当前帧与前一帧进行比较,以便将两帧之间的差异存储在“Mat”选项卡中 所有这些的目标是能够对不同的像素进行分析,并检查是否存在任何拉丁字符。这使我能够减少要分析的像素数量并节省宝贵的时间 如果有人有其他想法而不是这个来执行这样的操作,请随意提出 谢谢你的帮助 编辑1: 计算机屏幕的两个高分辨率图像示例。这些是目前我试图分析的完美例子。正如我们所看到的,这两幅大图之间只有一个不同的窗口,我想为任何角色分析一个新的“挑战”窗口 编辑2: 我正试图根据分析的数据调整算法。通常在下面的两张图片上,我只得到绿线作为差异,没有任何文本(这是最有趣的)。我正试图更好地理解这是怎么回事 第一张图片: 第二张图片: 第三张图片:C++ OCR&;OpenCV:高分辨率图像上两帧之间的差异,c++,opencv,ocr,run-length-encoding,C++,Opencv,Ocr,Run Length Encoding,根据这篇文章,我现在知道了如何使用OpenCV查找两幅图像之间的像素差异 我希望改进此解决方案,并将其用于内容丰富的高分辨率图像(来自视频)。上面的示例不适用于大图像,因为处理速度太慢(发现太多差异,“findCountours方法”使用250k元素填充选项卡,这需要花费大量时间来处理) 我的应用程序使用RLE解码器对视频的压缩帧进行解码。一旦该帧被解码,我想将当前帧与前一帧进行比较,以便将两帧之间的差异存储在“Mat”选项卡中 所有这些的目标是能够对不同的像素进行分析,并检查是否存在任何拉丁字
正如你所见,我只有那些绿线,而没有文本(在减少计数[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;
}