Official Analyzer for LiveDet Iris 2020 competition

This algorithm is a sequential one. The platform will call its process() method once per data incoming on its inputs.
This algorithm is an analyzer. It can only be used on analysis blocks.

Algorithms have at least one input and one output. All algorithm endpoints are organized in groups. Groups are used by the platform to indicate which inputs and outputs are synchronized together. The first group is automatically synchronized with the channel defined by the block in which the algorithm is deployed.

Group: main

Endpoint Name Data Format Nature
scores system/integer/1 Input
category system/integer/1 Input

Analyzers may produce any number of results. Once experiments using this analyzer are done, you may display the results or filter experiments using criteria based on them.

Name Type
rocAll plot/isoroc/1
numberCorrectT5Samples int32
totalNumberT1Samples int32
totalNumberT5Samples int32
totalNumberT3Samples int32
numberNotProcessedT4Samples int32
totalNumberT6Samples int32
totalNumberT2Samples int32
numberCorrectT3Samples int32
rocT1T3 plot/isoroc/1
ACER float32
numberNotProcessedT5Samples int32
rocT1T2 plot/isoroc/1
numberNotProcessedT6Samples int32
numberNotProcessedT3Samples int32
numberCorrectT6Samples int32
numberCorrectT2Samples int32
rocT1T6 plot/isoroc/1
numberCorrectT4Samples int32
numberNotProcessedT2Samples int32
totalNumberT4Samples int32
numberCorrectT1Samples int32
rocT1T4 plot/isoroc/1
numberNotProcessedT1Samples int32
rocT1T5 plot/isoroc/1
xxxxxxxxxx
235
 
1
import numpy as np
2
import bob.measure
3
4
5
class Algorithm:
6
    def __init__(self):
7
        self.T1 = None
8
        self.T2 = None
9
        self.T3 = None
10
        self.T4 = None
11
        self.T5 = None
12
        self.T6 = None
13
        self.allspoofs = None
14
        self.correct_T1 = []
15
        self.correct_T2 = []
16
        self.correct_T3 = []
17
        self.correct_T4 = []
18
        self.correct_T5 = []
19
        self.correct_T6 = []
20
        self.incorrect_T1 = []
21
        self.incorrect_T2 = []
22
        self.incorrect_T3 = []
23
        self.incorrect_T4 = []
24
        self.incorrect_T5 = []
25
        self.incorrect_T6 = []
26
        self.notprocessed_T1 = []
27
        self.notprocessed_T2 = []
28
        self.notprocessed_T3 = []
29
        self.notprocessed_T4 = []
30
        self.notprocessed_T5 = []
31
        self.notprocessed_T6 = []
32
        self.acer = None
33
        self.n_bins = 50
34
        self.threshold = 50
35
36
    def process(self, inputs, data_loaders, outputs):
37
        # accumulate the test scores
38
        data_test = inputs["scores"].data.value
39
        label_test = inputs["category"].data.value
40
41
        if label_test == 1:
42
            if data_test < 0 or data_test > 100:
43
                self.notprocessed_T1.append(data_test)
44
            elif data_test > self.threshold:
45
                self.correct_T1.append(data_test)
46
            else:
47
                self.incorrect_T1.append(data_test)
48
        elif label_test == 2:
49
            if data_test < 0 or data_test > 100:
50
                self.notprocessed_T2.append(data_test)
51
            elif data_test <= self.threshold:
52
                self.correct_T2.append(data_test)
53
            else:
54
                self.incorrect_T2.append(data_test)
55
        elif label_test == 3:
56
            if data_test < 0 or data_test > 100:
57
                self.notprocessed_T3.append(data_test)
58
            elif data_test <= self.threshold:
59
                self.correct_T3.append(data_test)
60
            else:
61
                self.incorrect_T3.append(data_test)
62
        elif label_test == 4:
63
            if data_test < 0 or data_test > 100:
64
                self.notprocessed_T4.append(data_test)
65
            elif data_test <= self.threshold:
66
                self.correct_T4.append(data_test)
67
            else:
68
                self.incorrect_T4.append(data_test)
69
        elif label_test == 5:
70
            if data_test < 0 or data_test > 100:
