TensorFlow的C++之路(4):如何利用预测得到的Tensor

上一节,我讲到了用Session指针的run函数得到网络的输出。形式是

vector<Tensor>

现在我们看一个示范

status = session->Run(inputs, { "post_processing/result" }, {}, &outputs);
		if (!status.ok()) {
			cout << status.ToString() << "\n";
		}
		Tensor t = outputs[0];  //从节点取出第一个输出  "node :0"


		TensorShape shape = t.shape();
		cout << shape.dims() << std::endl;  // 2 6 
		cout << shape.dim_size(0) << " " << shape.dim_size(1) << std::endl;
		if (shape.dims() != 2)   // num, 6
		{
			std::cout << "no bbox in this frame!" << std::endl;
		}
		else {
			auto tmap = t.tensor<float, 2>();
			int output_dim = shape.dim_size(0);
			for (int i = 0; i < output_dim; i++)
			{
				cv::rectangle(img, cv::Point(tmap(i, 0), tmap(i, 1)), cv::Point(tmap(i, 2), tmap(i, 3)), Scalar(255, 0, 0));
			}
		}

~~对outputs我们需要使用输出节点的第一个输出(这句话对tensorflow了解的同学应该能明白,一个node的输出是有编号的~
因为我们在session->run中仅需要"post_processing/result"的输出,所以这里用index为0的位置得到这个节点的输出。
然后API提供了查看shape的函数。
重点是这里

auto tmap = t.tensor<float, 2>();

Tensor.tensor能帮助用户获得Tensor类型的数据接口,和OpenCV支持的Mat.data很相似。
然后我们就可以用圆括号来获得我们想获得的值。

在能获得我们想得到的值之前,我们需要对输出的shape有了解。如果输出是一个特征图,则

auto tmap = t.tensor<float, 4>();

如果是向量则,

auto tmap = t.tensor<float, 2>();

Note: 如果你对用到的pb模型不了解,还是先用

TensorShape shape = t.shape();
cout << shape.dims() << std::endl;

来看看输出是几维的。
然后就跟使用numpy一样方便了,

auto tmap = t.tensor<float, 2>();
int output_dim = shape.dim_size(0);
for (int i = 0; i < output_dim; i++)
{
	cv::rectangle(img, cv::Point(tmap(i, 0), tmap(i, 1)),
			 cv::Point(tmap(i, 2), tmap(i, 3)), Scalar(255, 0, 0));
}

tmap就可以当做是sess.run输出的numpy数组了。用圆括号索引。注意output_dim是Batch size维度,就是第一维(index为0)。
比如:

tmap(0,0) 就是在第一行,第一列的值。 当然这是在输出是两维的情况下。即【batch size,classses num】
另外如果tmap(0)的输出是什么值得探讨,是一组float型的数组还是啥?

上面的代码,for循环要做的是,遍历模型输出的数组,得到每一个经过NMS的框,然后用opencv的函数画出来框。

你可能感兴趣的:(TesorFlow)