专栏名称: 腾讯云加社区
目录
相关文章推荐
植物星球  ·  发现了狗牙蜡梅之美 ·  3 天前  
植物星球  ·  樱花树上长了木耳和灵芝,采不采? ·  2 天前  
植物星球  ·  雨水是春的开始 ·  4 天前  
第一财经资讯  ·  两年消失8000万张!信用卡业务春寒料峭 ·  2 天前  
51好读  ›  专栏  ›  腾讯云加社区

如何在直播中解决花屏问题?

腾讯云加社区  · 掘金  ·  · 2018-10-18 07:06

正文

阅读 44

如何在直播中解决花屏问题?

欢迎大家前往 腾讯云+社区 ,获取更多腾讯海量技术实践干货哦~

本文由 腾讯云视频 发表于 云+社区专栏

img

关注公众号“腾讯云视频”,一键获取 技术干货 | 优惠活动 | 视频方案

本是一名佛性型吃鸡选手,自从被三个妹子带着躺尸吃鸡之后,便立志要成为一名吃鸡高手,一大早便沉迷于各大网站的吃鸡直播中,正看到决赛圈激动人心的时刻,直播花屏了?然后游戏结束了?我的天,我是谁?我在哪?我错过了什么?

作为一名有强迫症的IT小哥哥,怎能让直播花屏现象存在呢?一方面,为了自己能成为一名吃鸡高手。另一方面,不能错过每一个升职加薪的机会。就这样开始了一段漫长的长征之路……

对于直播业务,"秒开、卡顿、时延、进房成功率"是我们经常关注的几个指标,这些指标可以说是从"一个用户能够优雅地进入直播间"的角度来考量的,然而进入直播间后"用户究竟看到的什么内容"也是很关键的一环,内容上除了涉及安全的一些指标外,还可能会有内容是否有花屏、绿屏等其他异常内容,这时我们便会考虑如何衡量和发现外网的花屏情况。

本文主要针对花屏提出了一种基于CNN网络的检测方案。

01

花屏检测能力构建

无论是视频还是直播,都是由一帧帧图像组成的,之所以会以一种动态的形式展现到我们眼前,是因为了人类的视觉暂留现象。

物体在快速运动时, 当人眼所看到的影像消失后,人眼仍能继续保留其影像0.1-0.4秒左右的图像,这种现象被称为 视觉暂留现象

既然如此,检测直播中是否存在花屏,其实可以转换为检测直播中的帧画面是否是花屏的画面,即一个图像识别问题。 那么如何识别一个图像是否是花屏呢?

通常图像识别总是以特征为基础的,我们会先根据所设定的目标来提取相应的特征,用于我们后面来制定策略。不过好在现在的深度学习卷积神经网络CNN将提取特征和制定决策策略都帮我们完成了。

而使用深度学习CNN网络则绕不开 数据集 模型训练 两大块

1.1数据集准备

困难

要使用深度学习网络,一个门槛是需要足够的带有标签的数据集,否则**学习出的网络很容易过拟合,从而泛化能力不强。**说其是门槛是因为实际业务中更多情况是缺少数据集,就以现在的花屏为例,目前直播发生花屏的案例非常少,想要通过实际案例来收集足够的花屏图片作为训练集显得异常困难。因此必须探寻其他的路子来收集训练集。

人类之所以能够分辨出花屏,是因为人类眼睛能够找到花屏图像的特征,虽然这些特征我们可能用语言都描述不出来,事实上,如果我们能用语言描述出特征,我们也很容易将其翻译成代码来找到花屏图像的特征。

制作训练集

机器学习其实也是通过特征来工作的,既然如此,我们可以制作一些花屏图像出来,让CNN网络找到它们区别于正常图片的特征,从而学习到花屏图片的检测能力。

在使用YUVviewer工具时,发现当设置错误的分辨率来播放视频文件时会出现花屏情况。灵感来源于此,我们完全可以通过使用错误的分辨率从YUV文件中抽取帧,从而拿到花屏图片。整体流程如下:

img

这里需要了解YUV文件的存储格式,从而根据格式来进行抽取对应的帧:

YUV,分为三个分量,“Y”表示明亮度(Luminance或Luma),也就是灰度值;而“U”和“V” 表示的则是色度(Chrominance或Chroma),作用是描述影像色彩及饱和度,用于指定像素的颜色。

YUV采样样式有一下几种,以黑点表示采样该像素点的Y分量,以空心圆圈表示采用该像素点的UV分量,一般情况下我们都使用的是YUV420格式

img

YUV420格式存储方式如下所示:

img

按照上面存储方式编写代码来提取帧,代码如下:

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)分辨率正确

img

2)分辨率width+1情况

img

3)分辨率width+n情况

img

4)分辨率width-1情况

img

5)分辨率width-n情况

img

上面只是针对图片宽来进行错误干扰,可以看出宽变小花屏条纹方向是左下的,宽变大花屏条纹方向时右下的。

所以我们队宽和高分别设置不同的错误值,会造成不同类型的花屏,于是可以用这种策略构造大量的花屏。

我们用800多个视频,每个视频以一定的间隔来抽10帧,获得了8000多张花屏图片。

img

img

这些图片标签为花屏,也就是我们的正样本,负样本可选取实际直播中的正常截图。

至此,数据集准备差不多了。

1.2 模型和训练

模型上使用网上一些知名模型即可,这里我们使用了轻量的mobilenet模型,模型结构如下图所示:







请到「今天看啥」查看全文