项目实训(十)—提取视频特征
引言:
为了实现智能预览功能:将与视频进度条所在的视频片段的场景相似的场景视频展示给用户,即用户看到某个场景片段的同时也会看到相似的场景片段,并且当点击某个相似场景片段时,进度条会跳转到该场景片段。
提取视频特征:
使用 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()
运行结果:
项目实训(十)—提取视频特征相关推荐
- 项目实训-关键词提取-论文研读-load centrality的合理性探讨
项目实训记录系列博客 一马当先,争做国家栋梁. 博客说明 本博客初衷是用于学校项目实训知识梳理.工作内容.收获感悟的记录. 若能在您的学习之路上有所帮助,不胜荣幸.但若需转载,也请注明出处. 博客包含 ...
- 项目实训-关键词提取-任务理解工作分配
项目实训记录系列博客 一马当先,争做国家栋梁. 博客说明 本博客初衷是用于学校项目实训知识梳理.工作内容.收获感悟的记录. 若能在您的学习之路上有所帮助,不胜荣幸.但若需转载,也请注明出处. 博客包含 ...
- 山东大学项目实训十六——可控音乐变压器Controllable Music Transformer
Controllable Music Transformer Official code for our paper Video Background Music Generation with Co ...
- 火云开发课堂 - 《使用Cocos2d-x 开发3D游戏》系列 第二十四节:小项目实训《绝命沙滩》
<使用Cocos2d-x 开发3D游戏>系列在线课程 第二十四节:小项目实训<绝命沙滩> 视频地址:http://edu.csdn.net/course/detail/1330 ...
- 视频教程-JSP从入门到精通2016+在线视频教学平台项目实训-其他
JSP从入门到精通2016+在线视频教学平台项目实训 19年软件开发经验,设计开发40多个大型软件,10年从事高等教育,主要为java系列课程,带你轻松进入java生涯. 赖国荣 ¥68.00 立即订 ...
- 项目实训(十六)——总结
通过这次项目实训学到了很多自己之前没有接触过的知识,对unity游戏开发和C#语言有了更深入的了解.开发的过程非常艰难,但最终还是解决了不少问题,完成了许多功能.在这里我要感谢一下我的队友们和指导老师 ...
- 项目实训-收尾工作-组织协调
项目实训记录系列博客 一马当先,争做国家栋梁. 博客说明 本博客初衷是用于学校项目实训知识梳理.工作内容.收获感悟的记录. 若能在您的学习之路上有所帮助,不胜荣幸.但若需转载,也请注明出处. 博客包含 ...
- 【项目实训】篮球计分系统设计(无线nRF905版本)
将单片机项目实训--篮球计分系统(无线nRF905版本)分享出来,如有不足,敬请指出. [实验图片] [视频视频] [项目实训]篮球积分系统(nRF905版本) 目录 一.设计要求 二.方案设计 三. ...
- C语言编程实训企业计算,C语言编程项目实训
24.C语言编程项目实训(高级)(全日制一个半月,夜班三个月,学费1390元) 理论与实操一体化课程: 一.C语言基础:1.应用C语言的各种特点:2.应用算法的含义.特点.表示方法 二.C的基本数据类 ...
最新文章
- 数据缺失、混乱、重复怎么办?最全数据清洗指南!
- SEO网络优化三招教你高质量外链的技巧
- 获取前一天的时间安排表_要想有一个完美的婚礼 这份婚庆策划时间表少不了...
- 上海理工大学第二届“联想杯”全国程序设计邀请赛 - Experiment Class(几何+三分套三分)
- Linux中高斯分布的参数设置,华为openGauss 配置操作系统参数
- java句柄数过高怎么解决_主播个人及企业利润高,个税或企业所得税怎么解决...
- 编程语言对比 内存操作
- 红旗linux系统可以运行QQ吗,如何在红旗Linux系统redflag6.0上安装QQ
- SharedMaterial的一些问题
- 想学习Java编程,看书还是看视频更合适?
- 配置管理工具Puppet入门介绍:1 :安装与设定
- DayDayUp:计算机技术与软件专业技术资格证书之《系统集成项目管理工程师》课程讲解之十大知识领域之4核心—项目质量管理
- 批量修改文件名称方法
- python 英语词频统计_Python实现统计英文文章词频的方法分析
- 云计算网络,在数据中心之中主要有哪些优势?
- Spring AOP基础组件 Advised
- 微信公众号代运营的的技巧有哪些(2)
- 按分数段统计学生人数python_用Excel统计各分数段学生数
- mismatch,equal比较两序列
- springcloud数据库密码加密
热门文章
- amd cpu 安卓模拟器_Android模拟器稳定版终于支持AMD处理器 开发者喜极而泣
- **为什么安装CAD时总出现 Command line option syntax error.**
- 宁可累死在路上,也绝不闲死在家里
- 【linux】解决系统卡在ubuntu loading initial ramdisk
- 尝试“魔镜” 没有想象中的美好
- 个人作业-week2:关于微软必应词典的案例分析
- SecureCRT中文乱码解决方法以及相关配置
- 有意识领导力承诺12:一切都是足够的
- Java后端学习路线分享
- Django学习记录10——Django使用支付宝付款(电脑支付,手机网页支付,面对面扫码)