百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

「技术分享」截图录屏-截长图的实现原理

bigegpt 2024-11-20 12:38 11 浏览

今天给大家分享一下截图录屏中截长图功能的实现原理及流程。

截长图功能,虽然在移动端已经屡见不鲜,但在PC端长久以来依然存在较大局限。以企业微信界面为例,主要的差异和难点如下:

移动端:界面布局大都为纵向设计(即:上、中、下三部分),可滚动区域和截图区域位于中间位置,基本固定,所以处理相对简单;

PC端:界面布局更复杂(包含:左,右,上,下,中五部分),界面交叉重叠,可滚动区域布局不明朗,而截图区域又由用户自由框选,区域不固定、不可控、单次截图滚动距离难以预测。

长图截取的过程,究其实质是在滚动过程中进行多次截图,同时进行上下拼接起来的结果,拼接的过程中会过滤掉上下重复的部分。主要流程如下:

1、在主线程上,根据鼠标滚轮事件触发截图,并将其保存到队列中(滚轮事件,既可以是自动滚动模拟发出的事件,也可以是在手动滚动模式下用户通过鼠标滚轮滚动发出的事件);

2、在子线程上,将截图队列中的图片进行编辑处理(比如:识别顶部与底部的固定区域并裁剪掉然后进行拼接,在最终结束时再将前面裁剪掉的顶部区域与底部区域还原到长图的顶部与底部)。

也就是说,截长图的核心流程就在于子线程上的“图像拼接”。

对图像拼接的实现过程是采用基于模板匹配的拼接算法,基本实现原理如下:

在截图B中截取部分公共区域ROI作为模板,利用模板在截图A中匹配,得到最佳匹配位置后计算Y方向需要平移的像素距离(上下拼接,只需计算纵坐标位置),将图B数据完全拷贝到图A中(0, Y)的起始位置。

OpenCV库提供了基于模板匹配的算法实现,详细实现流程如下:

1、将图片A、B转灰度图像;

2、获取图片B的前50行数据作为模板图像;

3、模板与图片A做模板匹配;

4、匹配结果矩阵阈值化处理;

5、如果匹配值是否大于阈值,则判断匹配成功,即基于匹配坐标位置拼接图片。

OpenCV提供了六种匹配算法:

1、CV_TM_SQDIFF 平方差匹配,最好匹配为0,值越大匹配越差

2、CV_TM_SQDIFF_NORMED 归一化平方差匹配

3、CV_TM_CCORR 相关匹配,采用乘法操作,值越大表明匹配越好

4、CV_TM_CCORR_NORMED 归一化相关匹配

5、CV_TM_CCOEFF 相关系数匹配,最好匹配为1,-1表示最差匹配

6、CV_TM_CCOEFF_NORMED 归一化相关系数匹配

从简单的匹配测量算法“平方差匹配”到更复杂的匹配测量算法“相关系数”,匹配精确度随之增加,但同时也意味着越来越大的计算代价。

为了同时兼顾速度和精度的最佳选择,在验证了所有匹配算法后,最后截长图在拼接时采用了CV_TM_CCOEFF_NORMED 归一化相关系数匹配。

归一化相关系数匹配是 OpenCV 支持的最复杂的一种相似度算法,运用了数理统计学科的相关系数计算方法。具体就是在减去了各自的平均值之外,还要各自除以各自的方差。

经过这两步操作之后,待检图像与模板都被标准化了,这样可以保证图像和模板分别改变光照亮度都不会影响计算结果。计算出的相关系数被限制在了 [-1, 1]区间。其中,1 表示完全相同,-1 表示两幅图像的亮度正好相反,0 表示两幅图像之间没有线性关系。

流程关键代码如下:

