tensorflow c++中api,如何从张量中保存图片或数组
In tensorflow c++ api, how to save a picture or an array from a tensor
我正在尝试 运行 用于图像分割的已保存模型,使用 tf 1.5.0 c++ api。
我的模型得到一个大小为 1*256*256*3 的输入图像,并像这样输入一个张量:
for (int x = 0; x < 256; x++) {
for (int y = 0; y <256; y++) {
data_(0, x, y, 0) =
(float) image_out.at<cv::Vec3b>(x, y)[0];
data_(0, x, y, 1) =
(float) image_out.at<cv::Vec3b>(x, y)[1];
data_(0, x, y, 2) =
(float) image_out.at<cv::Vec3b>(x, y)[2];
}
}
然后我 运行 使用 sess->Run()
的模型,并得到输出:
input Tensor type: float shape: [1,224,224,3] values: [[[254 254
254]]]... Output Tensor type: float shape: [1,224,224,1] values:
[[[0.160249829][0.0639446825][0.0414313935]]]...
我想使用 cv::imwrite() 将输出保存到图像中。但是,不能直接保存张量。所以我试着像这样转换张量:tensorflow::tensor->eigen::mat->cv::mat。代码是:
auto m = Eigen::Map<Eigen::Matrix<
float, /* scalar element type */
Eigen::Dynamic, /* num_rows is a run-time value */
Eigen::Dynamic, /* num_cols is a run-time value */
Eigen::RowMajor /* tensorflow::Tensor is always row-major */
>>(
outputs[0].flat<float>().data(), /* ptr to data */
outputs[0].dim_size(1), /* num_rows */
outputs[0].dim_size(2) /* num_cols */);
//std::cout << "m " << m << std::endl;
cv::Mat rotMatrix;
cv::eigen2cv(m, rotMatrix);
这会在编译时引发错误:
note: template void cv::eigen2cv(const Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>&, cv::Mat&) void eigen2cv( const Eigen::Matrix<_Tp, _rows, _cols, _options, _maxRows,
_maxCols>& src, Mat& dst )
^ /usr/local/opencv3.1/include/opencv2/core/eigen.hpp:63:6: note: template argument deduction/substitution failed:
src/demo/demo.cpp:152:28: note:
\u2018Eigen::Map >\u2019 is not
derived from \u2018const Eigen::Matrix<_Scalar, _Rows, _Cols,
_Options, _MaxRows, _MaxCols>\u2019 cv::eigen2cv(m, rotMatrix);
^ In file included from src/demo/demo.cpp:11:0:
/usr/local/opencv3.1/include/opencv2/core/eigen.hpp:81:6: note:
template void cv::eigen2cv(const Eigen::Matrix<_Scalar, _Rows,
_Cols, _Options, _MaxRows, _MaxCols>&, cv::Matx<_Tp, m, n>&) void eigen2cv( const Eigen::Matrix<_Tp, _rows, _cols, _options, _maxRows,
_maxCols>& src,
^ /usr/local/opencv3.1/include/opencv2/core/eigen.hpp:81:6: note: template argument deduction/substitution failed:
src/demo/demo.cpp:152:28: note:
\u2018Eigen::Map >\u2019 is not
derived from \u2018const Eigen::Matrix<_Scalar, _Rows, _Cols,
_Options, _MaxRows, _MaxCols>\u2019 cv::eigen2cv(m, rotMatrix);
^ make: *** [obj/demo.o] Error 1
怎么了?
另一方面,我认为这不是从张量获取图片的好方法。翻了tf的c++ api文档,没找到好的方法。 https://www.tensorflow.org/api_docs/cc/class/tensorflow/tensor#classtensorflow_1_1_tensor_1a6afab48885080a80ff0b52437959d929
那么,有什么方便的方法吗?
我认为你可以通过这种方式直接用 OpenCV 矩阵头包装张量数据:
cv::Mat rotMatrix(outputs[0].dim_size(1), outputs[0].dim_size(2), CV_32FC1, outputs[0].flat<float>().data())
我正在尝试 运行 用于图像分割的已保存模型,使用 tf 1.5.0 c++ api。 我的模型得到一个大小为 1*256*256*3 的输入图像,并像这样输入一个张量:
for (int x = 0; x < 256; x++) {
for (int y = 0; y <256; y++) {
data_(0, x, y, 0) =
(float) image_out.at<cv::Vec3b>(x, y)[0];
data_(0, x, y, 1) =
(float) image_out.at<cv::Vec3b>(x, y)[1];
data_(0, x, y, 2) =
(float) image_out.at<cv::Vec3b>(x, y)[2];
}
}
然后我 运行 使用 sess->Run()
的模型,并得到输出:
input Tensor type: float shape: [1,224,224,3] values: [[[254 254 254]]]... Output Tensor type: float shape: [1,224,224,1] values: [[[0.160249829][0.0639446825][0.0414313935]]]...
我想使用 cv::imwrite() 将输出保存到图像中。但是,不能直接保存张量。所以我试着像这样转换张量:tensorflow::tensor->eigen::mat->cv::mat。代码是:
auto m = Eigen::Map<Eigen::Matrix<
float, /* scalar element type */
Eigen::Dynamic, /* num_rows is a run-time value */
Eigen::Dynamic, /* num_cols is a run-time value */
Eigen::RowMajor /* tensorflow::Tensor is always row-major */
>>(
outputs[0].flat<float>().data(), /* ptr to data */
outputs[0].dim_size(1), /* num_rows */
outputs[0].dim_size(2) /* num_cols */);
//std::cout << "m " << m << std::endl;
cv::Mat rotMatrix;
cv::eigen2cv(m, rotMatrix);
这会在编译时引发错误:
note: template void cv::eigen2cv(const Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>&, cv::Mat&) void eigen2cv( const Eigen::Matrix<_Tp, _rows, _cols, _options, _maxRows, _maxCols>& src, Mat& dst ) ^ /usr/local/opencv3.1/include/opencv2/core/eigen.hpp:63:6: note: template argument deduction/substitution failed: src/demo/demo.cpp:152:28: note:
\u2018Eigen::Map >\u2019 is not derived from \u2018const Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>\u2019 cv::eigen2cv(m, rotMatrix); ^ In file included from src/demo/demo.cpp:11:0: /usr/local/opencv3.1/include/opencv2/core/eigen.hpp:81:6: note: template void cv::eigen2cv(const Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>&, cv::Matx<_Tp, m, n>&) void eigen2cv( const Eigen::Matrix<_Tp, _rows, _cols, _options, _maxRows, _maxCols>& src, ^ /usr/local/opencv3.1/include/opencv2/core/eigen.hpp:81:6: note: template argument deduction/substitution failed: src/demo/demo.cpp:152:28: note:
\u2018Eigen::Map >\u2019 is not derived from \u2018const Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>\u2019 cv::eigen2cv(m, rotMatrix); ^ make: *** [obj/demo.o] Error 1
怎么了?
另一方面,我认为这不是从张量获取图片的好方法。翻了tf的c++ api文档,没找到好的方法。 https://www.tensorflow.org/api_docs/cc/class/tensorflow/tensor#classtensorflow_1_1_tensor_1a6afab48885080a80ff0b52437959d929
那么,有什么方便的方法吗?
我认为你可以通过这种方式直接用 OpenCV 矩阵头包装张量数据:
cv::Mat rotMatrix(outputs[0].dim_size(1), outputs[0].dim_size(2), CV_32FC1, outputs[0].flat<float>().data())