引言:

为了实现智能预览功能:将与视频进度条所在的视频片段的场景相似的场景视频展示给用户,即用户看到某个场景片段的同时也会看到相似的场景片段,并且当点击某个相似场景片段时,进度条会跳转到该场景片段。

提取视频特征:

使用 googlenet 网络进行特征的提取

Extract_Feature 类初始化函数(每个场景视频的图像的特征值保存都在一个h5文件中):

    def __init__(self, video_path, save_path):self.resnet = ResNet()self.google = googlenet(pretrained=True)self.google.float()self.google.cuda()self.google.eval()self.video_list = []self.video_path = ''self.h5_file = h5py.File(save_path, 'w')self._set_video_list(video_path)

获取所有的场景视频,创建相应的h5文件:

    def _set_video_list(self, video_path):# 如果video_path是目录,获取目录下的所有文件名并排序if os.path.isdir(video_path):self.video_path = video_pathself.video_list = os.listdir(video_path)self.video_list.sort()else:self.video_path = ''self.video_list.append(video_path)for idx, file_name in enumerate(self.video_list):# H5PY采用create_group命令进行创建self.h5_file.create_group('video_{}'.format(idx + 1))

对图像进行特征提取:

    def _extract_feature(self, frame):# 改变图像的颜色空间frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)# 对图片进行缩放frame = cv2.resize(frame, (224, 224))EF = [frame[:, :, 0], frame[:, :, 1], frame[:, :, 2]]EF = np.array(EF)# torch.from_numpy()方法把数组转换成张量,且二者共享内存,对张量进行修改比如重新赋值,那么原始数组也会相应发生改变# unsqueeze(dim=0)对0维度扩展一维frameTen = t.from_numpy(EF).unsqueeze(dim=0).cuda().float()res_pool5 = self.google(frameTen)frame_feat = res_pool5.cpu().data.numpy().flatten()return frame_feat

处理所有的场景视频,读取每个视频的每一帧,然后调用上面的_extract_feature方法提取每一帧的特征,并将每个视频的特征值写入相应的h5文件中,这里每个视频的特征表示为维数(帧数,1000)的张量

    def generate_dataset(self):print('generating...')print("video_list",self.video_list)for video_idx, video_filename in enumerate(self.video_list):video_path = video_filenameif os.path.isdir(self.video_path):video_path = os.path.join(self.video_path, video_filename)video_capture = cv2.VideoCapture(video_path)  # 读取视频fps = video_capture.get(cv2.CAP_PROP_FPS)  # 获取视频帧率n_frames = int(video_capture.get(cv2.CAP_PROP_FRAME_COUNT))  # 获取视频总帧数frame_list = []picks = []video_feat = Nonevideo_feat_for_train = Nonefor frame_idx in tqdm(range(n_frames - 1)):success, frame = video_capture.read()  # 读取下一帧if success:frame_feat = self._extract_feature(frame)picks.append(frame_idx)if video_feat is None:video_feat = frame_featelse:video_feat = np.vstack((video_feat, frame_feat))else:breakvideo_capture.release()print("shape of video_feat",video_feat.shape)self.h5_file['video_{}'.format(video_idx + 1)]['features'] = list(video_feat)

完整代码:

