Tensor to Mat is inconsistent!

I have been stuck in a place for a few days, please help, thank you.

I need to convert tensor to mat
Tenser.size()=[288, 384]
Tenser.dtype()=float

However, when I compare the results before and after the conversion, the content of the comparison is inconsistent. May I be mistaken there?

   cout << "score_text sizes=" << score_text.sizes() << "\n";//[288, 384]
   cout << "score_text dtype=" << score_text.dtype() << "\n";  //float


	cv::Mat textmap(score_text.size(0), score_text.size(1), CV_32FC1);
	std::memcpy((void *)textmap.data, score_text.data_ptr(), sizeof(torch::kFloat32) * score_text.numel());//sizeof(torch::kFloat32)
	cout << "textmap rows=" << textmap.rows << "\n"; //textmap rows = 288
	cout << "textmap=" << textmap.size() << "\n";//textmap = [384 x 288]

	for (size_t row = 0; row < textmap.rows; row++) {
		for (size_t col = 0; col < textmap.cols; col++) {
			float textmap_value = textmap.ptr<float>(row)[col];
			float score_text_value = score_text[row][col].item<float>();
			if (textmap_value != score_text_value) {
				cout << "textmap=" << textmap_value << ",score_text_value=" << score_text_value <<  "\n";
			}
		}
	}

It seems to be solved, and it seems to be replaced by the following…
But why?

	cv::Mat textmap(cv::Size(score_text.size(1), score_text.size(0)), CV_32FC1, score_text.data<float>());

Have you tried using sizeof(float) instead of sizeof(torch::kFloat32) ?

		printf("%I64u\n", sizeof(torch::kFloat32)); // outputs 1
		printf("%I64u\n", sizeof(float)); // outputs 4

Yes.
I had tried it.
Same error.
Now
cv::Mat textmap(cv::Size(score_text.size(1), score_text.size(0)), CV_32FC1, score_text.data());
is my choice.

I used following code to verify:

	torch::Tensor score_text = torch::ones({ 5, 3 }); // tensor of ones to simulate input

	std::cout << "score_text sizes=" << score_text.sizes() << std::endl;
	std::cout << "score_text dtype=" << score_text.dtype() << std::endl;

	cv::Mat textmap(score_text.size(0), score_text.size(1), CV_32FC1);

	textmap.setTo(0); // zero memory to be able to check whether it was overwritten

	//std::memcpy((void *)textmap.data, score_text.data_ptr(), sizeof(torch::kFloat32) * score_text.numel());
	std::memcpy((void *)textmap.data, score_text.data_ptr(), sizeof(float) * score_text.numel());

	std::cout << "textmap rows=" << textmap.rows << std::endl;
	std::cout << "textmap=" << textmap.size() << std::endl;

	for (size_t row = 0; row < textmap.rows; row++) 
	{
		for (size_t col = 0; col < textmap.cols; col++) 
		{
			float textmap_value = textmap.ptr<float>(row)[col];
			float score_text_value = score_text[row][col].item<float>();

			if (textmap_value != score_text_value) 
			{
				std::cout << "textmap=" << textmap_value << ",score_text_value=" << score_text_value << std::endl;
			}
		}
	}

Why this works ->

cv::Mat textmap(cv::Size(score_text.size(1), score_text.size(0)), CV_32FC1, score_text.data_ptr())

OpenCV’s Mat correctly assumes length of data as rows * cols * sizeof(float)

1 Like