Torch::from_blob failed to convert cv::Mat to torch::Tensor

I want to trace cv2.getAffineTransform by implementing the operator in c++, but there is a problem when converting cv:Mat to torch::Tensor by using torch::from_blob in my code:

C++ code:

// C++implementation
#include <opencv2/opencv.hpp>
#include "torch/script.h"

torch::Tensor get_affine_transform(at::Tensor src, at::Tensor dst) {

  cv::Mat src_mat(/*rows=*/src.size(0),
                  /*cols=*/src.size(1),
                  /*type=*/CV_32FC1,
                  /*data=*/src.data_ptr<float>());

  cv::Mat dst_mat(/*rows=*/dst.size(0),
                  /*cols=*/dst.size(1),
                  /*type=*/CV_32FC1,
                  /*data=*/dst.data_ptr<float>());

  std::vector<cv::Point2f> srcTri = cv::Mat_<cv::Point2f>(src_mat);
  std::vector<cv::Point2f> dstTri = cv::Mat_<cv::Point2f>(dst_mat);

  cv::Mat output_mat = cv::getAffineTransform(srcTri, dstTri);

  std::cout << "output_mat: " << output_mat << std::endl;  // for debug

  torch::Tensor out_data =
      torch::from_blob(output_mat.ptr<float>(), /*sizes=*/{2, 3}, at::kFloat);

  std::cout << "out_data: " << out_data << std::endl;  // for debug

  return out_data.clone();
}

// the op is successfully registered
static auto registry =
    torch::RegisterOperators("my_ops::get_affine_transform", &get_affine_transform);

python code:

import cv2
import torch

pts1 = torch.tensor([[50, 50], [200, 50], [50, 200]], dtype=torch.float32)
pts2 = torch.tensor([[10, 100], [200, 50], [100, 250]], dtype=torch.float32)

M = cv2.getAffineTransform(pts1.numpy(), pts2.numpy())
print(f"M: {M}")

M2 = torch.ops.my_ops.get_affine_transform(pts1, pts2)
print(f"M2: {M2}")

but the outputs:

M: [[  1.26666667   0.6        -83.33333333]
 [ -0.33333333   1.          66.66666667]]

output_mat: [1.266666666666667, 0.6, -83.33333333333334;
  -0.3333333333333334, 1, 66.66666666666669]

out_data: 7.8507e+02  1.9083e+00  4.1723e-08
 1.7750e+00  1.4660e+13 -3.3255e+00

M2: tensor([[ 7.8507e+02,  1.9083e+00,  4.1723e-08],
        [ 1.7750e+00,  1.4660e+13, -3.3255e+00]])

It seems that the torch::from_blob not copy the data of output_mat(cv::Mat) to out_data (Tensor).
Can someone help me to see where my problem is?

I suspect that ‘getAffineTransform’ returns matrix of doubles (float64), so you could try →

 torch::from_blob(output_mat.ptr<double>(), /*sizes=*/{2, 3}, at::kDouble)
1 Like

Thank you so much. it was indeed caused by double dtype, and after I use your code, the problem was solved.