71
                self.notprocessed_T5.append(data_test)
72
            elif data_test <= self.threshold:
73
                self.correct_T5.append(data_test)
74
            else:
75
                self.incorrect_T5.append(data_test)
76
        elif label_test == 6:
77
            if data_test < 0 or data_test > 100:
78
                self.notprocessed_T6.append(data_test)
79
            elif data_test <= self.threshold:
80
                self.correct_T6.append(data_test)
81
            else:
82
                self.incorrect_T6.append(data_test)
83
84
        # once all values are received, evaluate the scores
85
        if not (inputs.hasMoreData()):
86
            self.T1 = np.array(self.correct_T1 + self.incorrect_T1)
87
            self.T2 = np.array(self.correct_T2 + self.incorrect_T2)
88
            self.T3 = np.array(self.correct_T3 + self.incorrect_T3)
89
            self.T4 = np.array(self.correct_T4 + self.incorrect_T4)
90
            self.T5 = np.array(self.correct_T5 + self.incorrect_T5)
91
            self.T6 = np.array(self.correct_T6 + self.incorrect_T6)
92
            self.allspoofs = np.array(
93
                self.correct_T2
94
                + self.incorrect_T2
95
                + self.correct_T3
96
                + self.incorrect_T3
97
                + self.correct_T4
98
                + self.incorrect_T4
99
                + self.correct_T5
100
                + self.incorrect_T5
101
                + self.correct_T6
102
                + self.incorrect_T6
103
            )
104
105
            apcer = np.float32(
106
                len(
107
                    self.incorrect_T2
108
                    + self.incorrect_T3
109
                    + self.incorrect_T4
110
                    + self.incorrect_T5
111
                    + self.incorrect_T6
112
                )
113
                / len(self.allspoofs)
114
            )
115
            bpcer = np.float32(len(self.incorrect_T1) / len(self.T1))
116
            self.acer = np.float32((apcer + bpcer) / 2)
117
118
            # test_hist_pos, test_bin_pos = np.histogram(self.lives, self.n_bins)
119
            # test_hist_neg, test_bin_neg = np.histogram(self.spoofs, self.n_bins)
120
121
            # eer_threshold = bob.measure.eer_threshold(self.spoofs.astype(np.double), self.lives.astype(np.double))
122
            # far_test, frr_test = bob.measure.farfrr(self.negatives_test, self.lives, eer_threshold)
123
124
            rocAll = bob.measure.roc(
125
                self.T1.astype(np.double), self.allspoofs.astype(np.double), 100
126
            )
127
            rocT1T2 = bob.measure.roc(
128
                self.T1.astype(np.double), self.T2.astype(np.double), 100
129
            )
130
            rocT1T3 = bob.measure.roc(
131
                self.T1.astype(np.double), self.T3.astype(np.double), 100
132
            )
133
            rocT1T4 = bob.measure.roc(
134
                self.T1.astype(np.double), self.T4.astype(np.double), 100
135
            )
136
            rocT1T5 = bob.measure.roc(
137
                self.T1.astype(np.double), self.T5.astype(np.double), 100
138
            )
139
            rocT1T6 = bob.measure.roc(
140
                self.T1.astype(np.double), self.T6.astype(np.double), 100
141
            )
142
143
            # writes the output back to the platform
