torch :: Tensor를 cv :: InputArray로 변환하는 방법?

Aug 22 2020

나는을 사용하려고하는데 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());

내가 여기서 뭘 잘못하고 있니? 기본 버퍼를 공유하고 복사를 전혀 피할 수있는 방법이 있습니까?

답변

1 Rika Aug 22 2020 at 15:36

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()충돌이 발생하므로 여기에 더 현실적인 입력 및 출력을 실행하여 작동하는지 확인할 수 있습니다.

방법 1 : 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>());