@@ -477,49 +477,104 @@ __attribute__((unused)) int extract_image_features(signal_t *signal, matrix_t *o
477
477
478
478
int16_t channel_count = strcmp (config.channels , " Grayscale" ) == 0 ? 1 : 3 ;
479
479
480
- if (output_matrix->rows * output_matrix->cols != EI_CLASSIFIER_INPUT_WIDTH * EI_CLASSIFIER_INPUT_HEIGHT * channel_count) {
480
+ if (output_matrix->rows * output_matrix->cols != static_cast < uint32_t >( EI_CLASSIFIER_INPUT_WIDTH * EI_CLASSIFIER_INPUT_HEIGHT * channel_count) ) {
481
481
ei_printf (" out_matrix = %hu items\n " , output_matrix->rows , output_matrix->cols );
482
- ei_printf (" calculated size = %hu items\n " , EI_CLASSIFIER_INPUT_WIDTH * EI_CLASSIFIER_INPUT_HEIGHT * channel_count);
482
+ ei_printf (" calculated size = %hu items\n " , static_cast < uint32_t >( EI_CLASSIFIER_INPUT_WIDTH * EI_CLASSIFIER_INPUT_HEIGHT * channel_count) );
483
483
EIDSP_ERR (EIDSP_MATRIX_SIZE_MISMATCH);
484
484
}
485
485
486
486
size_t output_ix = 0 ;
487
487
488
488
// buffered read from the signal
489
489
size_t bytes_left = signal ->total_length ;
490
- for (size_t ix = 0 ; ix < signal ->total_length ; ix += 4096 ) {
491
- size_t bytes_to_read = bytes_left > 4096 ? 4096 : bytes_left;
490
+ for (size_t ix = 0 ; ix < signal ->total_length ; ix += 1024 ) {
491
+ size_t elements_to_read = bytes_left > 1024 ? 1024 : bytes_left;
492
492
493
- matrix_t input_matrix (bytes_to_read , config.axes );
493
+ matrix_t input_matrix (elements_to_read , config.axes );
494
494
if (!input_matrix.buffer ) {
495
495
EIDSP_ERR (EIDSP_OUT_OF_MEM);
496
496
}
497
- signal ->get_data (ix, bytes_to_read , input_matrix.buffer );
497
+ signal ->get_data (ix, elements_to_read , input_matrix.buffer );
498
498
499
- for (size_t jx = 0 ; jx < bytes_to_read ; jx++) {
499
+ for (size_t jx = 0 ; jx < elements_to_read ; jx++) {
500
500
uint32_t pixel = static_cast <uint32_t >(input_matrix.buffer [jx]);
501
+
502
+ // rgb to 0..1
503
+ float r = static_cast <float >(pixel >> 16 & 0xff ) / 255 .0f ;
504
+ float g = static_cast <float >(pixel >> 8 & 0xff ) / 255 .0f ;
505
+ float b = static_cast <float >(pixel & 0xff ) / 255 .0f ;
506
+
507
+ if (channel_count == 3 ) {
508
+ output_matrix->buffer [output_ix++] = r;
509
+ output_matrix->buffer [output_ix++] = g;
510
+ output_matrix->buffer [output_ix++] = b;
511
+ }
512
+ else {
513
+ // ITU-R 601-2 luma transform
514
+ // see: https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.convert
515
+ float v = (0 .299f * r) + (0 .587f * g) + (0 .114f * b);
516
+ output_matrix->buffer [output_ix++] = v;
517
+ }
518
+ }
519
+
520
+ bytes_left -= elements_to_read;
521
+ }
522
+
523
+ return EIDSP_OK;
524
+ }
525
+
526
+ #if EI_CLASSIFIER_TFLITE_INPUT_QUANTIZED == 1
527
+ __attribute__ ((unused)) int extract_image_features_quantized(signal_t *signal, matrix_i8_t *output_matrix, void *config_ptr) {
528
+ ei_dsp_config_image_t config = *((ei_dsp_config_image_t *)config_ptr);
529
+
530
+ int16_t channel_count = strcmp (config.channels , " Grayscale" ) == 0 ? 1 : 3 ;
531
+
532
+ if (output_matrix->rows * output_matrix->cols != static_cast <uint32_t >(EI_CLASSIFIER_INPUT_WIDTH * EI_CLASSIFIER_INPUT_HEIGHT * channel_count)) {
533
+ ei_printf (" out_matrix = %hu items\n " , output_matrix->rows , output_matrix->cols );
534
+ ei_printf (" calculated size = %hu items\n " , static_cast <uint32_t >(EI_CLASSIFIER_INPUT_WIDTH * EI_CLASSIFIER_INPUT_HEIGHT * channel_count));
535
+ EIDSP_ERR (EIDSP_MATRIX_SIZE_MISMATCH);
536
+ }
537
+
538
+ size_t output_ix = 0 ;
539
+
540
+ // buffered read from the signal
541
+ size_t bytes_left = signal ->total_length ;
542
+ for (size_t ix = 0 ; ix < signal ->total_length ; ix += 1024 ) {
543
+ size_t elements_to_read = bytes_left > 1024 ? 1024 : bytes_left;
544
+
545
+ matrix_t input_matrix (elements_to_read, config.axes );
546
+ if (!input_matrix.buffer ) {
547
+ EIDSP_ERR (EIDSP_OUT_OF_MEM);
548
+ }
549
+ signal ->get_data (ix, elements_to_read, input_matrix.buffer );
550
+
551
+ for (size_t jx = 0 ; jx < elements_to_read; jx++) {
552
+ uint32_t pixel = static_cast <uint32_t >(input_matrix.buffer [jx]);
553
+
554
+ // rgb to 0..1
555
+ float r = static_cast <float >(pixel >> 16 & 0xff ) / 255 .0f ;
556
+ float g = static_cast <float >(pixel >> 8 & 0xff ) / 255 .0f ;
557
+ float b = static_cast <float >(pixel & 0xff ) / 255 .0f ;
558
+
501
559
if (channel_count == 3 ) {
502
- // rgb to 0..1
503
- output_matrix->buffer [output_ix++] = static_cast <float >(pixel >> 16 & 0xff ) / 255 .0f ;
504
- output_matrix->buffer [output_ix++] = static_cast <float >(pixel >> 8 & 0xff ) / 255 .0f ;
505
- output_matrix->buffer [output_ix++] = static_cast <float >(pixel & 0xff ) / 255 .0f ;
560
+ output_matrix->buffer [output_ix++] = static_cast <int8_t >(round (r / EI_CLASSIFIER_TFLITE_INPUT_SCALE) + EI_CLASSIFIER_TFLITE_INPUT_ZEROPOINT);
561
+ output_matrix->buffer [output_ix++] = static_cast <int8_t >(round (g / EI_CLASSIFIER_TFLITE_INPUT_SCALE) + EI_CLASSIFIER_TFLITE_INPUT_ZEROPOINT);
562
+ output_matrix->buffer [output_ix++] = static_cast <int8_t >(round (b / EI_CLASSIFIER_TFLITE_INPUT_SCALE) + EI_CLASSIFIER_TFLITE_INPUT_ZEROPOINT);
506
563
}
507
564
else {
508
- // grayscale conversion (also to 0..1)
509
- float r = static_cast <float >(pixel >> 16 & 0xff ) / 255 .0f ;
510
- float g = static_cast <float >(pixel >> 8 & 0xff ) / 255 .0f ;
511
- float b = static_cast <float >(pixel & 0xff ) / 255 .0f ;
512
565
// ITU-R 601-2 luma transform
513
566
// see: https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.convert
514
- output_matrix->buffer [output_ix++] = (0 .299f * r) + (0 .587f * g) + (0 .114f * b);
567
+ float v = (0 .299f * r) + (0 .587f * g) + (0 .114f * b);
568
+ output_matrix->buffer [output_ix++] = static_cast <int8_t >(round (v / EI_CLASSIFIER_TFLITE_INPUT_SCALE) + EI_CLASSIFIER_TFLITE_INPUT_ZEROPOINT);
515
569
}
516
570
}
517
571
518
- bytes_left -= bytes_to_read ;
572
+ bytes_left -= elements_to_read ;
519
573
}
520
574
521
575
return EIDSP_OK;
522
576
}
577
+ #endif // EI_CLASSIFIER_TFLITE_INPUT_QUANTIZED == 1
523
578
524
579
#ifdef __cplusplus
525
580
}
0 commit comments