144
            outputs.write(
145
                {
146
                    "totalNumberT1Samples": np.int32(len(self.T1)),
147
                    "totalNumberT2Samples": np.int32(len(self.T2)),
148
                    "totalNumberT3Samples": np.int32(len(self.T3)),
149
                    "totalNumberT4Samples": np.int32(len(self.T4)),
150
                    "totalNumberT5Samples": np.int32(len(self.T5)),
151
                    "totalNumberT6Samples": np.int32(len(self.T6)),
152
                    "numberCorrectT1Samples": np.int32(len(self.correct_T1)),
153
                    "numberCorrectT2Samples": np.int32(len(self.correct_T2)),
154
                    "numberCorrectT3Samples": np.int32(len(self.correct_T3)),
155
                    "numberCorrectT4Samples": np.int32(len(self.correct_T4)),
156
                    "numberCorrectT5Samples": np.int32(len(self.correct_T5)),
157
                    "numberCorrectT6Samples": np.int32(len(self.correct_T6)),
158
                    "numberNotProcessedT1Samples": np.int32(len(self.notprocessed_T1)),
159
                    "numberNotProcessedT2Samples": np.int32(len(self.notprocessed_T2)),
160
                    "numberNotProcessedT3Samples": np.int32(len(self.notprocessed_T3)),
161
                    "numberNotProcessedT4Samples": np.int32(len(self.notprocessed_T4)),
162
                    "numberNotProcessedT5Samples": np.int32(len(self.notprocessed_T5)),
163
                    "numberNotProcessedT6Samples": np.int32(len(self.notprocessed_T6)),
164
                    "ACER": np.float32(self.acer),
165
                    "rocAll": {
166
                        "data": [
167
                            {
168
                                "label": "rocAll",
169
                                "false_positives": rocAll[1],
170
                                "false_negatives": rocAll[0],
171
                                "number_of_positives": np.uint64(len(self.T1)),
172
                                "number_of_negatives": np.uint64(len(self.allspoofs)),
173
                            }
174
                        ]
175
                    },
176
                    "rocT1T2": {
177
                        "data": [
178
                            {
179
                                "label": "rocT1T2",
180
                                "false_positives": rocT1T2[1],
181
                                "false_negatives": rocT1T2[0],
182
                                "number_of_positives": np.uint64(len(self.T1)),
183
                                "number_of_negatives": np.uint64(len(self.T2)),
184
                            }
185
                        ]
186
                    },
187
                    "rocT1T3": {
188
                        "data": [
189
                            {
190
                                "label": "rocT1T3",
191
                                "false_positives": rocT1T3[1],
192
                                "false_negatives": rocT1T3[0],
193
                                "number_of_positives": np.uint64(len(self.T1)),
194
                                "number_of_negatives": np.uint64(len(self.T3)),
195
                            }
196
                        ]
197
                    },
198
                    "rocT1T4": {
199
                        "data": [
200
                            {
201
                                "label": "rocT1T4",
202
                                "false_positives": rocT1T4[1],
203
                                "false_negatives": rocT1T4[0],
204
                                "number_of_positives": np.uint64(len(self.T1)),
205
                                "number_of_negatives": np.uint64(len(self.T4)),
206
                            }
207
                        ]
208
                    },
209
                    "rocT1T5": {
210
                        "data": [
211
                            {
212
                                "label": "rocT1T5",
213
                                "false_positives": rocT1T5[1],
214
                                "false_negatives": rocT1T5[0],
215
                                "number_of_positives": np.uint64(len(self.T1)),
216
                                "number_of_negatives": np.uint64(len(self.T5)),
217
                            }
218
                        ]
219
                    },
220
                    "rocT1T6": {
221
                        "data": [
222
                            {
223
                                "label": "rocT1T6",
224
                                "false_positives": rocT1T6[1],
225
                                "false_negatives": rocT1T6[0],
226
                                "number_of_positives": np.uint64(len(self.T1)),
227
                                "number_of_negatives": np.uint64(len(self.T6)),
228
                            }
229
                        ]
230
                    },
231
                }
232
            )
233
234
        return True
235

The code for this algorithm in Python
The ruler at 80 columns indicate suggested POSIX line breaks (for readability).
The editor will automatically enlarge to accomodate the entirety of your input
Use keyboard shortcuts for search/replace and faster editing. For example, use Ctrl-F (PC) or Cmd-F (Mac) to search through this box

Could not find any documentation for this object.

Experiments

Updated Name Databases/Protocols Analyzers
amohammadi/amohammadi/livdet/1/livdet livdet-iris-2020/1@Main amohammadi/livdet_analyzer/1
Created with Raphaël 2.1.2[compare]zfang/livdet_analyzer/1amohammadi/livdet_analyzer/12020Jul13

This table shows the number of times this algorithm has been successfully run using the given environment. Note this does not provide sufficient information to evaluate if the algorithm will run when submitted to different conditions.

Terms of Service | Contact Information | BEAT platform version 2.2.1b0 | © Idiap Research Institute - 2013-2025