欢迎你们前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~javascript
本文由 腾讯云视频发表于 云+社区专栏
关注公众号“腾讯云视频”,一键获取 技术干货 | 优惠活动 | 视频方案java
本是一名佛性型吃鸡选手,自从被三个妹子带着躺尸吃鸡以后,便立志要成为一名吃鸡高手,一大早便沉迷于各大网站的吃鸡直播中,正看到决赛圈激动人心的时刻,直播花屏了?而后游戏结束了?个人天,我是谁?我在哪?我错过了什么?安全
做为一名有强迫症的IT小哥哥,怎能让直播花屏现象存在呢?一方面,为了本身能成为一名吃鸡高手。另外一方面,不能错过每个升职加薪的机会。就这样开始了一段漫长的长征之路……网络
对于直播业务,"秒开、卡顿、时延、进房成功率"是咱们常常关注的几个指标,这些指标能够说是从"一个用户可以优雅地进入直播间"的角度来考量的,然而进入直播间后"用户究竟看到的什么内容"也是很关键的一环,内容上除了涉及安全的一些指标外,还可能会有内容是否有花屏、绿屏等其余异常内容,这时咱们便会考虑如何衡量和发现外网的花屏状况。框架
本文主要针对花屏提出了一种基于CNN网络的检测方案。机器学习
01工具
花屏检测能力构建 学习
不管是视频仍是直播,都是由一帧帧图像组成的,之因此会以一种动态的形式展示到咱们眼前,是由于了人类的视觉暂留现象。测试
物体在快速运动时, 当人眼所看到的影像消失后,人眼仍能继续保留其影像0.1-0.4秒左右的图像,这种现象被称为视觉暂留现象。网站
既然如此,检测直播中是否存在花屏,其实能够转换为检测直播中的帧画面是不是花屏的画面,即一个图像识别问题。那么如何识别一个图像是不是花屏呢?
一般图像识别老是以特征为基础的,咱们会先根据所设定的目标来提取相应的特征,用于咱们后面来制定策略。不过好在如今的深度学习卷积神经网络CNN将提取特征和制定决策策略都帮咱们完成了。
而使用深度学习CNN网络则绕不开数据集和模型训练两大块
1.1数据集准备
困难
要使用深度学习网络,一个门槛是须要足够的带有标签的数据集,不然学习出的网络很容易过拟合,从而泛化能力不强。说其是门槛是由于实际业务中更多状况是缺乏数据集,就以如今的花屏为例,目前直播发生花屏的案例很是少,想要经过实际案例来收集足够的花屏图片做为训练集显得异常困难。所以必须探寻其余的路子来收集训练集。
人类之因此可以分辨出花屏,是由于人类眼睛可以找到花屏图像的特征,虽然这些特征咱们可能用语言都描述不出来,事实上,若是咱们能用语言描述出特征,咱们也很容易将其翻译成代码来找到花屏图像的特征。
制做训练集
机器学习其实也是经过特征来工做的,既然如此,咱们能够制做一些花屏图像出来,让CNN网络找到它们区别于正常图片的特征,从而学习到花屏图片的检测能力。
在使用YUVviewer工具时,发现当设置错误的分辨率来播放视频文件时会出现花屏状况。灵感来源于此,咱们彻底能够经过使用错误的分辨率从YUV文件中抽取帧,从而拿到花屏图片。总体流程以下:
这里须要了解YUV文件的存储格式,从而根据格式来进行抽取对应的帧:
YUV,分为三个份量,“Y”表示明亮度(Luminance或Luma),也就是灰度值;而“U”和“V” 表示的则是色度(Chrominance或Chroma),做用是描述影像色彩及饱和度,用于指定像素的颜色。
YUV采样样式有一下几种,以黑点表示采样该像素点的Y份量,以空心圆圈表示采用该像素点的UV份量,通常状况下咱们都使用的是YUV420格式
YUV420格式存储方式以下所示:
按照上面存储方式编写代码来提取帧,代码以下:
def get_frames_from_YUV(filename, dims, numfrm, startfrm, frmstep): """ 从给定的YUV文件中抽取对应的帧数据,帧数据格式仍然为YUV :param filename: YUV文件路径 :param dims: YUV文件的分辨率 :param numfrm: 要提取帧的数量 :param startfrm: 从哪一帧开始提取 :param frmstep: 抽取帧的帧间隔,即每隔几帧抽一帧 :return: 返回抽取帧的Y列表,U列表,V列表 """ filesize = os.path.getsize(filename) fp = open(filename, 'rb') blk_size = prod(dims) * 3 / 2 # 计算每帧大小 if (startfrm+1+(numfrm-1)*frmstep)*blk_size > filesize: numfrm = (filesize/blk_size - 1 - startfrm)/frmstep +1 util.log('文件读取越界--修改成%d'%numfrm) fp.seek(blk_size * startfrm, 0) # 跳转到指定开始帧 Y, U, V= [],[],[] d00 = dims[0] / 2 d01 = dims[1] / 2 for i in range(numfrm): util.log('文件读取第%d帧' % i) Yt = zeros((dims[1], dims[0]), uint8, 'C') Ut = zeros((d01, d00), uint8, 'C') Vt = zeros((d01, d00), uint8, 'C') for m in range(dims[1]): for n in range(dims[0]): # print m,n Yt[m, n] = ord(fp.read(1)) for m in range(d01): for n in range(d00): Ut[m, n] = ord(fp.read(1)) for m in range(d01): for n in range(d00): Vt[m, n] = ord(fp.read(1)) Y = Y + [Yt] U = U + [Ut] V = V + [Vt] fp.seek(blk_size * (frmstep - 1), 1) # 跳出间隔帧 fp.close() return (Y, U, V)
这里对分辨率错误的多种状况也作了下研究,发现以下规律:
1)分辨率正确
2)分辨率width+1状况
3)分辨率width+n状况
4)分辨率width-1状况
5)分辨率width-n状况
上面只是针对图片宽来进行错误干扰,能够看出宽变小花屏条纹方向是左下的,宽变大花屏条纹方向时右下的。
因此咱们队宽和高分别设置不一样的错误值,会形成不一样类型的花屏,因而能够用这种策略构造大量的花屏。
咱们用800多个视频,每一个视频以必定的间隔来抽10帧,得到了8000多张花屏图片。
这些图片标签为花屏,也就是咱们的正样本,负样本可选取实际直播中的正常截图。
至此,数据集准备差很少了。
1.2 模型和训练
模型上使用网上一些知名模型便可,这里咱们使用了轻量的mobilenet模型,模型结构以下图所示:
训练采用基于用imagenet已经训练好的模型来进行finetune训练,最后一层使用随机超参数来训练(这一层也没法读取pretrained模型的超参数,由于分类数不一致)。训练能够快速收敛,由于特征太明显了,并且测试集准确率很高。
其实这里训练是一个不断迭代的过程,由于机器学习模型是一张白纸,它要具备怎样的能力彻底是你教它的,而教的方式就是经过训练集(数据和标签),而想要让它可以应对更多的状况,你的训练集就要尽量涵盖各类状况。
而咱们的训练集老是不足的,你总会有care不到的地方。训练集不足的状况会怎样?举个例子
你训练个识别飞机的模型,而大部分关于飞机的图片都有天空,这样你给张天空的图片到模型,它也可能会认为是飞机,由于其实模型极可能学到的是天空的特征。而怎么让模型学到飞机的特征呢,固然须要调整训练集,让训练集里不只包含背景为天空的飞机,还有陆地上的飞机等等。
经过不断低迭代调优,咱们在空间场景下检测准确率已经能够达到94%,NOW直播场景检测准确率也已达到90%。
02
直播检测方案
检测能力具有后想要真正地接入直播业务,还须要将直播流进行分帧,而后把对应的帧图片进行花屏检测。
后台总体框架
采用分帧截屏的手段,若是天天须要检测2000万张截图,即10s会有一张截图须要检测,而考虑花屏老是出如今很长的一段时间内,所以这里但愿可以以更长的时间来抽样从而避免浪费算力。
附一张目前业务检测花屏结果的截图:
做为一名热爱工做的IT小哥哥,花了一个星期的时间,总算把基于CNN网络的直播花屏检测的工做告一段落了。
工做使我开心,游戏使我快乐,终于能够再次流畅的游走在各大网址的吃鸡直播中啦~
问答
游戏体系结构
相关阅读
团战开黑必备“良药”了解一下!
不再用担忧网吧开黑队友听不清了!
3行代码,为QQ轻游戏加上语音互动能力
【每日课程推荐】机器学习实战!快速入门在线广告业务及CTR相应知识
此文已由做者受权腾讯云+社区发布,更多原文请点击
搜索关注公众号「云加社区」,第一时间获取技术干货,关注后回复1024 送你一份技术课程大礼包!
海量技术实践经验,尽在云加社区!