Mat ImageMerger::getMerageImageBasedOnTemplate1(const Mat &image1, const Mat &image2)
{
//转灰度图像
Mat image1_gray, image2_gray;
cvtColor(image1, image1_gray, CV_BGR2GRAY);
cvtColor(image2, image2_gray, CV_BGR2GRAY);
//1-50行选做模板
Mat temp = image2_gray(Range(1, 50), Range::all());
//结果矩阵图像,大小,数据类型
Mat res(image1_gray.rows - temp.rows + 1, image2_gray.cols - temp.cols + 1, CV_32FC1);
//模板匹配,采用归一化相关系数匹配
matchTemplate(image1_gray, temp, res, CV_TM_CCOEFF_NORMED);
//结果矩阵阈值化处理
threshold(res, res, 0.8, 1, CV_THRESH_TOZERO);
double minVal, maxVal, thresholdv = 0.8;
Point minLoc, maxLoc;
minMaxLoc(res, &minVal, &maxVal, &minLoc, &maxLoc);
//图像拼接
Mat temp1, result;
if (maxVal >= thresholdv)//只有度量值大于阈值才认为是匹配
{
//result:拼接后的图像
result = Mat::zeros(cvSize(image1.cols, maxLoc.y + image2.rows), image1.type());
//temp1:原图1的非模板部分
temp1 = image1(Rect(0, 0, image1.cols, maxLoc.y));
//将图1的非模板部分和图2拷贝到result
temp1.copyTo(Mat(result, Rect(0, 0, image1.cols, maxLoc.y)));
image2.copyTo(Mat(result, Rect(0, maxLoc.y - 1, image2.cols, image2.rows)));
}
//将合并后的图像保存
imwrite("merge.jpg", result);
return result;

当前截长图功能已经能满足大多数场景,同时还存在以下不足:

1、拼接处不能有影响算法识别的区域, 例如大片的空白区域,或重复相同区域;

2、框选区域中不能有动态变化的视频或是动画;

后续我们将继续调研和优化现有的算法,进而完善截长图功能。也欢迎感兴趣的朋友给我们留言讨论。

相关推荐

悠悠万事,吃饭为大(悠悠万事吃饭为大,什么意思)

新媒体编辑:杜岷赵蕾初审:程秀娟审核:汤小俊审签:周星...

高铁扒门事件升级版!婚宴上‘冲喜’老人团:我们抢的是社会资源

凌晨两点改方案时,突然收到婚庆团队发来的视频——胶东某酒店宴会厅,三个穿大红棉袄的中年妇女跟敢死队似的往前冲,眼瞅着就要扑到新娘的高额钻石项链上。要不是门口小伙及时阻拦,这婚礼造型团队熬了三个月的方案...

微服务架构实战:商家管理后台与sso设计,SSO客户端设计

SSO客户端设计下面通过模块merchant-security对SSO客户端安全认证部分的实现进行封装,以便各个接入SSO的客户端应用进行引用。安全认证的项目管理配置SSO客户端安全认证的项目管理使...

还在为 Spring Boot 配置类加载机制困惑?一文为你彻底解惑

在当今微服务架构盛行、项目复杂度不断攀升的开发环境下,SpringBoot作为Java后端开发的主流框架,无疑是我们手中的得力武器。然而,当我们在享受其自动配置带来的便捷时,是否曾被配置类加载...

Seata源码—6.Seata AT模式的数据源代理二

大纲1.Seata的Resource资源接口源码2.Seata数据源连接池代理的实现源码3.Client向Server发起注册RM的源码4.Client向Server注册RM时的交互源码5.数据源连接...

30分钟了解K8S(30分钟了解微积分)

微服务演进方向o面向分布式设计(Distribution):容器、微服务、API驱动的开发;o面向配置设计(Configuration):一个镜像,多个环境配置;o面向韧性设计(Resista...

SpringBoot条件化配置(@Conditional)全面解析与实战指南

一、条件化配置基础概念1.1什么是条件化配置条件化配置是Spring框架提供的一种基于特定条件来决定是否注册Bean或加载配置的机制。在SpringBoot中,这一机制通过@Conditional...

一招解决所有依赖冲突(克服依赖)

背景介绍最近遇到了这样一个问题,我们有一个jar包common-tool,作为基础工具包,被各个项目在引用。突然某一天发现日志很多报错。一看是NoSuchMethodError,意思是Dis...

你读过Mybatis的源码?说说它用到了几种设计模式

学习设计模式时,很多人都有类似的困扰——明明概念背得滚瓜烂熟,一到写代码就完全想不起来怎么用。就像学了一堆游泳技巧,却从没下过水实践,很难真正掌握。其实理解一个知识点,就像看立体模型,单角度观察总...

golang对接阿里云私有Bucket上传图片、授权访问图片

1、为什么要设置私有bucket公共读写:互联网上任何用户都可以对该Bucket内的文件进行访问,并且向该Bucket写入数据。这有可能造成您数据的外泄以及费用激增,若被人恶意写入违法信息还可...

spring中的资源的加载(spring加载原理)

最近在网上看到有人问@ContextConfiguration("classpath:/bean.xml")中除了classpath这种还有其他的写法么,看他的意思是想从本地文件...

Android资源使用(android资源文件)

Android资源管理机制在Android的开发中,需要使用到各式各样的资源,这些资源往往是一些静态资源,比如位图,颜色,布局定义,用户界面使用到的字符串,动画等。这些资源统统放在项目的res/独立子...

如何深度理解mybatis?(如何深度理解康乐服务质量管理的5个维度)

深度自定义mybatis回顾mybatis的操作的核心步骤编写核心类SqlSessionFacotryBuild进行解析配置文件深度分析解析SqlSessionFacotryBuild干的核心工作编写...

@Autowired与@Resource原理知识点详解

springIOCAOP的不多做赘述了,说下IOC:SpringIOC解决的是对象管理和对象依赖的问题,IOC容器可以理解为一个对象工厂,我们都把该对象交给工厂,工厂管理这些对象的创建以及依赖关系...

java的redis连接工具篇(java redis client)

在Java里,有不少用于连接Redis的工具,下面为你介绍一些主流的工具及其特点:JedisJedis是Redis官方推荐的Java连接工具,它提供了全面的Redis命令支持,且...