ROIリストの前処理
アプリケーションにすでに 1 つ以上の画像ウィンドウがあり、各ウィンドウをモデルの入力として正確に前処理(リサイズまたはレターボックス処理、カラー変換、正規化、量子化、およびオプションでテッセレーション)したい場合は、前処理済み ROI リストを使用します。
これは、2 次分類器、検出器カスケード、トラッカー、またはソース画像のバッチから動的なクロップのリストが生成されるようなフローに最適なツールです。
最小限の例
C++:
#include <neat.h>
#include <opencv2/imgcodecs.hpp>
using namespace simaai::neat;
Model model("/path/to/model.tar.gz");
std::vector<cv::Mat> images = {
cv::imread("/data/camera0.jpg", cv::IMREAD_COLOR),
cv::imread("/data/camera1.jpg", cv::IMREAD_COLOR),
};
std::vector<PreprocessRoi> rois = {
{0, 0, 0, 320, 240},
{0, 120, 80, 160, 160},
{1, -20, 30, 224, 224},
};
TensorList out = stages::Preproc(images, model, rois);
for (std::size_t i = 0; i < out.size(); ++i) {
const auto& meta = out[i].semantic.preprocess;
// out[i] is the preprocessed tensor for rois[i].
// meta carries the ROI and inverse-coordinate breadcrumbs.
}
Python:
import cv2
import pyneat
model = pyneat.Model("/path/to/model.tar.gz")
images = [
cv2.imread("/data/camera0.jpg", cv2.IMREAD_COLOR),
cv2.imread("/data/camera1.jpg", cv2.IMREAD_COLOR),
]
rois = [
pyneat.PreprocessRoi(0, 0, 0, 320, 240),
pyneat.PreprocessRoi(0, 120, 80, 160, 160),
pyneat.PreprocessRoi(1, -20, 30, 224, 224),
]
out = pyneat.stages.preproc(
images,
model,
rois=rois,
image_format=pyneat.PixelFormat.BGR,
)
for i, tensor in enumerate(out):
meta = tensor.semantic.preprocess
# tensor is the preprocessed output for rois[i].
# meta carries the ROI and inverse-coordinate breadcrumbs.
リサイズ、レターボックス、および正規化の設定を行います。
ROIリストの前処理は、フルフレームの前処理と同じモデル前処理オプションを使用します。
C++:
Model::Options opt;
opt.preprocess.resize.enable = AutoFlag::On;
opt.preprocess.resize.width = 640;
opt.preprocess.resize.height = 640;
opt.preprocess.resize.mode = ResizeMode::Letterbox;
opt.preprocess.resize.pad_value = 114;
opt.preprocess.resize.scaling_type = "BILINEAR";
opt.preprocess.normalize.enable = AutoFlag::On;
opt.preprocess.normalize.mean = {0.0f, 0.0f, 0.0f};
opt.preprocess.normalize.stddev = {1.0f, 1.0f, 1.0f};
opt.preprocess.tessellate.enable = AutoFlag::Auto;
Model model("/path/to/model.tar.gz", opt);
TensorList out = stages::Preproc(images, model, rois);
Python:
opt = pyneat.ModelOptions()
opt.preprocess.resize.enable = pyneat.AutoFlag.On
opt.preprocess.resize.width = 640
opt.preprocess.resize.height = 640
opt.preprocess.resize.mode = pyneat.ResizeMode.Letterbox
opt.preprocess.resize.pad_value = 114
opt.preprocess.resize.scaling_type = "BILINEAR"
opt.preprocess.normalize.enable = pyneat.AutoFlag.On
opt.preprocess.normalize.mean = [0.0, 0.0, 0.0]
opt.preprocess.normalize.stddev = [1.0, 1.0, 1.0]
opt.preprocess.tessellate.enable = pyneat.AutoFlag.Auto
model = pyneat.Model("/path/to/model.tar.gz", opt)
out = pyneat.stages.preproc(
images,
model,
rois=rois,
image_format=pyneat.PixelFormat.BGR,
)
サポートされているscaling_typeトークンは、BILINEAR、NEAREST_NEIGHBOUR、BICUBIC、INTERAREA、およびNO_SCALINGです。NEAREST_NEIGHBORとINTER_AREAは、有効な別名として受け入れられます。
バッチ処理のセマンティクス
| 入力 | 意味 |
|---|---|
images | 入力画像のバッチ。ROIが指定されている場合、ベクトル/リストは空であってはなりません。Pythonでは、uint8形式のHW/HWC形式のNumPy/Torch/pyneat.Tensor形式の画像を入力として受け付けます。 |
rois | ランタイムにおけるROIリスト。出力されるテンソルの順序は、このベクトルの順序と一致します。 |
PreprocessRoi::batch_index | は、images 内のどのソース画像からROIが読み取るかを指定します。 |
PreprocessRoi::x, y | 署名されたソースフレームの左上座標。負の値も許可されます。 |
PreprocessRoi::width, height | ROIの寸法。どちらも正の値である必要があります。 |
ROIリスト呼び出しで使用するすべてのソース画像は、幅、高さ、OpenCVのタイプ、およびチャンネル数が一致している必要があります。ステージAPIは、ROIリスト用の、パックされた8ビットRGB/BGR(CV_8UC3)およびGRAY/GRAY8(CV_8UC1)のソース画像をサポートします。
Pythonの場合、cv2.imreadで読み込んだ画像にはimage_format=pyneat.PixelFormat.BGRを、RGB配列にはRGBを、HW形式のグレースケール配列にはGRAY8を渡します。CHW形式のテンソルはpyneat.stages.preprocによって拒否されるため、ステージを呼び出す前にHWC形式に変換してください。
出力の意味
stages::Preproc(images, model, rois) は、以下の値を返します。
- 有効な空でないリクエストの場合の、
out.size() == rois.size()。 - ROI
rois[i]から生成された出力テンソルout[i]。 - モデルのルーティングによって選択されたデータ型とレイアウト(BF16やINT8、および密な出力またはテッセレーションされた出力など)
- 出力ごとの
tensor.semantic.preprocessメタデータ。
各出力の事前処理メタデータには、選択された関心領域(ROI)、レターボックスのジオメトリ、正規化/量子化/テッセレーションのフラグ、およびモデル/事前処理された座標を元のソースフレーム座標系にマッピングするアフィン変換が含まれます。
フレーム外にある関心領域
関心領域(ROI)は、元の画像の外側にまで及ぶことがあります。
std::vector<PreprocessRoi> rois = {
{0, -16, -16, 128, 128},
{0, image.cols - 64, image.rows - 64, 128, 128},
};
フレーム内の領域はコピーされ、フレーム外の領域は、Preproc パッドの値を使用してパディングされます。これにより、出力形状が安定し、画像の端付近での特別な処理を回避できます。