C#でのFaster RCNNによる物体検出
C#でのFaster RCNNディープラーニングによる物体検出
Section titled “C#でのFaster RCNNディープラーニングによる物体検出”このサンプルでは、ONNX Runtime C# APIを使用して、事前トレーニング済みのFaster R-CNN物体検出ONNXモデルを実行する方法を順を追って説明します。
このサンプルのソースコードはこちらで入手できます。
このサンプルを実行するには、次のものが必要です。
- お使いのOS(Mac、Windows、またはLinux)に.NET Core 3.1以上をインストールします。
- Faster R-CNN ONNXモデルをローカルシステムにダウンロードします。
- モデルをテストするためにこのデモ画像をダウンロードします。お好きな画像を使用することもできます。
始めましょう
Section titled “始めましょう”これで準備が整いましたので、画像上でモデルを実行するためのコードの追加を開始できます。簡単にするために、プログラムのmainメソッドでこれを行います。
パスの読み取り
Section titled “パスの読み取り”まず、モデルへのパス、テストしたい画像へのパス、および出力画像へのパスを読み取ります。
string modelFilePath = args[0];string imageFilePath = args[1];string outImageFilePath = args[2];画像の読み取り
Section titled “画像の読み取り”次に、クロスプラットフォームの画像ライブラリImageSharpを使用して画像を読み取ります。
using Image<Rgb24> image = Image.Load<Rgb24>(imageFilePath, out IImageFormat format);後のステップで画像を効率的に前処理できるように、特にRgb24型を読み取っていることに注意してください。
画像のリサイズ
Section titled “画像のリサイズ”次に、モデルが期待する適切なサイズに画像をリサイズします。高さと幅の両方が[800, 1333]の範囲内になるように画像をリサイズすることをお勧めします。
float ratio = 800f / Math.Min(image.Width, image.Height);using Stream imageStream = new MemoryStream();image.Mutate(x => x.Resize((int)(ratio * image.Width), (int)(ratio * image.Height)));image.Save(imageStream, format);画像の前処理
Section titled “画像の前処理”次に、モデルの要件に従って画像を前処理します。
var paddedHeight = (int)(Math.Ceiling(image.Height / 32f) * 32f);var paddedWidth = (int)(Math.Ceiling(image.Width / 32f) * 32f);var mean = new[] { 102.9801f, 115.9465f, 122.7717f };
// 画像の前処理// 多次元アクセスにはDenseTensorを使用しますDenseTensor<float> input = new(new[] { 3, paddedHeight, paddedWidth });image.ProcessPixelRows(accessor =>{ for (int y = paddedHeight - accessor.Height; y < accessor.Height; y++) { Span<Rgb24> pixelSpan = accessor.GetRowSpan(y); for (int x = paddedWidth - accessor.Width; x < accessor.Width; x++) { input[0, y, x] = pixelSpan[x].B - mean[0]; input[1, y, x] = pixelSpan[x].G - mean[1]; input[2, y, x] = pixelSpan[x].R - mean[2]; } }});ここでは、必要なサイズ(channels, paddedHeight, paddedWidth)のテンソルを作成し、ピクセル値にアクセスして前処理し、最後に適切なインデックスでテンソルに割り当てています。
// DenseTensorメモリをピン留めし、OrtValueテンソルで直接使用します // ortValueの破棄時にピン留めが解除されます
using var inputOrtValue = OrtValue.CreateTensorValueFromMemory(OrtMemoryInfo.DefaultInstance, input.Buffer, new long[] { 3, paddedHeight, paddedWidth });次に、モデルへの入力を作成します。
var inputs = new Dictionary<string, OrtValue>{ { "image", inputOrtValue }};ONNXモデルの入力ノード名を確認するには、Netronを使用してモデルを視覚化し、入力/出力名を確認できます。この場合、このモデルの入力ノード名はimageです。
次に、推論セッションを作成し、それに入力を通します。
using var session = new InferenceSession(modelFilePath);using var runOptions = new RunOptions();using IDisposableReadOnlyCollection<OrtValue> results = session.Run(runOptions, inputs, session.OutputNames);出力の後処理
Section titled “出力の後処理”次に、出力を後処理して、各ボックスのボックス、関連するラベル、および信頼度スコアを取得する必要があります。
var boxesSpan = results[0].GetTensorDataAsSpan<float>();var labelsSpan = results[1].GetTensorDataAsSpan<long>();var confidencesSpan = results[2].GetTensorDataAsSpan<float>();
const float minConfidence = 0.7f;var predictions = new List<Prediction>();
for (int i = 0; i < boxesSpan.Length - 4; i += 4){ var index = i / 4; if (confidencesSpan[index] >= minConfidence) { predictions.Add(new Prediction { Box = new Box(boxesSpan[i], boxesSpan[i + 1], boxesSpan[i + 2], boxesSpan[i + 3]), Label = LabelMap.Labels[labelsSpan[index]], Confidence = confidencesSpan[index] }); }}偽陽性を除去するために、信頼度が0.7を超えるボックスのみを取得していることに注意してください。
次に、画像にボックスと関連するラベル、および信頼度スコアを描画して、モデルがどのように機能したかを確認します。
using var outputImage = File.OpenWrite(outImageFilePath);Font font = SystemFonts.CreateFont("Arial", 16);foreach (var p in predictions){ image.Mutate(x => { x.DrawLines(Color.Red, 2f, new PointF[] {
new PointF(p.Box.Xmin, p.Box.Ymin), new PointF(p.Box.Xmax, p.Box.Ymin),
new PointF(p.Box.Xmax, p.Box.Ymin), new PointF(p.Box.Xmax, p.Box.Ymax),
new PointF(p.Box.Xmax, p.Box.Ymax), new PointF(p.Box.Xmin, p.Box.Ymax),
new PointF(p.Box.Xmin, p.Box.Ymax), new PointF(p.Box.Xmin, p.Box.Ymin) }); x.DrawText($"{p.Label}, {p.Confidence:0.00}", font, Color.White, new PointF(p.Box.Xmin, p.Box.Ymin)); });}image.Save(outputImage, format);ボックス予測ごとに、ImageSharpを使用して赤い線を描画してボックスを作成し、ラベルと信頼度のテキストを描画しています。
プログラムの実行
Section titled “プログラムの実行”プログラムが作成されたので、次のコマンドで実行できます。
dotnet run [path-to-model] [path-to-image] [path-to-output-image]例:実行中:
dotnet run ~/Downloads/FasterRCNN-10.onnx ~/Downloads/demo.jpg ~/Downloads/out.jpg画像内の次のオブジェクトを検出します。
