c++ - 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:抱歉不能运行,有点乱,我是从三个不同的插件里复制过来的。
解决方案
从评论来看,
Tensorflow C API 需要对 RGB 图像进行交错处理。这意味着首先需要切换 X 轴和 Z 轴(此处为第一个通道和颜色通道,为 (3x512x512) 图像),然后创建具有正常尺寸的张量(此处为 (512x512x3))(从 Mathematicus 转述)
推荐阅读
- c# - TreeView - 节点未扩展
- python - 在python中查找顶级父母的所有孩子
- javascript - 按两个最近的字段对 js 数组进行排序
- sql - SQL使用通配符在带有where子句的字符串中查找字段
- javascript - 动态创建的选择框不接受功能添加的选项
- concourse - VAULT_CLIENT_TOKEN 每 24 小时过期一次
- css - 覆盖像 MuiTab 这样使用媒体查询的组件
- arrays - 将字符串数组中名称的第一个字符提取到另一个数组中
- javascript - 如何将一个字符串附加到另一个具有多行并由反斜杠字符终止的字符串
- jquery - jQuery UI datepicker:限制每个月的最后 5 天