Detection
이 문서는 SaigieVision을 통해 이미지에서 Object를 사각 형태로 'Detection(검출)'하는 방법에 대해 설명합니다.
여러분이 앞서 제공된 Quick Start 를 끝냈다면, 'Detection'을 수행하는 방법은 그리 어렵지 않습니다.
아래 코드 블럭은 간단하게 Detection 검사 진행 방법에 대해서 설명합니다.
{
//Initialize
SaigeVision.Core.SaigeVisionApp.Init();
//Prepare
var gpuService = new NvGpuService();
gpuService.DetectConnectedGPUs();
SrImage data = new SrImage("../../../sample.png");
var modelUri = new Uri(@".../../../model.SrDet");
//Inspect
using (DetectionEngine engine = EngineLoader.LoadFrom<DetectionEngine>(modelUri))
{
DetInspectionOptions option = engine.ReadInspectionOptions();
option.TimeLimit = TimeSpan.FromSeconds(5);
option.MaxNumberOfBoxes[0] = 0;
option.MaxNumberOfBoxes[1] = 5;
engine.AllocateNetwork(gpuService.CurrentDetectedGPUs[0], option);
DetectionReport report = engine.Inspect(data);
Console.WriteLine($"Number of detected boxes: {report.Prediction.Count}");
foreach (var box in report.Prediction)
{
Console.WriteLine("------------------------");
Console.WriteLine($"Labeled class name: {box.Class.Name}");
Console.WriteLine($"Bounds: {box.Bounds}");
Console.WriteLine($"Score: {box.Score}");
}
}
//Clean up (optional)
data.DisposeAll();
}
Initialize
SaigeVision.Core를 사용하기 위해서는 런타임에 돌입하는 시점에서 1회 SaigeVisionApp.Init()을 통해 SaigeVision.Core를 초기화해야 합니다.
초기화를 진행하기 적절한 장소는 작성중인 애플리케이션의 main() 함수 최상단입니다.
여러분이 Console App이 아닌 다른 플랫폼을 사용하여 main()함수를 찾기 어렵다면 (WPF, WinForms 와 같은...) 어느 위치라도 좋으나 오직 '단 한번' 호출 하는것을 보장하는 장소가 좋습니다.
또한, EngineLoader를 사용하기 전이어야 합니다.
Prepare
DetectionEngine을 사용하기 위해 필요한 모든 데이터를 준비하는 과정입니다.
일반적으로 아래와 같은 3가지를 요구합니다.
- 검사에 사용할 GPU
- 검사에 사용할 샘플 이미지들
- 검사에 사용할 모델( .srDet 파일)
SaigeVision은 NVIDIA사의 GPU만을 지원하고 있습니다.
또한, SaigeVision은 모든 이미지 개체를 SrImage를 통해 전달 받고 있습니다.
SrImage는 내부적으로 ArrayPool<T>과 같은 .Net의 도구들을 통해 성능 최적화를 이루는데 많은 노력을 기울였습니다.
다양한 생성자를 지원하니 꼭 SrImage에 대한 API docs 확인을 권장합니다.
Inspection
'Inspection'부는 DetectionEngine을 EngineLoader를 통해 로드하는 것으로 시작합니다.
'Inspection'부는 알아보기 쉽게 아래와 같이 절차를 구분하여 설명하겠습니다.
1. Load engine
이 예제에서는 사용의 안전을 위해 C# 언어의 using 문을 사용합니다.
여러분의 시나리오에서 해당 using문 사용이 알맞지 않다고 생각한다면, 무시 할 수 있습니다.
하지만 using문을 사용하지 않는 경우, 사용이 완료된 DetectionEngine은 반드시 관리 하에 DetectionEngine.Dispose() 되어야합니다.
EngineLoader.LoadFrom<T>()는 완료하는데 약간이 시간이 소요 될 수 있습니다. 이는 일반적으로 Thread가 Blocking 될 수 있는 정도의 수준입니다.
2. Inspection Options
다시 샘플 코드의 설명으로 돌아가면, 샘플 코드는 Engine을 로드하고 나서 해당 Engine을 통해 DetInspectionOptions를 로드하고 있습니다.
DetectionEngine은 Inspection을 수행할 때 여러가지 옵션을 지정할 수 있습니다.
해당 옵션들은 실제 Inspection을 수행하는데 영향을 주며, 레포트(결과)에 반영됩니다.
이 예제에서는 뒤에 이어지는 코드에서 보이는것 처럼 'Forward time limit'과 'MaxNumberOfBoxes'에 옵션 값을 지정하고 있습니다.
이렇게 만들어진 새로운 옵션은(DetectionOptions)는 Engine의 AllocateNetowrk()를 통해 주입이 가능합니다.
- 이후 진행되는 모든 'Inspection'의 결과는 해당 Option이 적용된 값입니다.
특정한 시나리오에서는 이렇게 설정한 Option 값을 모델에 기록할 필요가 있을 수 있습니다.
사실 LoadInspectionOptions()는 모델에 기록된 제일 최근의 Option 값을 로드하는 함수입니다.
여러분이 해당 Option을 모델에 기록하길 원한다면 WirteInspectionOptions()를 사용하세요.
또한, WriteInspectionOptionsAsDefault()를 통해 Default options로 되돌릴 수 있습니다.
만약
AllocateNetowrk()를 통해 Options를 지정하지 않는다면, 자동적으로 모델에 기록되어있는 Option을 사용합니다.AllocateNetowrk()는 약간의 시간이 소요될 수 있습니다. 일반적으로 Thread가 Blocking될 수 있는 수준입니다.
3. Inspect
코드에서 볼수 있는 것처럼 'Inspection'을 수행하는 주 함수는 engine.Inspect()입니다. 모든 종류의 Engine들은 이러한 공통의 Inspect() 함수를 보유하고 있습니다. 또한, 다양한 사용을 위해 여러 형태로 중첩 되어 있습니다. 비동기 혹은 다수의 이미지들을 검사하는 등의 여러 시나리오에서 선택적으로 사용할 수 있습니다.
Inspect()가 반환하는 DetectionReport는 검사를 진행한 후 전달해야 하는 모든 결과를 레포트합니다.
Clean up (Optional)
이 예제에서는 검사에 사용했던 SrImage들을 더 이상 사용할 곳이 없이게 Dispose() 합니다.