Convert torch::tensor to cv::Mat

JeeLee: <p><strong>I want to convert th result torch::tensor to cv::Mat using the follow code, but the  <code>resultImg</code> is wrong.I have checked the tensor result.It is right</strong></p>
<p><code>torch::Tensor out_tensor = module-&gt;forward(inputs).toTensor(); assert(out_tensor.device().type() == torch::kCUDA); out_tensor=out_tensor.to(torch::kCPU); out_tensor=out_tensor.squeeze().detach(); out_tensor=out_tensor.permute({1,2,0}); out_tensor=out_tensor.mul(255).clamp(0,255).to(torch::kInt);</code><br>
<code>cv::Mat resultImg(512, 512,CV_8UC3,(void*)out_tensor.data_ptr());</code></p>
<p><strong>Of course, I can get the correct image result like this</strong>:</p>
<p><code>for(int y=0;y&lt;512;++y)</code><br>
<code>for(int x=0;x&lt;512;++x)</code><br>
<code>for(int c=0;c&lt;3;++c)</code><br>
<code>{</code><br>
<code>int val=(*(out_tensor[y][x][c]).data&lt;int&gt;());</code><br>
<code>testImg.at&lt; cv::Vec3b&gt;(y,x)[c]=val;</code><br>
<code>}</code><br>
<strong>But this way is too slow.I want to know the efficient method ，any advise is appreciated</strong></p>

mhubii: <p>Hi <a class="mention" href="/u/jeelee">@JeeLee</a></p>
<p>you should be able to use a <code>std::memcpy</code> like so</p>
<pre><code class="lang-cpp">#include &lt;torch/torch.h&gt;
#include &lt;opencv2/core/core.hpp&gt;

int main()
{
   cv::Mat cv_mat = cv::Mat::eye(3,3,CV_32F);
   torch::Tensor tensor = torch::zeros({3, 3}, torch::kF32);

   std::memcpy(tensor.data_ptr(), cv_mat.data, sizeof(float)*tensor.numel());

   std::cout &lt;&lt; cv_mat &lt;&lt; std::endl;
   std::cout &lt;&lt; tensor &lt;&lt; std::endl;

   return 0;
}
</code></pre>
<p>and your CMakeLists.txt</p>
<pre><code class="lang-auto">cmake_minimum_required(VERSION 3.11 FATAL_ERROR)

project(torch_to_cv)

find_package(Torch REQUIRED)
find_package(OpenCV REQUIRED)

include_directories(${TORCH_INCLUDE_DIRS})
include_directories(${OpenCV_INCLUDE_DIRS})

add_executable(main main.cpp)
target_link_libraries(main ${TORCH_LIBRARIES} ${OpenCV_LIBRARIES})
</code></pre>
<p>of course this also means that you’ll lose track of the gradients. And of course if you are dealing with higher dimensional tensors, as you already pointed out, you’ll need to be aware that OpenCV stores images HxWxC, while for Pytorch they are stored as CxHxW. Using <code>permute()</code> for that is perfectly fine.</p>

JeeLee: <aside class="quote no-group" data-username="mhubii" data-post="2" data-topic="42751">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/mhubii/48/71033_2.png" class="avatar"> mhubii:</div>
<blockquote>
<p>you should be able to use a <code>std::memcpy</code> like so</p>
</blockquote>
</aside>
<p>Thanks for your reply. Your advise is very useful to me. Now I can get the correct result image using the follow code:</p>
<blockquote>
<p><code> torch::Tensor out_tensor = module-&gt;forward(inputs).toTensor();</code><br>
<code>assert(out_tensor.device().type() == torch::kCUDA);</code><br>
<code>out_tensor=out_tensor.squeeze().detach().permute({1,2,0}); </code><br>
<code>out_tensor=out_tensor.mul(255).clamp(0,255).to(torch::kU8);</code><br>
<code>out_tensor=out_tensor.to(torch::kCPU);</code><br>
<code>cv::Mat resultImg(512, 512,CV_8UC3);</code><br>
<code>std::memcpy((void*)resultImg.data,out_tensor.data_ptr(),sizeof(torch::kU8)*out_tensor.numel());</code></p>
</blockquote>

hktxt: <p>Oh, it’s helpful.<br>
How to do inference on GPU? I mean move model and input to the GPU, can I see the code?</p>