torchvisionのResizeを、OpenCV および PyTorch C++ API を使ってなるべく再現します。
ここで紹介するのは、あくまでも「同じような操作」を行う方法なので、torchvisionと全く同じ前処理ができる訳ではないです。(PyTorch Forum)
Pythonと全く同じ前処理をした画像をTorchScriptに変換したモデルに入れてC++で使いたい、という場合には、Pythonで前処理した画像を読み込むのが確実だと思います。
torch::nn::functional::interpolateを使う方法
namespace F=torch::nn:functional;
auto image_float_tensor = torch::from_blob(image_float.data, { image_float.rows, image_float.cols, 3 }).toType(c10::kFloat);
image_float_tensor = image_float_tensor.unsqueeze(0);
if(image_float.size().width >= image_float.size().height)
F::interpolate(image_float_tensor, F::InterpolateFuncOptions().size(std::vector<int64_t>({(int64_t)(image_float.cols / (image_float.rows / (float)resize)), resize})).mode(torch::kBilinear).align_corners(true));
else
F::interpolate(image_float_tensor, F::InterpolateFuncOptions().size(std::vector<int64_t>({resize, (int64_t)(image_float.rows / (image_float.cols / (float)resize))})).mode(torch::kBilinear).align_corners(true));
image_float_tensor = image_float_tensor.squeeze(0);
// end tensorとしてresize
// cv::Matに戻す
std::memcpy(image_float_tensor.data_ptr(), image_float.data, sizeof(float)*image_float_tensor.numel());
// end cv::Matに戻す
OpenCVを使う方法
// cv::resize(image_float, image_float, cv::Size(resize, resize), cv::INTER_NEAREST);
// torchvisionのresize(引数一つ)は短辺の長さを引数にするようなResizeをするので下でOK
/* 補完方法
// auto INTERPOLATE = cv::INTER_NEAREST;
// auto INTERPOLATE = cv::INTER_LINEAR_EXACT;
// auto INTERPOLATE = cv::INTER_AREA;
// auto INTERPOLATE = cv::INTER_CUBIC;
*/
auto INTERPOLATE = cv::INTER_LINEAR;
if(image_float.size().width >= image_float.size().height)
cv::resize(image_float, image_float, cv::Size(image_float.cols / (image_float.rows / (float)resize), resize), INTERPOLATE);
else
cv::resize(image_float, image_float, cv::Size(resize, image_float.rows / (image_float.cols / (float)resize)), INTERPOLATE);
この記事は役に立ちましたか?
もし参考になりましたら、下記のボタンで教えてください。
コメント