To receive notifications about scheduled maintenance, please subscribe to the mailing-list gitlab-operations@sympa.ethz.ch. You can subscribe to the mailing-list at https://sympa.ethz.ch

utils.py 6.76 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
import numpy as np
from sklearn.metrics import classification_report, confusion_matrix
import seaborn as sn
import pandas as pd
import matplotlib.pyplot as plt

def index_of_id(id, start_indexes_of_videos):
    num_video = (id.split('_')[0])
    start_index = start_indexes_of_videos[num_video]
    time = float(id.split('_')[1])
    offset = round(time / (100 / 3))
    return int(start_index + offset)

def IoU(segment1, segment2, start_indexes_of_videos):
    first_segment = list(range(index_of_id(segment1[0], start_indexes_of_videos=start_indexes_of_videos), index_of_id(segment1[-1], start_indexes_of_videos=start_indexes_of_videos) + 1))
    second_segment = list(range(index_of_id(segment2[0], start_indexes_of_videos= start_indexes_of_videos), index_of_id(segment2[-1], start_indexes_of_videos= start_indexes_of_videos) + 1))
    intersection = np.intersect1d(first_segment, second_segment)
    if len(intersection) == 0:
        return 0
    union = np.union1d(first_segment, second_segment)
    return len(intersection) / len(union)


def non_maximum_suppresion_all_segments(segments, scores, threshold, path_to_sequences, start_indexes_of_videos):
    #segments = ID: video-num_start-time_segment-length
    #scores = int: max-score for segment [0:1]
    threshold_segments = []
    best_segments = []

    #Reduce segments to those with score >= threshold
    for i in range(len(segments)):
        if scores[i] >= threshold:
            threshold_segments.append(segments[i])

    #Add thershold segment only, if there is not intersection to other best-segments, starting with first threshold segment
    best_segments.append(threshold_segments[0])
    for i in range(len(threshold_segments)-1):
        sequence_current = np.load(path_to_sequences + "\\" + threshold_segments[i + 1] + ".npy", allow_pickle=True)
        segment_best_new = None
        for j in range(len(best_segments)):
            sequence_best_j = np.load(path_to_sequences + "\\" + best_segments[j] + ".npy", allow_pickle=True)
            if IoU(segment1= sequence_current, segment2= sequence_best_j, start_indexes_of_videos= start_indexes_of_videos) == 0:
                segment_best_new = threshold_segments[i+1]
        if segment_best_new != None:
            best_segments.append(segment_best_new)
    print('ratio threshold segments best segments:', len(threshold_segments)/len(best_segments)*100, '%')
    return best_segments

def non_maximum_suppresion_all_best_segments(segments, scores, path_to_sequences, start_indexes_of_videos):
    #segments = ID: video-num_start-time_segment-length
    #scores = int: max-score for segment [0:1]

    best_segments = []
    best_scores = []
    #Add thershold segment only, if there is not intersection to other best-segments, starting with first threshold segment
    best_segments.append(segments[0])
    best_scores.append(scores[0])
    for i in range(len(segments)-1):
        sequence_current = np.load(path_to_sequences + "\\" + segments[i + 1] + ".npy", allow_pickle=True)
        segment_best_new = None
        score_best_new = None
        for j in range(len(best_segments)):
            sequence_best_j = np.load(path_to_sequences + "\\" + best_segments[j] + ".npy", allow_pickle=True)
            if IoU(segment1= sequence_current, segment2= sequence_best_j, start_indexes_of_videos= start_indexes_of_videos) == 0:
                segment_best_new = segments[i+1]
                score_best_new = scores[i+1]

            #if there is a segment already in the best segments which has an intersection with proposed segment but lower score, it is replaced
            elif IoU(segment1= sequence_current, segment2= sequence_best_j, start_indexes_of_videos= start_indexes_of_videos) != 0 and scores[i+1] > best_scores[j]:
                best_scores[j] = scores[i+1]
                best_segments[j] = segments[i+1]
        if segment_best_new != None:
            best_segments.append(segment_best_new)
            best_scores.append(score_best_new)
    print('ratio threshold segments best segments:', len(best_segments/len(segments))*100, '%')

    return best_segments

def get_image_ids_from_segment(id, path_to_sequences, start_indexes_of_videos):
    segment = np.load(path_to_sequences + "\\" + id + ".npy", allow_pickle=True)
    indexes = list(range(index_of_id(segment[0], start_indexes_of_videos= start_indexes_of_videos), index_of_id(segment[-1], start_indexes_of_videos= start_indexes_of_videos) + 1))
    return indexes


def save_classification_report(t_labels, p_labels, activities, title_name, path, plot_name):
    labels = np.arange(4)
    target_names = activities
    clf_report = classification_report(t_labels,
                                       p_labels,
                                       labels=labels,
                                       target_names=target_names,
                                       output_dict=True)
    plt.title(title_name)
    fig = sn.heatmap(pd.DataFrame(clf_report).iloc[:-1, :].T, annot=True, cmap="RdBu", vmin=0, vmax=1)
    plt.xlabel("Metrics")
    plt.savefig(path + "\\" + plot_name + '.png', dpi=300, bbox_inches='tight')
    plt.clf()

    clf_report = classification_report(t_labels,
                                       p_labels,
                                       target_names=target_names)
    path = path + f"\\" + plot_name + f".txt"
    text_file = open(path, 'w')
    text_file.write(clf_report)
    text_file.close()


def print_performance(t_labels, p_labels, names):
    print('Confusion Matrix')
    print(confusion_matrix(t_labels, p_labels))
    print('Classification Report')
    print(classification_report(t_labels, p_labels, target_names=names))

def save_activity_confusion_matrix(t_labels, p_labels, activities, title_name, path, plot_name):
    matrix = confusion_matrix(t_labels, p_labels)
    #matrix = matrix / int(len(t_labels)) #23/11/20 NOT INTUITIVE TO DIVIDE BY TOTAL NUMBER OF PREDICTED SEGMENTS, Better: divide by represenations/class or absulute values
    plt.figure(figsize=(4, 4))
    plt.title(title_name)
    df_cm = pd.DataFrame(matrix, index=[i for i in activities],
                         columns=[i for i in activities])
    fig = sn.heatmap(df_cm, annot=True, cmap="Blues", vmin=0, vmax=1)
    plt.xlabel("Predicted label")
    plt.xticks(rotation=45)
    plt.ylabel("True Label")
    plt.savefig(path + "\\" + plot_name + '.png', dpi=300,
                bbox_inches='tight')
    plt.clf()

    df_conf = pd.DataFrame.from_dict(matrix)
    df_conf.to_csv(path + f"\\" + plot_name + f".csv")

def get_start_end_list_of_videos(list_of_ids):
    cur_id = '-1'
    indexes = []
    for i in range(len(list_of_ids)):
        id = list_of_ids[i].split('_')[0]
        if id != cur_id:
            indexes.append(i)
            cur_id = id
    indexes.append(len(list_of_ids)) #add last index to have the stop value of last video
    return indexes