如何将 torch::Tensor 转换为 cv::InputArray?
How to Convert a torch::Tensor into a cv::InputArray?
我正在尝试使用 cv::getAffineTransform()
,但我一直在研究如何将张量转换为相应的 cv::InputArray
。
我已经尝试过这些来应对访问冲突:
torch::Tensor src = torch::tensor({ 1.1, 2.0, 3.3 });
torch::Tensor dst = torch::tensor({ 1.1, 2.0, 3.3 });
cv::Mat input_array;
cv::Mat destination_array;
std::memcpy(input_array.data, src.data_ptr<float>(), sizeof(float) * src.numel());
std::memcpy(destination_array.data, dst.data_ptr<float>(), sizeof(float) * dst.numel());
我在这里做错了什么?
有没有办法共享底层缓冲区并完全避免复制?
它 运行 需要在 cv::Mat
中指定尺寸才能成功复制!也就是说,我需要这样做:
cv::Mat input_array (3, 1, CV_32FC1);
cv::Mat destination_array (3, 1, CV_32FC1);
std::memcpy(input_array.data, src.data_ptr<float>(), sizeof(float) * src.numel());
std::memcpy(destination_array.data, dst.data_ptr<float>(), sizeof(float) * dst.numel());
std::cout << input_array << std::endl;
std::cout << destination_array << std::endl;
并且这不再导致访问冲突。我可以验证这些值确实被复制了:
[1.1;
2;
3.3]
[1.1;
2;
3.3]
由于前一个示例使用的是伪造的输入数据,cv::getAffineTransform()
会崩溃,所以这是一个更真实的输入和输出,您可以 运行 看看它是否有效:
方法一:使用std::memcpy
复制数据:
torch::Tensor src = torch::tensor({ {137.47012, 62.52604}, {170.50703, 64.21498}, {154.49675, 80.78379} });
torch::Tensor dst = torch::tensor({ {38.294598, 51.6963}, {73.5318, 51.5014}, {56.0252, 71.7366} });
std::cout << "src.shapes: " << src.sizes() << std::endl;
std::cout << "dst.shapes: " << dst.sizes() << std::endl;
int rows = src.sizes()[0];
int cols = (src.sizes().size() == 1) ? 1 : src.sizes()[1];
cv::Mat input_array (rows, cols, CV_32FC1);
cv::Mat destination_array (rows, cols, CV_32FC1);
std::memcpy(input_array.data, src.data_ptr<float>(), sizeof(float) * src.numel());
std::memcpy(destination_array.data, dst.data_ptr<float>(), sizeof(float) * dst.numel());
std::cout << "input_array:\n" << input_array << std::endl;
std::cout << "destination_array:\n" << destination_array << std::endl;
auto tfm = cv::getAffineTransform(input_array, destination_array);
std::cout << "tfm:\n" << tfm << std::endl;
和
方法 2:使用底层缓冲区而不是复制:
int height = src.sizes()[0];
int width = src.sizes()[1];
cv::Mat input_array(cv::Size{width, height }, CV_32F, src.data_ptr<float>());
cv::Mat destination_array(cv::Size{ width, height }, CV_32F, dst.data_ptr<float>());
我正在尝试使用 cv::getAffineTransform()
,但我一直在研究如何将张量转换为相应的 cv::InputArray
。
我已经尝试过这些来应对访问冲突:
torch::Tensor src = torch::tensor({ 1.1, 2.0, 3.3 });
torch::Tensor dst = torch::tensor({ 1.1, 2.0, 3.3 });
cv::Mat input_array;
cv::Mat destination_array;
std::memcpy(input_array.data, src.data_ptr<float>(), sizeof(float) * src.numel());
std::memcpy(destination_array.data, dst.data_ptr<float>(), sizeof(float) * dst.numel());
我在这里做错了什么? 有没有办法共享底层缓冲区并完全避免复制?
它 运行 需要在 cv::Mat
中指定尺寸才能成功复制!也就是说,我需要这样做:
cv::Mat input_array (3, 1, CV_32FC1);
cv::Mat destination_array (3, 1, CV_32FC1);
std::memcpy(input_array.data, src.data_ptr<float>(), sizeof(float) * src.numel());
std::memcpy(destination_array.data, dst.data_ptr<float>(), sizeof(float) * dst.numel());
std::cout << input_array << std::endl;
std::cout << destination_array << std::endl;
并且这不再导致访问冲突。我可以验证这些值确实被复制了:
[1.1;
2;
3.3]
[1.1;
2;
3.3]
由于前一个示例使用的是伪造的输入数据,cv::getAffineTransform()
会崩溃,所以这是一个更真实的输入和输出,您可以 运行 看看它是否有效:
方法一:使用std::memcpy
复制数据:
torch::Tensor src = torch::tensor({ {137.47012, 62.52604}, {170.50703, 64.21498}, {154.49675, 80.78379} });
torch::Tensor dst = torch::tensor({ {38.294598, 51.6963}, {73.5318, 51.5014}, {56.0252, 71.7366} });
std::cout << "src.shapes: " << src.sizes() << std::endl;
std::cout << "dst.shapes: " << dst.sizes() << std::endl;
int rows = src.sizes()[0];
int cols = (src.sizes().size() == 1) ? 1 : src.sizes()[1];
cv::Mat input_array (rows, cols, CV_32FC1);
cv::Mat destination_array (rows, cols, CV_32FC1);
std::memcpy(input_array.data, src.data_ptr<float>(), sizeof(float) * src.numel());
std::memcpy(destination_array.data, dst.data_ptr<float>(), sizeof(float) * dst.numel());
std::cout << "input_array:\n" << input_array << std::endl;
std::cout << "destination_array:\n" << destination_array << std::endl;
auto tfm = cv::getAffineTransform(input_array, destination_array);
std::cout << "tfm:\n" << tfm << std::endl;
和
方法 2:使用底层缓冲区而不是复制:
int height = src.sizes()[0];
int width = src.sizes()[1];
cv::Mat input_array(cv::Size{width, height }, CV_32F, src.data_ptr<float>());
cv::Mat destination_array(cv::Size{ width, height }, CV_32F, dst.data_ptr<float>());