视频数据集UCF101的处理与加载

这篇文章是对UCF101视频数据集处理以及加载的一个记录,也适用于其他的视频数据集。

 

二 UCF101数据集

简单介绍一下UCF101数据集。

  • 内含13320 个短视频
  • 视频来源:YouTube
  • 视频类别:101 种
  • 主要包括这5大类动作 :人和物体交互,只有肢体动作,人与人交互,玩音乐器材,各类运动

......

三 具体实现思路

1 数据集准备

  1. 下载UCF101数据集UCF101.zip并解压;
  2. 下载标注文件及训练数据和测试数据的列表文件The Train/Test Splits for Action Recognition on UCF101 data set:
    内含:


以上两个文件都在UCF数据集官网可以下载。

 

2 预处理

  • 参考代码:two-stream-action-recognition
  • 预处理主要分为讲视频分解为帧,统计每个视频的帧数这两个步骤。
  • 这两部分的代码在以上的参考文件中给出了,去下载video_jpg_ucf101_hmdb51.py以及n_frames_ucf101_hmdb51.py源码即可。

这里说明一下怎么使用以及执行结果:

  1. 将UCF101中的视频保持结构不变逐帧视频分解为图像。
    python utils_fyq/video_jpg_ucf101_hmdb51.py /home/hl/Desktop/lovelyqian/CV_Learning/UCF101 /home/hl/Desktop/lovelyqian/CV_Learning/UCF101_jpg
    将UCF101中的视频保持结构不变都逐帧视频分解为图像,每个视频帧数目都不一样,150帧左右,图片大小都是320*240。

  2. 实现每个视频的帧数(图像数量)统计。
    python utils_fyq/n_frames_ucf101_hmdb51.py /home/hl/Desktop/lovelyqian/CV_Learning/UCF101_jpg
    执行结果是每个视频帧文件夹内都有一个n_frames.txt文件,记录该视频帧的数目。

3 后续处理

定义了UCF101类,具体目标:

  • train_x: [batch_size,16,3,160,160]
  • test_x : [batch_size,16,3,160,160]
  • 每个视频取随机取16个连续帧
  • 图片为3通道,大小随机取(160,160)
  • 总共101类,所以label值为:0-100
  • train_y: [batch_size] 返回对应的label值;
  • test_y_label: [batch_size] 根据视频名称返回对应的label,用于与预测值进行对比。
  • classNames[101]: index表示label, value表示具体的类别,例如classNames[0]='ApplyEyeMakeup`

 

......

使用方法

    myUCF101=UCF101()

   # get classNames
    className=myUCF101.get_className()

    # train
    batch_num=myUCF101.set_mode('train')
    for batch_index in range(batch_num):
        train_x,train_y=myUCF101[batch_index]
        print (train_x,train_y)
        print ("train batch:",batch_index)
    
    #TEST
    batch_num=myUCF101.set_mode('test')
    for batch_index in range(batch_num):
        test_x,test_y_label=myUCF101[batch_index]
        print test_x,test_y_label
        print ("test batch: " ,batch_index)

 

 

 

完整代码


from PIL import Image
import random
from skimage import io, color, exposure
from skimage.transform import resize
import os
import numpy as np
import pandas as pd
import torch


