首页 > 解决方案 > Tensorflow C API 为 RGB 图像返回错误的结果

问题描述

我正在尝试为 C++ 插件环境实现 Tensorflow C API,但分割结果与 Python 图不同。有人告诉我,它可能需要对 float/uint8 进行正确的转换,因为生成的图像看起来有点像正确图像的 3x3 网格,但作为 C/C++ 的新手,我看不出到底在哪里错误是。它适用于简单的分类任务,例如 MNIST 或灰度输入分割,但不适用于 RGB 图像的分割任务。

我们使用自己的环境进行图像表示,但它相当于 OpenCV Mat。我将图像转换为这样的张量:

void* tensor_data = image->Buffer().Ptr();

int64_t dims4[]={1,512,512,3};
int ndims = 4;

std::shared_ptr<TF_Tensor> tensor = TF_NewTensor(
    TF_FLOAT, dims4, ndims, tensor_data, 3*512*512*sizeof(float) , noDealloc, nullptr
);

因此,如果错误地读取了 RGB 数据,可能会出现错误。但我尝试分割具有相同通道的图像,即 3D 灰度图像,但它仍然不起作用。

然后我运行模型,一切都应该正确,因为它适用于某些任务,除非 Tensorflow 出现错误。

//********* Read model
TF_Graph* Graph = TF_NewGraph();
TF_Status* Status = TF_NewStatus();

TF_SessionOptions* SessionOpts = TF_NewSessionOptions();
TF_Buffer* RunOpts = NULL;
const char* saved_model_dir = m_path.c_str(); // Path of the model
const char* tags = "serve"; // default model serving tag; can change in future
int ntags = 1;

TF_Session* Session = TF_LoadSessionFromSavedModel(SessionOpts, RunOpts, saved_model_dir, &tags, ntags, Graph, NULL, Status);
tf_utils::throw_status(Status);

//****** Get input tensor operation
int NumInputs = 1;
TF_Output* Input = (TF_Output*)malloc(sizeof(TF_Output) * NumInputs);
const std::string in_param_name = "input_op:" + std::to_string(0);
const std::string in_op_name = m_params.GetString(in_param_name.c_str(), "").c_str();

TF_Output t0 = {TF_GraphOperationByName(Graph, in_op_name.c_str()), 0};
if(t0.oper == NULL){
    printf("ERROR: Failed TF_GraphOperationByName Input\n");
}
Input[0] = t0;

//********* Get Output tensor operation
int NumOutputs = 1;
TF_Output* Output = (TF_Output*)malloc(sizeof(TF_Output) * NumOutputs);
const std::string out_param_name = "output_op:" + std::to_string(0);
const std::string out_op_name = m_params.GetString(out_param_name.c_str(), "").c_str();

TF_Output t2 = {TF_GraphOperationByName(Graph, out_op_name.c_str()), 0};
if(t2.oper == NULL){
    printf("ERROR: Failed TF_GraphOperationByName Output\n");
}

Output[0] = t2;

//********* Allocate data for inputs & outputs
TF_Tensor** InputValues = (TF_Tensor**)malloc(sizeof(TF_Tensor*)*NumInputs);
TF_Tensor** OutputValues = (TF_Tensor**)malloc(sizeof(TF_Tensor*)*NumOutputs);

InputValues[0] = tensor.get();

// //Run the Session
 TF_SessionRun(Session, NULL, Input, InputValues, NumInputs, Output, OutputValues, NumOutputs, NULL, 0,NULL , Status);
 tf_utils::throw_status(Status);

 // //Free memory
 TF_DeleteGraph(Graph);
 TF_DeleteSession(Session, Status);
 TF_DeleteSessionOptions(SessionOpts);
 TF_DeleteStatus(Status);
 std::shared_ptr<TF_Tensor> out_tensor(OutputValues[0], TF_DeleteTensor);

然后我将它转换回图像,我认为错误可能是:

const TF_DataType tensor_type = TF_TensorType(out_tensor.get());
itwm_type = &ITWM::IMAGE_GREY_F; //Float image
// Create the image and copy the buffer.
const float* data = reinterpret_cast<float*>(TF_TensorData(out_tensor.get()));
const std::size_t byte_size = TF_TensorByteSize(out_tensor.get());
const std::size_t size = byte_size/sizeof(float);
ITWM::CImage* image = new ITWM::CImage(*itwm_type, ITWM::CSize(size));
memcpy(image->Buffer().Ptr(), data, byte_size);

我尝试将其转换为不同的格式,但错误相同或结果为 NaN。我还尝试将输入更改为三个灰度图像并将它们堆叠在一起,但它仍然不起作用。如果您能帮我找出错误,我将不胜感激!

PS:抱歉不能运行,有点乱,我是从三个不同的插件里复制过来的。

标签: c++ctensorflowc-api

解决方案


从评论来看,

Tensorflow C API 需要对 RGB 图像进行交错处理。这意味着首先需要切换 X 轴和 Z 轴(此处为第一个通道和颜色通道,为 (3x512x512) 图像),然后创建具有正常尺寸的张量(此处为 (512x512x3))(从 Mathematicus 转述)


推荐阅读