| 28 | |
| 29 | template <class T> |
| 30 | void resize(T* out, uint8_t* in, int image_height, int image_width, |
| 31 | int image_channels, int wanted_height, int wanted_width, |
| 32 | int wanted_channels, Settings* s) { |
| 33 | int number_of_pixels = image_height * image_width * image_channels; |
| 34 | std::unique_ptr<Interpreter> interpreter(new Interpreter); |
| 35 | |
| 36 | int base_index = 0; |
| 37 | |
| 38 | // two inputs: input and new_sizes |
| 39 | interpreter->AddTensors(2, &base_index); |
| 40 | // one output |
| 41 | interpreter->AddTensors(1, &base_index); |
| 42 | // set input and output tensors |
| 43 | interpreter->SetInputs({0, 1}); |
| 44 | interpreter->SetOutputs({2}); |
| 45 | |
| 46 | // set parameters of tensors |
| 47 | TfLiteQuantizationParams quant; |
| 48 | interpreter->SetTensorParametersReadWrite( |
| 49 | 0, kTfLiteFloat32, "input", |
| 50 | {1, image_height, image_width, image_channels}, quant); |
| 51 | interpreter->SetTensorParametersReadWrite(1, kTfLiteInt32, "new_size", {2}, |
| 52 | quant); |
| 53 | interpreter->SetTensorParametersReadWrite( |
| 54 | 2, kTfLiteFloat32, "output", |
| 55 | {1, wanted_height, wanted_width, wanted_channels}, quant); |
| 56 | |
| 57 | ops::builtin::BuiltinOpResolver resolver; |
| 58 | const TfLiteRegistration* resize_op = |
| 59 | resolver.FindOp(BuiltinOperator_RESIZE_BILINEAR, 1); |
| 60 | auto* params = reinterpret_cast<TfLiteResizeBilinearParams*>( |
| 61 | malloc(sizeof(TfLiteResizeBilinearParams))); |
| 62 | params->align_corners = false; |
| 63 | interpreter->AddNodeWithParameters({0, 1}, {2}, nullptr, 0, params, resize_op, |
| 64 | nullptr); |
| 65 | |
| 66 | interpreter->AllocateTensors(); |
| 67 | |
| 68 | // fill input image |
| 69 | // in[] are integers, cannot do memcpy() directly |
| 70 | auto input = interpreter->typed_tensor<float>(0); |
| 71 | for (int i = 0; i < number_of_pixels; i++) { |
| 72 | input[i] = in[i]; |
| 73 | } |
| 74 | |
| 75 | // fill new_sizes |
| 76 | interpreter->typed_tensor<int>(1)[0] = wanted_height; |
| 77 | interpreter->typed_tensor<int>(1)[1] = wanted_width; |
| 78 | |
| 79 | interpreter->Invoke(); |
| 80 | |
| 81 | auto output = interpreter->typed_tensor<float>(2); |
| 82 | auto output_number_of_pixels = wanted_height * wanted_width * wanted_channels; |
| 83 | |
| 84 | for (int i = 0; i < output_number_of_pixels; i++) { |
| 85 | if (s->input_floating) |
| 86 | out[i] = (output[i] - s->input_mean) / s->input_std; |
| 87 | else |
no test coverage detected