import argparse
import torch as t
import os
from torchvision.models import googlenet
# tqdm 进度条库
from tqdm import tqdm
import cv2
import numpy as np
import h5pyparser = argparse.ArgumentParser("Pytorch code for unsupervised video feature extraction with REINFORCE")
parser.add_argument('--ID', type=str)
parser.add_argument('--ID_VideoName', type=str)
parser.add_argument('--VideoName', type=str)
args = parser.parse_args()# Pytorch 提供 torchvision.models 接口,里面包含了一些常用用的网络结构,并提供了预训练模型,可以通过简单调用来读取网络结构和预训练模型。
class Extract_Feature:def __init__(self, video_path, save_path):self.google = googlenet(pretrained=True)self.google.float()self.google.cuda()self.google.eval()self.video_list = []self.video_path = ''self.h5_file = h5py.File(save_path, 'w')self._set_video_list(video_path)#  获取所有的视频,创建相应的h5文件def _set_video_list(self, video_path):# 如果video_path是目录,获取目录下的所有文件名并排序if os.path.isdir(video_path):self.video_path = video_pathself.video_list = os.listdir(video_path)self.video_list.sort()else:self.video_path = ''self.video_list.append(video_path)for idx, file_name in enumerate(self.video_list):# H5PY采用create_group命令进行创建self.h5_file.create_group('video_{}'.format(idx + 1))# 提取特征def _extract_feature(self, frame):# 改变图像的颜色空间frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)# 对图片进行缩放frame = cv2.resize(frame, (224, 224))EF = [frame[:, :, 0], frame[:, :, 1], frame[:, :, 2]]EF = np.array(EF)# torch.from_numpy()方法把数组转换成张量,且二者共享内存,对张量进行修改比如重新赋值,那么原始数组也会相应发生改变# unsqueeze(dim=0)对0维度扩展一维frameTen = t.from_numpy(EF).unsqueeze(dim=0).cuda().float()res_pool5 = self.google(frameTen)frame_feat = res_pool5.cpu().data.numpy().flatten()return frame_featdef generate_dataset(self):print('generating...')print("video_list",self.video_list)for video_idx, video_filename in enumerate(self.video_list):video_path = video_filenameif os.path.isdir(self.video_path):video_path = os.path.join(self.video_path, video_filename)video_capture = cv2.VideoCapture(video_path)  # 读取视频fps = video_capture.get(cv2.CAP_PROP_FPS)  # 获取视频帧率n_frames = int(video_capture.get(cv2.CAP_PROP_FRAME_COUNT))  # 获取视频总帧数frame_list = []picks = []video_feat = Nonevideo_feat_for_train = Nonefor frame_idx in tqdm(range(n_frames - 1)):success, frame = video_capture.read()  # 读取下一帧if success:frame_feat = self._extract_feature(frame)picks.append(frame_idx)if video_feat is None:video_feat = frame_featelse:video_feat = np.vstack((video_feat, frame_feat))else:breakvideo_capture.release()print("shape of video_feat",video_feat.shape)self.h5_file['video_{}'.format(video_idx + 1)]['features'] = list(video_feat)if __name__ == '__main__':# 要处理的视频所在的目录short_video_path_dir = '/opt/data/private/xuyunyang/EasyCut/' + args.ID + '/' + args.ID_VideoName + '/Key_Frame/' + args.VideoNamedirs = os.listdir(short_video_path_dir)for file in dirs:short_video_path = short_video_path_dir + '/' + fileshort_video_name = short_video_path.split('/')[-1].split('.')[0]# h5文件的保存地址result_path_dir = '/opt/data/private/xuyunyang/EasyCut/' + args.ID + '/' + args.ID_VideoName + '/SceneFeature/'if not os.path.exists(result_path_dir):os.makedirs(result_path_dir)result_path = os.path.join(result_path_dir, short_video_name + '.h5')gen = Extract_Feature(short_video_path, result_path)gen.generate_dataset()gen.h5_file.close()

运行结果:

