<jupyter_start><jupyter_text>Custom data generator for loading video data for action recognition<jupyter_code>import pandas as pd
import cv2
import numpy as np
from sklearn.utils import shuffle
import os
from collections import deque
import copy
import matplotlib
import matplotlib.pyplot as plt
from keras.utils import np_utils
from config import Config
%matplotlib inline<jupyter_output><empty_output><jupyter_text>A helper function for loading the samples in the format of[[[frame1_filename,frame2_filename,…],label1], [[frame1_filename,frame2_filename,…],label2],……….]<jupyter_code># reading the video files from the csv file
def file_generator(data_path,data_files,temporal_stride=1,temporal_length=16):
    '''
    data_files - list of csv files to be read.
    '''
    for f in data_files: # read all the csv files (one csv file corresponds to one vdieo) in data_files one by one
        tmp_df = pd.read_csv(os.path.join(data_path,f))
        label_list = list(tmp_df['Label'])  # Load all the labels in the label_list
        total_images = len(label_list) 
        if total_images>=temporal_length: # only if the number of frames in the video is greater tha temporal length, use that video
            num_samples = int((total_images-temporal_length)/temporal_stride)+1
            print ('num of samples from vid seq-{}: {}'.format(f,num_samples))
            img_list = list(tmp_df['FileName'])
        else: # if the number of frames are less than temporal length , discard it
            print ('num of frames is less than temporal length; hence discarding this file-{}'.format(f))
            continue

        start_frame = 0
        samples = deque() # initliaze a queue to store the frames 
        samp_count=0 # a counter to count the number of smaple. one smaple has as many frames as defined by temporal length
        for img in img_list:
            samples.append(img)
            if len(samples)==temporal_length: #if the queue has as many frames as temporal length, return it as one sample
                samples_c=copy.deepcopy(samples) # copy the queue as in the next stage frames would be popped
                samp_count+=1
                for t in range(temporal_stride): # pop out as many frames as described by the stride from the left to accomodate new frames
                    samples.popleft()
                yield samples_c,label_list[0] # return a sample(consisting of as many frames as defined by temporal length) 
                                                # and its corsponding label<jupyter_output><empty_output><jupyter_text>A load function for loading the samples in the format of[[[frame1_filename,frame2_filename,…],label1], [[frame1_filename,frame2_filename,…],label2],……….]<jupyter_code># Load the samples and their corresponding label for each video
def load_samples(data_cat='train',temporal_stride=1,temporal_length=16):
    data_path = os.path.join('data_files',data_cat)
    data_files = os.listdir(data_path)
    # define a generator to read the samples
    file_gen = file_generator(data_path,data_files,temporal_stride,temporal_length)
    iterator = True
    data_list = []
    while iterator:
        try:
            x,y = next(file_gen)
            x=list(x)
            data_list.append([x,y])
        except Exception as e:
            print ('the exception: ',e)
            iterator = False
            print ('end of data generator')
    return data_list<jupyter_output><empty_output><jupyter_text>load the train data<jupyter_code>train_data = load_samples(data_cat='train',temporal_stride=4,temporal_length=16)
print ('Total number of train samples:',len(train_data))
train_data[0]
train_data[5000:5002]<jupyter_output><empty_output><jupyter_text>Load the test data<jupyter_code>test_data = load_samples(data_cat='test',temporal_stride=4)
len(test_data)<jupyter_output><empty_output><jupyter_text>Shuffle the dataset<jupyter_code>def shuffle_data(samples):
    data = shuffle(samples,random_state=2)
    return data
def preprocess_image(img):
    img = cv2.resize(img,(224,224))
    img = img/255
    return img
def data_generator(data,batch_size=10,temporal_padding='same',shuffle=True):              
    """
    Yields the next training batch.
    data is an array [[img1_filename,img2_filename...,img16_filename],label1], [image2_filename,label2],...].
    """
    num_samples = len(data)
    if shuffle:
        data = shuffle_data(data)
    while True:   
        for offset in range(0, num_samples, batch_size):
            print ('startring index: ', offset) 
            # Get the samples you'll use in this batch
            batch_samples = data[offset:offset+batch_size]
            # Initialise X_train and y_train arrays for this batch
            X_train = []
            y_train = []
            # For each example
            for batch_sample in batch_samples: # Loop over every batch
                # Load image (X)
                x = batch_sample[0]
                y = batch_sample[1]
                temp_data_list = []
                for img in x:
                    try:
                        img = cv2.imread(img)
                        #apply any kind of preprocessing here
                        #img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
                        img = preprocess_image(img)
                        temp_data_list.append(img)

                    except Exception as e:
                        print (e)
                        print ('error reading file: ',img)                      
                # Read label (y)
                #label = label_names[y]
                # Add example to arrays
                X_train.append(temp_data_list)
                y_train.append(y)
    
            # Make sure they're numpy arrays (as opposed to lists)
            X_train = np.array(X_train)
            #X_train = np.rollaxis(X_train,1,4)
            y_train = np.array(y_train)
            # convert to one hot encoding for training keras model
            y_train = np_utils.to_categorical(y_train, 3)
    
            # yield the next training batch            
            yield X_train, y_train<jupyter_output><empty_output><jupyter_text>create a generator object with training data<jupyter_code>train_generator = data_generator(train_data,batch_size=4,shuffle=True)
    
x,y = next(train_generator)
print ('x shape: ',x.shape)
print ('y shape: ',y.shape)
y<jupyter_output><empty_output><jupyter_text>Let's visualize the first sample<jupyter_code>x_0=x[2]
y_0=y[2]
print('x_0 shape: ',x_0.shape)
print('y_0 shape: ',y_0.shape)
Config.labels_to_class
activity = Config.labels_to_class[np.argmax(y_0)]
activity<jupyter_output><empty_output><jupyter_text>Plot the first sample<jupyter_code>num_of_images=16
fig=plt.figure(figsize=(8,8))	
plt.title("one sample with {} frames ; activity:{}".format(num_of_images,activity))
subplot_num = int(np.ceil(np.sqrt(num_of_images)))
for i in range(int(num_of_images)):
    ax = fig.add_subplot(subplot_num, subplot_num, i+1)
    #ax.imshow(output_image[0,:,:,i],interpolation='nearest' ) #to see the first filter
    ax.imshow(x_0[i,:,:,::-1])
    plt.xticks([])
    plt.yticks([])
    plt.tight_layout()
plt.show()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.09287496534516218, 'fraction_numerical': 0.011782644857222068, 'mean_word_length': 2.8727858293075683, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 38, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '15941', 'license': 'MIT', 'n_tokens_mistral': 2252, 'n_tokens_neox': 2152, 'n_words': 578, 'path': 'activity_recognition/data_gen.ipynb', 'repo_name': 'JonahYeoh/custom_data_generator', 'size': '7214'}