class UCF101:
    def __init__(self,mode='train'):
        self.videos_path='/home/hl/Desktop/lovelyqian/CV_Learning/UCF101_jpg'
        self.csv_dir_path='/home/hl/Desktop/lovelyqian/CV_Learning/UCF101_TrainTestlist/'
        self.label_csv_path = os.path.join(self.csv_dir_path, 'classInd.txt')
        # self.batch_size=128
        self.batch_size=8
        self.mode= mode

        self.get_train()
        self.get_test()

        
    def get_className(self):
        data = pd.read_csv(self.label_csv_path, delimiter=' ', header=None)
        labels = []
        # labels.append("0")
        for i in range(data.shape[0]):
            labels.append(data.ix[i, 1])
        return labels

    def get_train(self):
        train_x_path = []
        train_y = []
        for index in range(1,4):
            tmp_path='trainlist0'+str(index)+'.txt'
            train_csv_path = os.path.join(self.csv_dir_path, tmp_path)
            # print (train_csv_path)

            data = pd.read_csv(train_csv_path, delimiter=' ', header=None)
            for i in range(data.shape[0]):
                train_x_path.append(data.ix[i,0])
                # train_y.append(data.ix[i,1])
                train_y.append(data.ix[i,1]-1)
    
        self.train_num=len(train_x_path)
        self.train_x_path=train_x_path
        self.train_y=train_y
        return train_x_path,train_y


    def get_test(self):
        test_x_path=[]
        test_y_label=[]
        for index in range(1,4):
            temp_path='testlist0'+str(index)+'.txt'
            test_csv_path=os.path.join(self.csv_dir_path,temp_path)
            # print (test_csv_path)

            data=pd.read_csv(test_csv_path,delimiter=' ',header=None)
            for i in range(data.shape[0]):
                test_x_path.append(data.ix[i,0])
                label=self.get_label(data.ix[i,0])
                test_y_label.append(label)
        self.test_num=len(test_x_path)
        self.test_x_path=test_x_path
        self.test_y_label=test_y_label
        return test_x_path,test_y_label


    def get_label(self,video_path):
        slash_rows = video_path.split('/')
        class_name = slash_rows[0]
        return class_name
    

    def get_single_image(self,image_path):
        image=resize(io.imread(image_path),output_shape=(160,160),preserve_range= True)    #240,320,3--160,160,3
        # io.imshow(image.astype(np.uint8))
        # io.show()
        image =image.transpose(2, 0, 1)              #3,160,160
        return torch.from_numpy(image)               #range[0,255]

    def get_single_video_x(self,train_x_path):
        slash_rows=train_x_path.split('.')
        dir_name=slash_rows[0]
        video_jpgs_path=os.path.join(self.videos_path,dir_name)
        ##get the random 16 frame
        data=pd.read_csv(os.path.join(video_jpgs_path,'n_frames'),delimiter=' ',header=None)
        frame_count=data[0][0]
        train_x=torch.Tensor(16,3,160,160)

        image_start=random.randint(1,frame_count-17)
        image_id=image_start
        for i in range(16):
            s="%05d" % image_id
            image_name='image_'+s+'.jpg'
            image_path=os.path.join(video_jpgs_path,image_name)
            single_image=self.get_single_image(image_path)
            train_x[i,:,:,:]=single_image
            image_id+=1
        return train_x

    
    def get_minibatches_index(self, shuffle=True):
        """
        :param n: len of data
        :param minibatch_size: minibatch size of data
        :param shuffle: shuffle the data
        :return: len of minibatches and minibatches
        """
        if self.mode=='train':
            n=self.train_num
        elif self.mode=='test':
            n=self.test_num

        minibatch_size=self.batch_size
        
        index_list = np.arange(n, dtype="int32")
 
        # shuffle
        if shuffle:
            random.shuffle(index_list)
 
        # segment
        minibatches = []
        minibatch_start = 0
        for i in range(n // minibatch_size):
            minibatches.append(index_list[minibatch_start:minibatch_start + minibatch_size])
            minibatch_start += minibatch_size
 
        # processing the last batch
        if (minibatch_start != n):
            minibatches.append(index_list[minibatch_start:])
        
        if self.mode=='train':
            self.minibatches_train=minibatches
        elif self.mode=='test':
            self.minibatches_test=minibatches
        return 


    
    def __getitem__(self, index):
        if self.mode=='train':
            batches=self.minibatches_train[index]
            N=batches.shape[0]
            train_x=torch.Tensor(N,16,3,160,160)
            train_y=torch.Tensor(N)
            for i in range (N):
                tmp_index=batches[i]
                tmp_video_path=self.train_x_path[tmp_index]
                tmp_train_x= self.get_single_video_x(tmp_video_path)
                tmp_train_y=self.train_y[tmp_index]
                train_x[i,:,:,:]=tmp_train_x
                train_y[i]=tmp_train_y
            train_x=train_x.permute(0,2,1,3,4)
            return train_x,train_y
        elif self.mode=='test':
            batches=self.minibatches_test[index]
            N=batches.shape[0]
            test_x=torch.Tensor(N,16,3,160,160)
            test_y_label=[]
            for i in range (N):
                tmp_index=batches[i]
                tmp_video_path=self.test_x_path[tmp_index]
                tmp_test_x= self.get_single_video_x(tmp_video_path)
                tmp_test_y=self.test_y_label[tmp_index]
                test_x[i,:,:,:]=tmp_test_x
                test_y_label.append(tmp_test_y)
            test_x=test_x.permute(0,2,1,3,4)
            return test_x,test_y_label
    
    def set_mode(self,mode):
        self.mode=mode
        if mode=='train':
            self.get_minibatches_index()
            return self.train_num // self.batch_size
        elif mode=='test':
            self.get_minibatches_index()
            return self.test_num // self.batch_size





##  usage 

if __name__=="__main__":
    myUCF101=UCF101()
   
    className=myUCF101.get_className()


    
    # train
    batch_num=myUCF101.set_mode('train')
    for batch_index in range(batch_num):
        train_x,train_y=myUCF101[batch_index]
        print (train_x,train_y)
        print ("train batch:",batch_index)
    
    #TEST
    batch_num=myUCF101.set_mode('test')
    for batch_index in range(batch_num):
        test_x,test_y_label=myUCF101[batch_index]
        print test_x,test_y_label
        print ("test batch: " ,batch_index)

 

 

 

 

你可能感兴趣的:(Deep,Learning)