项目实训(十)—提取视频特征相关推荐

  1. 项目实训-关键词提取-论文研读-load centrality的合理性探讨

    项目实训记录系列博客 一马当先,争做国家栋梁. 博客说明 本博客初衷是用于学校项目实训知识梳理.工作内容.收获感悟的记录. 若能在您的学习之路上有所帮助,不胜荣幸.但若需转载,也请注明出处. 博客包含 ...

  2. 项目实训-关键词提取-任务理解工作分配

    项目实训记录系列博客 一马当先,争做国家栋梁. 博客说明 本博客初衷是用于学校项目实训知识梳理.工作内容.收获感悟的记录. 若能在您的学习之路上有所帮助,不胜荣幸.但若需转载,也请注明出处. 博客包含 ...

  3. 山东大学项目实训十六——可控音乐变压器Controllable Music Transformer

    Controllable Music Transformer Official code for our paper Video Background Music Generation with Co ...

  4. 火云开发课堂 - 《使用Cocos2d-x 开发3D游戏》系列 第二十四节:小项目实训《绝命沙滩》

    <使用Cocos2d-x 开发3D游戏>系列在线课程 第二十四节:小项目实训<绝命沙滩> 视频地址:http://edu.csdn.net/course/detail/1330 ...

  5. 视频教程-JSP从入门到精通2016+在线视频教学平台项目实训-其他

    JSP从入门到精通2016+在线视频教学平台项目实训 19年软件开发经验,设计开发40多个大型软件,10年从事高等教育,主要为java系列课程,带你轻松进入java生涯. 赖国荣 ¥68.00 立即订 ...

  6. 项目实训(十六)——总结

    通过这次项目实训学到了很多自己之前没有接触过的知识,对unity游戏开发和C#语言有了更深入的了解.开发的过程非常艰难,但最终还是解决了不少问题,完成了许多功能.在这里我要感谢一下我的队友们和指导老师 ...

  7. 项目实训-收尾工作-组织协调

    项目实训记录系列博客 一马当先,争做国家栋梁. 博客说明 本博客初衷是用于学校项目实训知识梳理.工作内容.收获感悟的记录. 若能在您的学习之路上有所帮助,不胜荣幸.但若需转载,也请注明出处. 博客包含 ...

  8. 【项目实训】篮球计分系统设计(无线nRF905版本)

    将单片机项目实训--篮球计分系统(无线nRF905版本)分享出来,如有不足,敬请指出. [实验图片] [视频视频] [项目实训]篮球积分系统(nRF905版本) 目录 一.设计要求 二.方案设计 三. ...

  9. C语言编程实训企业计算,C语言编程项目实训

    24.C语言编程项目实训(高级)(全日制一个半月,夜班三个月,学费1390元) 理论与实操一体化课程: 一.C语言基础:1.应用C语言的各种特点:2.应用算法的含义.特点.表示方法 二.C的基本数据类 ...

最新文章

  1. 数据缺失、混乱、重复怎么办?最全数据清洗指南!
  2. SEO网络优化三招教你高质量外链的技巧
  3. 获取前一天的时间安排表_要想有一个完美的婚礼 这份婚庆策划时间表少不了...
  4. 上海理工大学第二届“联想杯”全国程序设计邀请赛 - Experiment Class(几何+三分套三分)
  5. Linux中高斯分布的参数设置,华为openGauss 配置操作系统参数
  6. java句柄数过高怎么解决_主播个人及企业利润高,个税或企业所得税怎么解决...
  7. 编程语言对比 内存操作
  8. 红旗linux系统可以运行QQ吗,如何在红旗Linux系统redflag6.0上安装QQ
  9. SharedMaterial的一些问题
  10. 想学习Java编程,看书还是看视频更合适?
  11. 配置管理工具Puppet入门介绍:1 :安装与设定
  12. DayDayUp:计算机技术与软件专业技术资格证书之《系统集成项目管理工程师》课程讲解之十大知识领域之4核心—项目质量管理
  13. 批量修改文件名称方法
  14. python 英语词频统计_Python实现统计英文文章词频的方法分析
  15. 云计算网络,在数据中心之中主要有哪些优势?
  16. Spring AOP基础组件 Advised
  17. 微信公众号代运营的的技巧有哪些(2)
  18. 按分数段统计学生人数python_用Excel统计各分数段学生数
  19. mismatch,equal比较两序列
  20. springcloud数据库密码加密

热门文章

  1. amd cpu 安卓模拟器_Android模拟器稳定版终于支持AMD处理器 开发者喜极而泣
  2. **为什么安装CAD时总出现 Command line option syntax error.**
  3. 宁可累死在路上,也绝不闲死在家里
  4. 【linux】解决系统卡在ubuntu loading initial ramdisk
  5. 尝试“魔镜” 没有想象中的美好
  6. 个人作业-week2:关于微软必应词典的案例分析
  7. SecureCRT中文乱码解决方法以及相关配置
  8. 有意识领导力承诺12:一切都是足够的
  9. Java后端学习路线分享
  10. Django学习记录10——Django使用支付宝付款(电脑支付,手机网页支付,面对面扫码)