1.简介
该方法发布于IEEE Conference on Computer Vision and Pattern Recognition (CVPR) 2020,由 港中文商汤联合实验室与香港中文大学深圳合作发作
GitHub地址:https://github.com/AnyiRao/SceneSeg
网站地址:https://anyirao.com/projects/SceneSeg.html
相对于传统的视频切割,该篇文章给出了”幕“scene的定义,另一方面,今年的腾讯广告算法大赛提出了新的定义,可以更加直观地理解:
LGSS认为幕是镜头切割的子集,因此先进行镜头切割,再通过地点,人物,动作和音频对镜头进行分类(是否为幕边界)
2.具体步骤
2.1 数据预处理
数据预处理模块主要分为音频特征提取,地点特征提取以及镜头切割
音频特征:
使用在AVA-ActiveSpeaker数据集训练的NaverNet模型分离演讲以及背景音,再使用stft模型分别获得镜头特征并结合得到音频特征。
地点特征:
使用ResNet50,Faster-RCNN等预训练模型获得地点,动作等特征,详情如下:
ResNet50 [11] pretrained on Places dataset [33] on key frame images to get place features, 2) Faster-RCNN [20]
pretrained on CIM dataset [12, 30] to detect cast instances
and ResNet50 pretrained on PIPA dataset [32] to extract
cast features, 3) TSN [28] pretrained on AVA dataset [8]
to get action features
镜头切割:
镜头切割通过设定阈值,计算图像hsv相似度得到
2.2 幕粗获得
接下来其实是一个二分类问题,即对每个镜头进行是否为幕的分类预测,首先采用一个边界网络(BNet)对镜头的差异与关系进行提取。Bnet由两个分支网络构建,Bd捕捉镜头前后两幕的差异,Br用于捕捉镜头关系,由一个卷积加一个最大池化层构建。
class BNet(nn.Module):
#context即Br,sim即Bd
def __init__(self, cfg):
super(BNet, self).__init__()
self.shot_num = cfg.shot_num
self.channel = cfg.model.sim_channel
self.conv1 = nn.Conv2d(1, self.channel, kernel_size=(cfg.shot_num, 1))
self.max3d = nn.MaxPool3d(kernel_size=(self.channel, 1, 1))
self.cos = Cos(cfg)
def forward(self, x): # [batch_size, seq_len, shot_num, feat_dim]
context = x.view(x.shape[0]*x.shape[1], 1, -1, x.shape[-1])
context = self.conv1(context) # batch_size*seq_len,512,1,feat_dim
context = self.max3d(context) # batch_size*seq_len,1,1,feat_dim
context = context.squeeze()
sim = self.cos(x)
bound = torch.cat((context, sim), dim=1)
return bound
基于获得通过Bnet得到的镜头代表,构建一个lstm模型获得镜头构成幕的概率,通过设定幕个数阈值得到结果。
2.3 整体信息
由于构成幕时未考虑到整体,因此将问题转化为整体最优化问题,即如何将我们上一步得到的粗分幕(超级镜头)分入j个幕(自定阈值)中