IAD (Image Anomaly Detection)
이 문서는 SaigieVision을 통해 이미지를 'Image Anomaly Detection(이상탐지)' (이하 IAD) 하는 방법에 대해 설명합니다.
여러분이 앞서 제공된 Quick Start 를 끝냈다면, 'IAD'을 수행하는 방법은 그리 어렵지 않습니다.
아래 코드 블럭은 간단하게 IAD(Image Anomaly Detection) 검사 진행 방법에 대해서 설명합니다.
{
// Prepare
SrImage srImage = new SrImage(@"..\..\sample.png");
string modelPath = @"..\..\model.saigeiad";
int gpuIndex = 0;
// Initialize
using (var engine = new IADEngine(modelPath, gpuIndex))
{
// Model Info
ModelInfo model = engine.GetModelInfo();
// Option
IADOption option = engine.GetInferenceOption();
option.CalcTime = true;
option.CalcHeatmap = true;
option.CalcMask = true;
option.CalcObject = true;
option.CalcObjectAreaAndApplyThreshold = true;
option.CalcObjectScoreAndApplyThreshold = true;
engine.SetInferenceOption(option);
// Inspection & Get Result
IADResult result = engine.Inspection(srImage);
Console.WriteLine("RESULT: " + (result.IsNG ? "NG" : "OK"));
Console.WriteLine($"Anomaly Score:{result.AnomalyScore.Score:N3}");
Console.WriteLine($"Max:{result.AnomalyScore.MaxScore:N3}");
Console.WriteLine($"Min{result.AnomalyScore.MinScore:N3}");
Console.WriteLine($"ImreadTime:{result.InspectionTime.ImreadTime}");
Console.WriteLine($"InferenceTime:{result.InspectionTime.InferenceTime}");
Console.WriteLine($"PostProcessingTime:{result.InspectionTime.PostProcessingTime}");
foreach (var so in result.SegmentedObjects)
{
Console.WriteLine($"Name:{so.ClassInfo.Name}");
Console.WriteLine($"Area:{so.Area}");
Console.WriteLine($"Score:{so.Score}");
Console.WriteLine($"Center Point X: ({so.BoundingRotBox.Center.X}");
Console.WriteLine($"Center Point Y: ({so.BoundingRotBox.Center.Y}");
}
}
// optional
srImage.Dispose();
}
Prepare
SrImage srImage = new SrImage(@"..\..\sample.png");
string modelPath = @"..\..\model.saigeiad";
int gpuIndex = 0;
IADEngine 을 사용하기 위해 필요한 모든 데이터를 준비하는 과정입니다. 일반적으로 아래와 같은 3가지를 요구합니다.
- 검사에 사용할 GPU
- 검사에 사용할 샘플 이미지들
- 검사에 사용할 모델( .saigeiad 파일)
SaigeVision은 NVIDIA사의 GPU만을 지원하고 있습니다.
GPU Index에 대해서는명령 프롬프트 (command)창을 통해nvidia-smi명령어를 입력하면 GPU의 index를 확인할 수 있습니다.
이미지는
SrImage객체를 통해 생성 가능합니다.8bit,16bit형태의 이미지를GrayScale,RGB,RGBA형태로 제공이 됩니다.
Initialize
IADEngine engine = new IADEngine(modelPath, gpuIndex)
IADEngine 생성자에서 .saigeiad 모델파일에 대한 경로와 GPU Index를 매개변수로 설정하여 생성합니다.
Model Info (Optional)
ModelInfo model = engine.GetModelInfo();
ModelInfo 는 .saigeiad 모델 파일에 대한 정보를 확인할 수 있습니다. 일반적으로 아래와 같은 정보를 확인할 수 있습니다.
- Network Type (어떤 종류의 딥러닝 네트워크를 사용했는지 나타냅니다)
- Classes Information (클래스 정보입니다. name, color에 대한 정보들을 확인할 수 있습니다.)
- Developer Version (모델을 학습할 때 사용한 SaigeVision Developer의 버전입니다.)
- Server Version (모델을 학습할 때 사용한 SaigeVision Developer의 구성 요소 중 서버의 버전입니다.)
- Module Version (모델을 학습할 때 사용한 SaigeVision Developer의 구성 요소 중 딥러닝 모듈의 버전입니다.)
- Roi Information (ROI 정보입니다.)
- Resize Factor (Segmentation, IEN 전용, 인풋 이미지에 적용되는 리사이즈 비율입니다. 추론 이미지에도 동일하게 적용됩니다.)
- Crop Size (Segmentation, IEN 전용, 학습 때 사용된 패치의 사이즈입니다. 추론 이미지와는 관련 없습니다)
- Image Resize (IAD, CLS 전용, 인풋 이미지에 적용되는 리사이즈 입니다. 추론 이미지에도 동일하게 적용됩니다)
자세한 내용은 Model Info 문서를 통하여 확인할 수 있습니다.
Option (Optional)
IADOption option = engine.GetInferenceOption();
option.CalcTime = true;
option.CalcHeatmap = true;
option.CalcMask = true;
option.CalcObject = true;
option.CalcObjectAreaAndApplyThreshold = true;
option.CalcObjectScoreAndApplyThreshold = true;
engine.SetInferenceOption(option);
IADOption 에서 GetInferenceOption() 을 통해서 옵션에 대해서 정보를 받을 수 있습니다.
SetInferenceOption() 을 통해서 옵션에 대해서 설정을 할 수 있습니다.
옵션은 아래와 같은 정보들을 설정할 수 있습니다.
- Calc Time (추론 API 실행에 소요되는 시간을 세분화하여 출력할지 결정합니다.)
- Batch Size (추론을 한 번 수행할 때 추론하는 이미지의 개수입니다.)
- Calc Segmented Object (
true로 설정하면 추론 시segmented object를 계산합니다.) - Calc Mask (
true로 설정하면 추론 시 이미지 원본과 같은 크기의mask를 계산합니다.) - Calc Heatmap (
true로 설정하면 추론 시 이미지 원본과 같은 크기의heatmap을 계산합니다.) - Calc Object Area and Apply Threshold
- Calc Object Score and Apply Threshold
- Anomaly Score Threshold (이미지 전체를 대표하는 anomaly score가 이 값보다 크면 비정상 이미지로, 작거나 같으면 정상 이미지로 판정합니다.)
- Heatmap Color Range Min/Max
- Object Boundary Threshold
- Object Area Threshold
- Object Score Threshold
자세한 내용은 IAD Option 문서를 통하여 확인할 수 있습니다.
Inspection
engine.Inspection(srImage);
코드에서 볼수 있는 것처럼 'Inspection'을 수행하는 주 함수는 engine.Inspect()입니다. 모든 종류의 Engine들은 이러한 공통의 Inspect() 함수를 보유하고 있습니다. 또한, 다양한 사용을 위해 여러 형태로 중첩 되어 있습니다. 비동기 혹은 다수의 이미지들을 검사하는 등의 여러 시나리오에서 선택적으로 사용할 수 있습니다.
Result
IADResult result = engine.GetResult();
Console.WriteLine("RESULT: " + (result.IsNG ? "NG" : "OK"));
Console.WriteLine($"Anomaly Score:{result.AnomalyScore.Score:N3}");
Console.WriteLine($"Max:{result.AnomalyScore.MaxScore:N3}");
Console.WriteLine($"Min{result.AnomalyScore.MinScore:N3}");
Console.WriteLine($"ImreadTime:{result.InspectionTime.ImreadTime}");
Console.WriteLine($"InferenceTime:{result.InspectionTime.InferenceTime}");
Console.WriteLine($"PostProcessingTime:{result.InspectionTime.PostProcessingTime}");
foreach (var so in result.SegmentedObjects)
{
Console.WriteLine($"Name:{so.ClassInfo.Name}");
Console.WriteLine($"Area:{so.Area}");
Console.WriteLine($"Score:{so.Score}");
Console.WriteLine($"Center Point X: ({so.BoundingRotBox.Center.X}");
Console.WriteLine($"Center Point Y: ({so.BoundingRotBox.Center.Y}");
}
IADResult 에서 결과에 대한 모든 정보를 확인할 수 있습니다. IAD 의 경우 아래와 같은 정보를 결과로 확인할 수 있습니다. 일부 결과 정보에 대해서는 IADOption 에서 true로 반영해야 정보를 받아올 수 있습니다.
- IsNG (정상/비정상 판별 결과입니다.)
- Anomaly Score (이미지의 대표 anomaly score, 최소, 최대값입니다)
- Segmented Objects (Anomaly Detection을 통해 검출된 영역의 정보를 받아 옵니다.)
- Mask (Mask 이미지 정보입니다.)
- Scoremap (Scoremap 이미지 정보입니다.)
- Heatmap (Heatmap 이미지 정보입니다.)
- Insepction Time (추론 API 실행에 소요된 시간을 밀리초 단위로 받아 옵니다.)
Optional
srImage.Dispose();
이 예제에서는 검사에 사용했던 Bitmap들을 더 이상 사용할 곳이 없이게 Dispose() 합니다.
많은 수의 이미지를 한번에 검사
앞선 예제에서는 '한 장의 이미지'를 검사하는 시나리오에 대해서 살펴보았습니다. 하지만 '많은 수의 이미지'를 한번에 검사하고자 하는 경우에 대해 알아보겠습니다.
샘플 코드에서 몇가지 부분을 수정하여 이 상황을 해결해봅시다.
우선 Bitmap을 배열로 만들어 '많은 수의 이미지' 데이터를 준비합니다. 아래와 같습니다.
SrImage[] srImages = new SrImage[]
{
new SrImage(@"..\...\sample1.png"),
new SrImage(@"..\...\sample2.png"),
new SrImage(@"..\...\sample3.png"),
new SrImage(@"..\...\sample4.png")
};
이후 생성자에서 숨어있던 마지막 인자를 사용할 수 있습니다.
var engine = new IADEngine(modelPath, gpuIndex, 4)
마지막 인자는 '최대 이미지 수' 를 의미하며 한번에 (병렬로) 처리할 수 있는 이미지 수를 의미합니다.
큰 값이 설정될수록 GPU 메모리 할당량이 커지므로, 메모리가 부족하다면 작은 수로 설정해 주세요.
마지막으로 Inspect() 함수가 포함된 라인 이후를 수정합니다. 결과를 받아오는 GetResults() 함수를 복수명으로 변경 후 배열로 받아올 수 있도록 변경합니다.
IADResult[] results =engine.Inspection(srImages);
이제 코드를 동작하여 '많은 수의 이미지'를 검사할 수 있습니다.