上一篇博客中已经将所有的场景视频的特征提取出来了,下面介绍一下如何将相似的场景视频聚类到一起。
代码实现:1、读取h5特征文件:
def H5Filepocess():
h5_file_path_dir = '/opt/data/private/xuyunyang/EasyCut/' + args.ID + '/' + args.ID_VideoName + '/SceneFeature'
dirs = os.listdir(h5_file_path_dir)
for file in dirs:
h5_file_path = h5_file_path_dir + '/' + file
h5 = h5py.File(h5_file_path, 'r')
data = h5['video_1']['features'][...]
h5FileName_feature[h5_file_path] = data
2、相似度对比:
思路是对于每一个视频,计算与除自己外的所有其他视频的相似度,相似度计算使用余弦相似度方法,设定相似度阈值为0.95,大于阈值的视频就被添加到列表中,该列表之后作为字典结构的值存在,键则为对应的目标视频路径。
def CalculateDistance(path):
distance = dict()
A = h5FileName_feature[path]
a = A
a = np.average(A, axis=0) # 按列求均值
for i in h5FileName_feature.keys():
if i == path:
continue
B = h5FileName_feature[i]
b = B
b = np.average(B, axis=0)
# cosin相似度(余弦相似度)方法:把图片表示成一个向量,通过计算向量之间的余弦距离来表征两张图片的相似度。
a_norm = np.linalg.norm(a)
b_norm = np.linalg.norm(b)
cosin = np.dot(a, b) / (a_norm * b_norm)
distance[i.split('.')[0]+'.mp4'] = cosin
# distance=sorted(distance.items(),key=lambda x:x[1],reverse=True) #从大到小排序
# 筛选出相似度大于0.95的
distance1 = {k: v for k, v in distance.items() if v >= 0.95}
result_list = list(distance1.keys())
return result_list
3、以字典结构存储结果:
def generate_result():
H5Filepocess()
# print(h5FileName_feature)
for key in h5FileName_feature.keys():
result_dict[key.split('.')[0]+'.mp4'] = CalculateDistance(key)
# print('key:',key)
# print('reasult_dic_list:',result_dict[key])
4、将结果保存为json文件:
result_json = json.dumps(result_dict)
with open(
'/opt/data/private/xuyunyang/EasyCut/' + args.ID + '/' + args.ID_VideoName + '/SceneSimilar/' + args.ID_VideoName+'_scene_clustering.json',
'w') as f:
f.write(result_json)
print('END ALL')
完整代码如下:
import json
import numpy as np
import os
import h5py
import argparse
parser = argparse.ArgumentParser("Compute scene similarity of videos and generate a clusterd result")
parser.add_argument('--ID', type=str)
parser.add_argument('--ID_VideoName', type=str)
args = parser.parse_args()
h5FileName_feature = dict()
result_dict = dict()
def H5Filepocess():
h5_file_path_dir = '/opt/data/private/xuyunyang/EasyCut/' + args.ID + '/' + args.ID_VideoName + '/SceneFeature'
dirs = os.listdir(h5_file_path_dir)
for file in dirs:
h5_file_path = h5_file_path_dir + '/' + file
h5 = h5py.File(h5_file_path, 'r')
data = h5['video_1']['features'][...]
h5FileName_feature[h5_file_path] = data
def CalculateDistance(path):
distance = dict()
A = h5FileName_feature[path]
a = A
a = np.average(A, axis=0) # 按列求均值
for i in h5FileName_feature.keys():
if i == path:
continue
B = h5FileName_feature[i]
b = B
b = np.average(B, axis=0)
# cosin相似度(余弦相似度)方法:把图片表示成一个向量,通过计算向量之间的余弦距离来表征两张图片的相似度。
a_norm = np.linalg.norm(a)
b_norm = np.linalg.norm(b)
cosin = np.dot(a, b) / (a_norm * b_norm)
distance[i.split('.')[0]+'.mp4'] = cosin
# distance=sorted(distance.items(),key=lambda x:x[1],reverse=True) #从大到小排序
# 筛选出相似度大于0.95的
distance1 = {k: v for k, v in distance.items() if v >= 0.95}
result_list = list(distance1.keys())
return result_list
def generate_result():
H5Filepocess()
# print(h5FileName_feature)
for key in h5FileName_feature.keys():
result_dict[key.split('.')[0]+'.mp4'] = CalculateDistance(key)
# print('key:',key)
# print('reasult_dic_list:',result_dict[key])
if __name__ == '__main__':
generate_result()
result_json = json.dumps(result_dict)
with open(
'/opt/data/private/xuyunyang/EasyCut/' + args.ID + '/' + args.ID_VideoName + '/SceneSimilar/' + args.ID_VideoName+'_scene_clustering.json',
'w') as f:
f.write(result_json)
print('END ALL')



