1 /* Copyright 2019 The TensorFlow Authors. All Rights Reserved.
2
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6
7 http://www.apache.org/licenses/LICENSE-2.0
8
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ==============================================================================*/
15
16 #include "flatbuffers/flexbuffers.h"
17 #include "tensorflow/lite/c/builtin_op_data.h"
18 #include "tensorflow/lite/c/common.h"
19 #include "tensorflow/lite/micro/kernels/kernel_runner.h"
20 #include "tensorflow/lite/micro/test_helpers.h"
21 #include "tensorflow/lite/micro/testing/micro_test.h"
22
23 // See: tensorflow/lite/micro/kernels/detection_postprocess_test/README.md
24 #include "tensorflow/lite/micro/kernels/flexbuffers_generated_data.h"
25
26 namespace tflite {
27 namespace testing {
28 namespace {
29
30 // Common inputs and outputs.
31
32 static constexpr int kInputShape1[] = {3, 1, 6, 4};
33 static constexpr int kInputShape2[] = {3, 1, 6, 3};
34 static constexpr int kInputShape3[] = {2, 6, 4};
35 static constexpr int kOutputShape1[] = {3, 1, 3, 4};
36 static constexpr int kOutputShape2[] = {2, 1, 3};
37 static constexpr int kOutputShape3[] = {2, 1, 3};
38 static constexpr int kOutputShape4[] = {1, 1};
39
40 // six boxes in center-size encoding
41 static constexpr float kInputData1[] = {
42 0.0, 0.0, 0.0, 0.0, // box #1
43 0.0, 1.0, 0.0, 0.0, // box #2
44 0.0, -1.0, 0.0, 0.0, // box #3
45 0.0, 0.0, 0.0, 0.0, // box #4
46 0.0, 1.0, 0.0, 0.0, // box #5
47 0.0, 0.0, 0.0, 0.0 // box #6
48 };
49
50 // class scores - two classes with background
51 static constexpr float kInputData2[] = {0., .9, .8, 0., .75, .72, 0., .6, .5,
52 0., .93, .95, 0., .5, .4, 0., .3, .2};
53
54 // six anchors in center-size encoding
55 static constexpr float kInputData3[] = {
56 0.5, 0.5, 1.0, 1.0, // anchor #1
57 0.5, 0.5, 1.0, 1.0, // anchor #2
58 0.5, 0.5, 1.0, 1.0, // anchor #3
59 0.5, 10.5, 1.0, 1.0, // anchor #4
60 0.5, 10.5, 1.0, 1.0, // anchor #5
61 0.5, 100.5, 1.0, 1.0 // anchor #6
62 };
63 // Same boxes in box-corner encoding:
64 // { 0.0, 0.0, 1.0, 1.0,
65 // 0.0, 0.1, 1.0, 1.1,
66 // 0.0, -0.1, 1.0, 0.9,
67 // 0.0, 10.0, 1.0, 11.0,
68 // 0.0, 10.1, 1.0, 11.1,
69 // 0.0, 100.0, 1.0, 101.0}
70
71 static constexpr float kGolden1[] = {0.0, 10.0, 1.0, 11.0, 0.0, 0.0,
72 1.0, 1.0, 0.0, 100.0, 1.0, 101.0};
73 static constexpr float kGolden2[] = {1, 0, 0};
74 static constexpr float kGolden3[] = {0.95, 0.9, 0.3};
75 static constexpr float kGolden4[] = {3.0};
76
TestDetectionPostprocess(const int * input_dims_data1,const float * input_data1,const int * input_dims_data2,const float * input_data2,const int * input_dims_data3,const float * input_data3,const int * output_dims_data1,float * output_data1,const int * output_dims_data2,float * output_data2,const int * output_dims_data3,float * output_data3,const int * output_dims_data4,float * output_data4,const float * golden1,const float * golden2,const float * golden3,const float * golden4,const float tolerance,bool use_regular_nms,uint8_t * input_data_quantized1=nullptr,uint8_t * input_data_quantized2=nullptr,uint8_t * input_data_quantized3=nullptr,const float input_min1=0,const float input_max1=0,const float input_min2=0,const float input_max2=0,const float input_min3=0,const float input_max3=0)77 void TestDetectionPostprocess(
78 const int* input_dims_data1, const float* input_data1,
79 const int* input_dims_data2, const float* input_data2,
80 const int* input_dims_data3, const float* input_data3,
81 const int* output_dims_data1, float* output_data1,
82 const int* output_dims_data2, float* output_data2,
83 const int* output_dims_data3, float* output_data3,
84 const int* output_dims_data4, float* output_data4, const float* golden1,
85 const float* golden2, const float* golden3, const float* golden4,
86 const float tolerance, bool use_regular_nms,
87 uint8_t* input_data_quantized1 = nullptr,
88 uint8_t* input_data_quantized2 = nullptr,
89 uint8_t* input_data_quantized3 = nullptr, const float input_min1 = 0,
90 const float input_max1 = 0, const float input_min2 = 0,
91 const float input_max2 = 0, const float input_min3 = 0,
92 const float input_max3 = 0) {
93 TfLiteIntArray* input_dims1 = IntArrayFromInts(input_dims_data1);
94 TfLiteIntArray* input_dims2 = IntArrayFromInts(input_dims_data2);
95 TfLiteIntArray* input_dims3 = IntArrayFromInts(input_dims_data3);
96 TfLiteIntArray* output_dims1 = nullptr;
97 TfLiteIntArray* output_dims2 = nullptr;
98 TfLiteIntArray* output_dims3 = nullptr;
99 TfLiteIntArray* output_dims4 = nullptr;
100
101 const int zero_length_int_array_data[] = {0};
102 TfLiteIntArray* zero_length_int_array =
103 IntArrayFromInts(zero_length_int_array_data);
104
105 output_dims1 = output_dims_data1 == nullptr
106 ? const_cast<TfLiteIntArray*>(zero_length_int_array)
107 : IntArrayFromInts(output_dims_data1);
108 output_dims2 = output_dims_data2 == nullptr
109 ? const_cast<TfLiteIntArray*>(zero_length_int_array)
110 : IntArrayFromInts(output_dims_data2);
111 output_dims3 = output_dims_data3 == nullptr
112 ? const_cast<TfLiteIntArray*>(zero_length_int_array)
113 : IntArrayFromInts(output_dims_data3);
114 output_dims4 = output_dims_data4 == nullptr
115 ? const_cast<TfLiteIntArray*>(zero_length_int_array)
116 : IntArrayFromInts(output_dims_data4);
117
118 constexpr int inputs_size = 3;
119 constexpr int outputs_size = 4;
120 constexpr int tensors_size = inputs_size + outputs_size;
121
122 TfLiteTensor tensors[tensors_size];
123 if (input_min1 != 0 || input_max1 != 0 || input_min2 != 0 ||
124 input_max2 != 0 || input_min3 != 0 || input_max3 != 0) {
125 const float input_scale1 = ScaleFromMinMax<uint8_t>(input_min1, input_max1);
126 const int input_zero_point1 =
127 ZeroPointFromMinMax<uint8_t>(input_min1, input_max1);
128 const float input_scale2 = ScaleFromMinMax<uint8_t>(input_min2, input_max2);
129 const int input_zero_point2 =
130 ZeroPointFromMinMax<uint8_t>(input_min2, input_max2);
131 const float input_scale3 = ScaleFromMinMax<uint8_t>(input_min3, input_max3);
132 const int input_zero_point3 =
133 ZeroPointFromMinMax<uint8_t>(input_min3, input_max3);
134
135 tensors[0] =
136 CreateQuantizedTensor(input_data1, input_data_quantized1, input_dims1,
137 input_scale1, input_zero_point1);
138 tensors[1] =
139 CreateQuantizedTensor(input_data2, input_data_quantized2, input_dims2,
140 input_scale2, input_zero_point2);
141 tensors[2] =
142 CreateQuantizedTensor(input_data3, input_data_quantized3, input_dims3,
143 input_scale3, input_zero_point3);
144 } else {
145 tensors[0] = CreateTensor(input_data1, input_dims1);
146 tensors[1] = CreateTensor(input_data2, input_dims2);
147 tensors[2] = CreateTensor(input_data3, input_dims3);
148 }
149 tensors[3] = CreateTensor(output_data1, output_dims1);
150 tensors[4] = CreateTensor(output_data2, output_dims2);
151 tensors[5] = CreateTensor(output_data3, output_dims3);
152 tensors[6] = CreateTensor(output_data4, output_dims4);
153
154 ::tflite::AllOpsResolver resolver;
155 const TfLiteRegistration* registration =
156 resolver.FindOp("TFLite_Detection_PostProcess");
157 TF_LITE_MICRO_EXPECT_NE(nullptr, registration);
158
159 int inputs_array_data[] = {3, 0, 1, 2};
160 TfLiteIntArray* inputs_array = IntArrayFromInts(inputs_array_data);
161 int outputs_array_data[] = {4, 3, 4, 5, 6};
162 TfLiteIntArray* outputs_array = IntArrayFromInts(outputs_array_data);
163
164 micro::KernelRunner runner(*registration, tensors, tensors_size, inputs_array,
165 outputs_array, nullptr);
166
167 // Using generated data as input to operator.
168 int data_size = 0;
169 const unsigned char* init_data = nullptr;
170 if (use_regular_nms) {
171 init_data = g_gen_data_regular_nms;
172 data_size = g_gen_data_size_regular_nms;
173 } else {
174 init_data = g_gen_data_none_regular_nms;
175 data_size = g_gen_data_size_none_regular_nms;
176 }
177
178 // TfLite uses a char* for the raw bytes whereas flexbuffers use an unsigned
179 // char*. This small discrepancy results in compiler warnings unless we
180 // reinterpret_cast right before passing in the flexbuffer bytes to the
181 // KernelRunner.
182 TF_LITE_MICRO_EXPECT_EQ(
183 kTfLiteOk, runner.InitAndPrepare(reinterpret_cast<const char*>(init_data),
184 data_size));
185
186 // Output dimensions should not be undefined after Prepare
187 TF_LITE_MICRO_EXPECT_NE(nullptr, tensors[3].dims);
188 TF_LITE_MICRO_EXPECT_NE(nullptr, tensors[4].dims);
189 TF_LITE_MICRO_EXPECT_NE(nullptr, tensors[5].dims);
190 TF_LITE_MICRO_EXPECT_NE(nullptr, tensors[6].dims);
191
192 TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.Invoke());
193
194 const int output_elements_count1 = tensors[3].dims->size;
195 const int output_elements_count2 = tensors[4].dims->size;
196 const int output_elements_count3 = tensors[5].dims->size;
197 const int output_elements_count4 = tensors[6].dims->size;
198
199 for (int i = 0; i < output_elements_count1; ++i) {
200 TF_LITE_MICRO_EXPECT_NEAR(golden1[i], output_data1[i], tolerance);
201 }
202 for (int i = 0; i < output_elements_count2; ++i) {
203 TF_LITE_MICRO_EXPECT_NEAR(golden2[i], output_data2[i], tolerance);
204 }
205 for (int i = 0; i < output_elements_count3; ++i) {
206 TF_LITE_MICRO_EXPECT_NEAR(golden3[i], output_data3[i], tolerance);
207 }
208 for (int i = 0; i < output_elements_count4; ++i) {
209 TF_LITE_MICRO_EXPECT_NEAR(golden4[i], output_data4[i], tolerance);
210 }
211 }
212 } // namespace
213 } // namespace testing
214 } // namespace tflite
215
216 TF_LITE_MICRO_TESTS_BEGIN
217
TF_LITE_MICRO_TEST(DetectionPostprocessFloatFastNMS)218 TF_LITE_MICRO_TEST(DetectionPostprocessFloatFastNMS) {
219 float output_data1[12];
220 float output_data2[3];
221 float output_data3[3];
222 float output_data4[1];
223
224 tflite::testing::TestDetectionPostprocess(
225 tflite::testing::kInputShape1, tflite::testing::kInputData1,
226 tflite::testing::kInputShape2, tflite::testing::kInputData2,
227 tflite::testing::kInputShape3, tflite::testing::kInputData3,
228 tflite::testing::kOutputShape1, output_data1,
229 tflite::testing::kOutputShape2, output_data2,
230 tflite::testing::kOutputShape3, output_data3,
231 tflite::testing::kOutputShape4, output_data4, tflite::testing::kGolden1,
232 tflite::testing::kGolden2, tflite::testing::kGolden3,
233 tflite::testing::kGolden4,
234 /* tolerance */ 0, /* Use regular NMS: */ false);
235 }
236
TF_LITE_MICRO_TEST(DetectionPostprocessQuantizedFastNMS)237 TF_LITE_MICRO_TEST(DetectionPostprocessQuantizedFastNMS) {
238 float output_data1[12];
239 float output_data2[3];
240 float output_data3[3];
241 float output_data4[1];
242 const int kInputElements1 = tflite::testing::kInputShape1[1] *
243 tflite::testing::kInputShape1[2] *
244 tflite::testing::kInputShape1[3];
245 const int kInputElements2 = tflite::testing::kInputShape2[1] *
246 tflite::testing::kInputShape2[2] *
247 tflite::testing::kInputShape2[3];
248 const int kInputElements3 =
249 tflite::testing::kInputShape3[1] * tflite::testing::kInputShape3[2];
250
251 uint8_t input_data_quantized1[kInputElements1 + 10];
252 uint8_t input_data_quantized2[kInputElements2 + 10];
253 uint8_t input_data_quantized3[kInputElements3 + 10];
254
255 tflite::testing::TestDetectionPostprocess(
256 tflite::testing::kInputShape1, tflite::testing::kInputData1,
257 tflite::testing::kInputShape2, tflite::testing::kInputData2,
258 tflite::testing::kInputShape3, tflite::testing::kInputData3,
259 tflite::testing::kOutputShape1, output_data1,
260 tflite::testing::kOutputShape2, output_data2,
261 tflite::testing::kOutputShape3, output_data3,
262 tflite::testing::kOutputShape4, output_data4, tflite::testing::kGolden1,
263 tflite::testing::kGolden2, tflite::testing::kGolden3,
264 tflite::testing::kGolden4,
265 /* tolerance */ 3e-1, /* Use regular NMS: */ false, input_data_quantized1,
266 input_data_quantized2, input_data_quantized3,
267 /* input1 min/max*/ -1.0, 1.0, /* input2 min/max */ 0.0, 1.0,
268 /* input3 min/max */ 0.0, 100.5);
269 }
270
TF_LITE_MICRO_TEST(DetectionPostprocessFloatRegularNMS)271 TF_LITE_MICRO_TEST(DetectionPostprocessFloatRegularNMS) {
272 float output_data1[12];
273 float output_data2[3];
274 float output_data3[3];
275 float output_data4[1];
276 const float kGolden1[] = {0.0, 10.0, 1.0, 11.0, 0.0, 10.0,
277 1.0, 11.0, 0.0, 0.0, 0.0, 0.0};
278 const float kGolden3[] = {0.95, 0.9, 0.0};
279 const float kGolden4[] = {2.0};
280
281 tflite::testing::TestDetectionPostprocess(
282 tflite::testing::kInputShape1, tflite::testing::kInputData1,
283 tflite::testing::kInputShape2, tflite::testing::kInputData2,
284 tflite::testing::kInputShape3, tflite::testing::kInputData3,
285 tflite::testing::kOutputShape1, output_data1,
286 tflite::testing::kOutputShape2, output_data2,
287 tflite::testing::kOutputShape3, output_data3,
288 tflite::testing::kOutputShape4, output_data4, kGolden1,
289 tflite::testing::kGolden2, kGolden3, kGolden4,
290 /* tolerance */ 1e-1, /* Use regular NMS: */ true);
291 }
292
TF_LITE_MICRO_TEST(DetectionPostprocessQuantizedRegularNMS)293 TF_LITE_MICRO_TEST(DetectionPostprocessQuantizedRegularNMS) {
294 float output_data1[12];
295 float output_data2[3];
296 float output_data3[3];
297 float output_data4[1];
298 const int kInputElements1 = tflite::testing::kInputShape1[1] *
299 tflite::testing::kInputShape1[2] *
300 tflite::testing::kInputShape1[3];
301 const int kInputElements2 = tflite::testing::kInputShape2[1] *
302 tflite::testing::kInputShape2[2] *
303 tflite::testing::kInputShape2[3];
304 const int kInputElements3 =
305 tflite::testing::kInputShape3[1] * tflite::testing::kInputShape3[2];
306
307 uint8_t input_data_quantized1[kInputElements1 + 10];
308 uint8_t input_data_quantized2[kInputElements2 + 10];
309 uint8_t input_data_quantized3[kInputElements3 + 10];
310
311 const float kGolden1[] = {0.0, 10.0, 1.0, 11.0, 0.0, 10.0,
312 1.0, 11.0, 0.0, 0.0, 0.0, 0.0};
313 const float kGolden3[] = {0.95, 0.9, 0.0};
314 const float kGolden4[] = {2.0};
315
316 tflite::testing::TestDetectionPostprocess(
317 tflite::testing::kInputShape1, tflite::testing::kInputData1,
318 tflite::testing::kInputShape2, tflite::testing::kInputData2,
319 tflite::testing::kInputShape3, tflite::testing::kInputData3,
320 tflite::testing::kOutputShape1, output_data1,
321 tflite::testing::kOutputShape2, output_data2,
322 tflite::testing::kOutputShape3, output_data3,
323 tflite::testing::kOutputShape4, output_data4, kGolden1,
324 tflite::testing::kGolden2, kGolden3, kGolden4,
325 /* tolerance */ 3e-1, /* Use regular NMS: */ true, input_data_quantized1,
326 input_data_quantized2, input_data_quantized3,
327 /* input1 min/max*/ -1.0, 1.0, /* input2 min/max */ 0.0, 1.0,
328 /* input3 min/max */ 0.0, 100.5);
329 }
330
TF_LITE_MICRO_TEST(DetectionPostprocessFloatFastNMSwithNoBackgroundClassAndKeypoints)331 TF_LITE_MICRO_TEST(
332 DetectionPostprocessFloatFastNMSwithNoBackgroundClassAndKeypoints) {
333 const int kInputShape1[] = {3, 1, 6, 5};
334 const int kInputShape2[] = {3, 1, 6, 2};
335
336 // six boxes in center-size encoding
337 const float kInputData1[] = {
338 0.0, 0.0, 0.0, 0.0, 1.0, // box #1
339 0.0, 1.0, 0.0, 0.0, 1.0, // box #2
340 0.0, -1.0, 0.0, 0.0, 1.0, // box #3
341 0.0, 0.0, 0.0, 0.0, 1.0, // box #4
342 0.0, 1.0, 0.0, 0.0, 1.0, // box #5
343 0.0, 0.0, 0.0, 0.0, 1.0, // box #6
344 };
345
346 // class scores - two classes without background
347 const float kInputData2[] = {.9, .8, .75, .72, .6, .5,
348 .93, .95, .5, .4, .3, .2};
349
350 float output_data1[12];
351 float output_data2[3];
352 float output_data3[3];
353 float output_data4[1];
354
355 tflite::testing::TestDetectionPostprocess(
356 kInputShape1, kInputData1, kInputShape2, kInputData2,
357 tflite::testing::kInputShape3, tflite::testing::kInputData3,
358 tflite::testing::kOutputShape1, output_data1,
359 tflite::testing::kOutputShape2, output_data2,
360 tflite::testing::kOutputShape3, output_data3,
361 tflite::testing::kOutputShape4, output_data4, tflite::testing::kGolden1,
362 tflite::testing::kGolden2, tflite::testing::kGolden3,
363 tflite::testing::kGolden4,
364 /* tolerance */ 0, /* Use regular NMS: */ false);
365 }
366
TF_LITE_MICRO_TEST(DetectionPostprocessFloatRegularNMSwithNoBackgroundClassAndKeypoints)367 TF_LITE_MICRO_TEST(
368 DetectionPostprocessFloatRegularNMSwithNoBackgroundClassAndKeypoints) {
369 const int kInputShape2[] = {3, 1, 6, 2};
370
371 // class scores - two classes without background
372 const float kInputData2[] = {.9, .8, .75, .72, .6, .5,
373 .93, .95, .5, .4, .3, .2};
374
375 const float kGolden1[] = {0.0, 10.0, 1.0, 11.0, 0.0, 10.0,
376 1.0, 11.0, 0.0, 0.0, 0.0, 0.0};
377 const float kGolden3[] = {0.95, 0.9, 0.0};
378 const float kGolden4[] = {2.0};
379
380 float output_data1[12];
381 float output_data2[3];
382 float output_data3[3];
383 float output_data4[1];
384
385 tflite::testing::TestDetectionPostprocess(
386 tflite::testing::kInputShape1, tflite::testing::kInputData1, kInputShape2,
387 kInputData2, tflite::testing::kInputShape3, tflite::testing::kInputData3,
388 tflite::testing::kOutputShape1, output_data1,
389 tflite::testing::kOutputShape2, output_data2,
390 tflite::testing::kOutputShape3, output_data3,
391 tflite::testing::kOutputShape4, output_data4, kGolden1,
392 tflite::testing::kGolden2, kGolden3, kGolden4,
393 /* tolerance */ 1e-1, /* Use regular NMS: */ true);
394 }
395
TF_LITE_MICRO_TEST(DetectionPostprocessFloatFastNMSWithBackgroundClassAndKeypoints)396 TF_LITE_MICRO_TEST(
397 DetectionPostprocessFloatFastNMSWithBackgroundClassAndKeypoints) {
398 const int kInputShape1[] = {3, 1, 6, 5};
399
400 // six boxes in center-size encoding
401 const float kInputData1[] = {
402 0.0, 0.0, 0.0, 0.0, 1.0, // box #1
403 0.0, 1.0, 0.0, 0.0, 1.0, // box #2
404 0.0, -1.0, 0.0, 0.0, 1.0, // box #3
405 0.0, 0.0, 0.0, 0.0, 1.0, // box #4
406 0.0, 1.0, 0.0, 0.0, 1.0, // box #5
407 0.0, 0.0, 0.0, 0.0, 1.0, // box #6
408 };
409
410 float output_data1[12];
411 float output_data2[3];
412 float output_data3[3];
413 float output_data4[1];
414
415 tflite::testing::TestDetectionPostprocess(
416 kInputShape1, kInputData1, tflite::testing::kInputShape2,
417 tflite::testing::kInputData2, tflite::testing::kInputShape3,
418 tflite::testing::kInputData3, tflite::testing::kOutputShape1,
419 output_data1, tflite::testing::kOutputShape2, output_data2,
420 tflite::testing::kOutputShape3, output_data3,
421 tflite::testing::kOutputShape4, output_data4, tflite::testing::kGolden1,
422 tflite::testing::kGolden2, tflite::testing::kGolden3,
423 tflite::testing::kGolden4,
424 /* tolerance */ 0, /* Use regular NMS: */ false);
425 }
426
TF_LITE_MICRO_TEST(DetectionPostprocessQuantizedFastNMSwithNoBackgroundClassAndKeypoints)427 TF_LITE_MICRO_TEST(
428 DetectionPostprocessQuantizedFastNMSwithNoBackgroundClassAndKeypoints) {
429 const int kInputShape1[] = {3, 1, 6, 5};
430 const int kInputShape2[] = {3, 1, 6, 2};
431
432 // six boxes in center-size encoding
433 const float kInputData1[] = {
434 0.0, 0.0, 0.0, 0.0, 1.0, // box #1
435 0.0, 1.0, 0.0, 0.0, 1.0, // box #2
436 0.0, -1.0, 0.0, 0.0, 1.0, // box #3
437 0.0, 0.0, 0.0, 0.0, 1.0, // box #4
438 0.0, 1.0, 0.0, 0.0, 1.0, // box #5
439 0.0, 0.0, 0.0, 0.0, 1.0, // box #6
440 };
441
442 // class scores - two classes without background
443 const float kInputData2[] = {.9, .8, .75, .72, .6, .5,
444 .93, .95, .5, .4, .3, .2};
445
446 const int kInputElements1 = tflite::testing::kInputShape1[1] *
447 tflite::testing::kInputShape1[2] *
448 tflite::testing::kInputShape1[3];
449 const int kInputElements2 = tflite::testing::kInputShape2[1] *
450 tflite::testing::kInputShape2[2] *
451 tflite::testing::kInputShape2[3];
452 const int kInputElements3 =
453 tflite::testing::kInputShape3[1] * tflite::testing::kInputShape3[2];
454
455 uint8_t input_data_quantized1[kInputElements1 + 10];
456 uint8_t input_data_quantized2[kInputElements2 + 10];
457 uint8_t input_data_quantized3[kInputElements3 + 10];
458
459 float output_data1[12];
460 float output_data2[3];
461 float output_data3[3];
462 float output_data4[1];
463
464 tflite::testing::TestDetectionPostprocess(
465 kInputShape1, kInputData1, kInputShape2, kInputData2,
466 tflite::testing::kInputShape3, tflite::testing::kInputData3,
467 tflite::testing::kOutputShape1, output_data1,
468 tflite::testing::kOutputShape2, output_data2,
469 tflite::testing::kOutputShape3, output_data3,
470 tflite::testing::kOutputShape4, output_data4, tflite::testing::kGolden1,
471 tflite::testing::kGolden2, tflite::testing::kGolden3,
472 tflite::testing::kGolden4,
473 /* tolerance */ 3e-1, /* Use regular NMS: */ false, input_data_quantized1,
474 input_data_quantized2, input_data_quantized3,
475 /* input1 min/max*/ -1.0, 1.0, /* input2 min/max */ 0.0, 1.0,
476 /* input3 min/max */ 0.0, 100.5);
477 }
478
479 TF_LITE_MICRO_TESTS_END
480