blob: 3b312301e167b76a6659fc2a491eb6ba1da98330 [file] [log] [blame]
/**
* Copyright (C) 2020-2021 Savoir-faire Linux Inc.
*
* Author: Aline Gondim Santos <aline.gondimsantos@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA.
*/
#include "pluginInference.h"
// Std libraries
#include "pluglog.h"
#include <cstring>
#include <numeric>
const char sep = separator();
const std::string TAG = "FORESEG";
namespace jami {
PluginInference::PluginInference(TFModel model)
: TensorflowInference(model)
{
#ifndef TFLITE
// Initialize TENSORFLOW_CC lib
static const char* kFakeName = "fake program name";
int argc = 1;
char* fake_name_copy = strdup(kFakeName);
char** argv = &fake_name_copy;
tensorflow::port::InitMain(kFakeName, &argc, &argv);
if (argc > 1) {
Plog::log(Plog::LogPriority::INFO, "TENSORFLOW INIT", "Unknown argument ");
}
free(fake_name_copy);
#endif // TFLITE
}
PluginInference::~PluginInference() {}
#ifdef TFLITE
std::pair<uint8_t*, std::vector<int>>
PluginInference::getInput()
{
// We assume that we have only one input
// Get the input index
int input = interpreter->inputs()[0];
uint8_t* inputDataPointer = interpreter->typed_tensor<uint8_t>(input);
// Get the input dimensions vector
std::vector<int> dims = getTensorDimensions(input);
return std::make_pair(inputDataPointer, dims);
}
// // Types returned by tensorflow
// int type = interpreter->tensor(outputIndex)->type
// typedef enum {
// kTfLiteNoType = 0,
// kTfLiteFloat32 = 1, float
// kTfLiteInt32 = 2, int // int32_t
// kTfLiteUInt8 = 3, uint8_t
// kTfLiteInt64 = 4, int64_t
// kTfLiteString = 5,
// kTfLiteBool = 6,
// kTfLiteInt16 = 7, int16_t
// kTfLiteComplex64 = 8,
// kTfLiteInt8 = 9, int8_t
// kTfLiteFloat16 = 10, float16_t
// } TfLiteType;
std::vector<float>
PluginInference::masksPredictions() const
{
int outputIndex = interpreter->outputs()[0];
std::vector<int> dims = getTensorDimensions(outputIndex);
int totalDimensions = 1;
for (size_t i = 0; i < dims.size(); i++) {
totalDimensions *= dims[i];
}
std::vector<float> out;
int type = interpreter->tensor(outputIndex)->type;
switch (type) {
case 1: {
float* outputDataPointer = interpreter->typed_tensor<float>(outputIndex);
std::vector<float> output(outputDataPointer, outputDataPointer + totalDimensions);
out = std::vector<float>(output.begin(), output.end());
break;
}
case 2: {
int* outputDataPointer = interpreter->typed_tensor<int>(outputIndex);
std::vector<int> output(outputDataPointer, outputDataPointer + totalDimensions);
out = std::vector<float>(output.begin(), output.end());
break;
}
case 4: {
int64_t* outputDataPointer = interpreter->typed_tensor<int64_t>(outputIndex);
std::vector<int64_t> output(outputDataPointer, outputDataPointer + totalDimensions);
out = std::vector<float>(output.begin(), output.end());
break;
}
}
return out;
}
void
PluginInference::setExpectedImageDimensions()
{
// We assume that we have only one input
// Get the input index
int input = interpreter->inputs()[0];
// Get the input dimensions vector
std::vector<int> dims = getTensorDimensions(input);
imageWidth = dims.at(1);
imageHeight = dims.at(2);
imageNbChannels = dims.at(3);
}
#else // TFLITE
// Given an image file name, read in the data, try to decode it as an image,
// resize it to the requested size, and then scale the values as desired.
void
PluginInference::ReadTensorFromMat(const cv::Mat& image)
{
imageTensor = tensorflow::Tensor(tensorflow::DataType::DT_FLOAT,
tensorflow::TensorShape({1, image.cols, image.rows, 3}));
float* p = imageTensor.flat<float>().data();
cv::Mat temp(image.rows, image.cols, CV_32FC3, p);
image.convertTo(temp, CV_32FC3);
}
std::vector<float>
PluginInference::masksPredictions() const
{
std::vector<int> dims;
int flatSize = 1;
int num_dimensions = outputs[0].shape().dims();
for (int ii_dim = 0; ii_dim < num_dimensions; ii_dim++) {
dims.push_back(outputs[0].shape().dim_size(ii_dim));
flatSize *= outputs[0].shape().dim_size(ii_dim);
}
std::vector<float> out;
int type = outputs[0].dtype();
switch (type) {
case tensorflow::DataType::DT_FLOAT: {
for (int offset = 0; offset < flatSize; offset++) {
out.push_back(outputs[0].flat<float>()(offset));
}
break;
}
case tensorflow::DataType::DT_INT32: {
for (int offset = 0; offset < flatSize; offset++) {
out.push_back(static_cast<float>(outputs[0].flat<tensorflow::int32>()(offset)));
}
break;
}
case tensorflow::DataType::DT_INT64: {
for (int offset = 0; offset < flatSize; offset++) {
out.push_back(static_cast<float>(outputs[0].flat<tensorflow::int64>()(offset)));
}
break;
}
default: {
for (int offset = 0; offset < flatSize; offset++) {
out.push_back(0);
}
break;
}
}
return out;
}
void
PluginInference::setExpectedImageDimensions()
{
if (tfModel.dims[1] != 0)
imageWidth = tfModel.dims[1];
if (tfModel.dims[2] != 0)
imageHeight = tfModel.dims[2];
if (tfModel.dims[3] != 0)
imageNbChannels = tfModel.dims[3];
}
#endif
int
PluginInference::getImageWidth() const
{
return imageWidth;
}
int
PluginInference::getImageHeight() const
{
return imageHeight;
}
int
PluginInference::getImageNbChannels() const
{
return imageNbChannels;
}
} // namespace jami