Development Guide¶
Handle Creation¶
To use SaigeVision inference functions, you need an inference handle and a result handle.
The inference handle can be created from a trained model file. When the inference handle creation API is successfully called, all information contained in the model file is loaded into the inference handle for use in subsequent inference operations.
std::string trainedModelPath = "your_model_path.saigeiad";
int deviceIndex = 0;
SaigeInferenceHandle handle = nullptr;
SaigeHandleConfig config;
SaigeCreateInferenceHandle(
&handle, kProjectTypeIAD, trainedModelPath.c_str(), deviceIndex, &config, 0
);
(Common) Batch size setting
If you want to perform batch inference on multiple images, adjust the inference handle settings and use the 'SAIGE_SET_BATCH_SIZE' flag.
std::string trainedModelPath = "your_model_path.saigeiad";
int deviceIndex = 0;
SaigeInferenceHandle handle = nullptr;
SaigeHandleConfig config;
config.batchSize = 2;
SaigeCreateInferenceHandle(
&handle, kProjectTypeIAD, trainedModelPath.c_str(), deviceIndex, &config, SAIGE_SET_BATCH_SIZE
);
(Common) Applying Inference Optimization
To perform inference at a faster speed, use the 'SAIGE_OPTIMIZE_HANDLE' flag to apply inference optimization.
std::string trainedModelPath = "your_model_path.saigeiad";
int deviceIndex = 0;
SaigeInferenceHandle handle = nullptr;
SaigeHandleConfig config;
SaigeCreateInferenceHandle(
&handle, kProjectTypeIAD, trainedModelPath.c_str(), deviceIndex, &config, SAIGE_OPTIMIZE_HANDLE
);
(SEG) Setting Inspection Size
If the project type is Segmentation, you can specify an inspection size. Modify the inference handle settings and use the 'SAIGE_SET_INSPECTION_SIZE' flag.
std::string trainedModelPath = "your_model_path.saigeseg";
int deviceIndex = 0;
SaigeInferenceHandle handle = nullptr;
SaigeHandleConfig config;
config.inspectionSizeWidth = 512;
config.inspectionSizeHeight = 512;
SaigeCreateInferenceHandle(
&handle, kProjectTypeSEG, trainedModelPath.c_str(), deviceIndex, &config, SAIGE_SET_INSPECTION_SIZE
);
The result handle is used to store and retrieve inference results. When using the inference API, results are stored in the result handle, which can then be accessed using the inference result APIs.
SaigeInferenceResult result = nullptr;
SaigeCreateInferenceResult(&result);
You can find more detailed information about handle creation in Handle Creation in the SaigeVision API documentation.
Checking Model Information (Optional)¶
You can retrieve model information set during training from the inference handle. 'SaigeModelInfo' is a structure that allows easy access to model details through its member variables.
SaigeInferenceHandle handle = ...;
SaigeModelInfo modelInfo;
SaigeGetModelInfo(handle, &modelInfo);
std::cout << "Network Type: " << modelInfo.networkType << std::endl;
std::cout << "Number of Classes: " << modelInfo.numOfClasses << std::endl;
std::cout << "Trained Developer Version: " << modelInfo.developerVersion << std::endl;
Skipping the model information check does not affect inference performance.
For more detailed information on model-related SaigeVision APIs, refer to Model Information
Checking and Setting Inference Options (Optional)¶
You can retrieve inference options from the inference handle. 'SaigeInferenceOption' is a structure that allows easy access to inference options through its member variables.
SaigeInferenceHandle handle = ...;
SaigeInferenceOption options;
SaigeGetInferenceOption(handle, &options);
std::cout << "Calc Time: " << (options.calcTime ? "True" : "False") << std::endl;
std::cout << "Anomaly Score Threshold: (" << options.anomalyScoreThreshold << ")"
<< std::endl;
std::cout << "Calc Mask: " << (options.calcMask ? "True" : "False") << std::endl;
std::cout << "Object Boundary Threshold: (" << options.objectBoundaryThreshold << ")"
<< std::endl;
You can also set new inference options. When you update the options, the values loaded in the inference handle are modified and applied during inference.
To set new options, populate the desired values in the 'SaigeInferenceOption' structure's member variables, and call the inference option setting API. Ensure that you specify the appropriate flags based on the current project type and the options you want to configure.
SaigeInferenceHandle handle = ...;
SaigeInferenceOption options;
options.calcHeatmap = true;
unsigned int flags = SAIGE_SET_CALC_HEATMAP
SaigeSetInferenceOption(handle, &options, flags);
When setting multiple options simultaneously, combine each flag using the bitwise OR operator ('|').
SaigeInferenceHandle handle = ...;
SaigeInferenceOption options;
options.calcHeatmap = true;
options.calcObject = true;
options.calcObjectAreaAndApplyThreshold = true;
options.calcObjectScoreAndApplyThreshold = true;
unsigned int flags = SAIGE_SET_CALC_HEATMAP | SAIGE_SET_CALC_OBJECT |
SAIGE_SET_CALC_OBJECT_AREA_AND_APPLY_THRESHOLD |
SAIGE_SET_CALC_OBJECT_SCORE_AND_APPLY_THRESHOLD;
SaigeSetInferenceOption(handle, &options, flags);
If you also want to overwrite the values stored in the model file, add the 'SAIGE_WRITE_ON_MODEL_FILE' flag.
SaigeInferenceHandle handle = ...;
SaigeInferenceOption options;
options.calcHeatmap = true;
unsigned int flags = SAIGE_SET_CALC_HEATMAP | SAIGE_WRITE_ON_MODEL_FILE
SaigeSetInferenceOption(handle, &options, flags);
Skipping the process of checking and setting inference options does not affect inference performance.
For more details on inference option-related SaigeVision APIs, refer to Inference Option
Inference¶
Inference is performed using an inference handle, a result handle, and an image.
There are three ways to pass an image to the inference API, each with its corresponding API:
-
You can perform inference using an image file path.
SaigeInferenceHandle handle = ...; SaigeInferenceResult result = ...; std::string imagePath = "your_image_path.png" SaigeInferFromImageFile(handle, imagePath.c_str(), result);
-
You can perform inference using single image data represented as an 'unsigned char' array. To obtain accurate results, ensure the image width, height, and flags are correctly set.
SaigeInferenceHandle handle = ...; SaigeInferenceResult result = ...; unsigned char* image = ...; int w = ..., h = ...; unsigned int flags = SAIGE_IMAGE_DATA_FLAG_COLOR; SaigeInferFromByteArray(handle, image, w, h, flags, result);
-
You can perform batch inference using image data represented as a 2D 'unsigned char' array. All images in the batch must have the same width and height. Again, set the width, height, and flags correctly for accurate results.
int batchSize = ...; SaigeInferenceHandle handle = ...; SaigeInferenceResult* batchResults = ...; unsigned char** batchImages = ...; int w = ..., h = ...; unsigned int flags = SAIGE_IMAGE_DATA_FLAG_COLOR; SaigeInferFromMultipleByteArray(handle, batchSize, batchImages, w, h, flags, batchResults); -
You can handle images with 16-bit depth using an 'unsigned short' array. Use utility functions like SaigeGetImageData and SaigeConvertImageType to determine the image type and obtain the appropriate flag for the inference function. Note that the data should be cast to 'const unsigned char*' when passed to the inference function.
SaigeInferenceHandle handle = ...; SaigeInferenceResult result = ...; int w, h, c, type; void* image_ptr = SaigeGetImageData(path, &w, &h, &c, &type); if (type == SaigeImageType::U16){ unsigned short* image_data = image_ptr; for(int i=0; i<h; ++i){ for(int j=0; j<w; ++j){ for(int k=0; k<c; ++k){ image_data[i*w*c + j*c + k] ... // image operation } } } } unsigned int imageFlag = SaigeConvertImageType(c, type); int retval = SaigeInferFromByteArray(handle, (const unsigned char*)image_ptr, w, h, imageFlag, result);
See Inference for more on inference-related SaigeVision APIs.
Inference Results¶
After successfully completing inference, you can retrieve the result information from the result handle.
Use the appropriate API based on the specific result item you need. For instance, the API to retrieve the image's normality status in an IAD inference result differs from the API to retrieve the score.
SaigeInferenceResult result = ...;
bool isNg;
SaigeGetInferenceResultIsNg(result, &isNg);
double anomalyScore, scoreMin, scoreMax;
SaigeGetInferenceResultAnomalyScores(result, &anomalyScore, &scoreMin, &scoreMax);
For result items with multiple values, first retrieve the result count, then fetch each value.
int numSegObj;
std::vector<SaigeSegmentedObject> segObjs;
SaigeGetInferenceResultNumOfSegmentedObjects(result, &numSegObj);
segObjs.resize(numSegObj);
SaigeGetInferenceResultSegmentedObjects(result, segObjs.data());
For more details on inference result-related SaigeVision APIs, see Inference Result
Handle Destruction¶
After completing all inferences, destroy the inference and result handles to release allocated memory and prevent memory leaks.
SaigeInferenceHandle handle = ...;
SaigeInferenceResult result = ...;
SaigeDestroyInferenceHandle(handle);
SaigeDestroyInferenceResult(result);
Refer to Handle Destruction for more information on handle destruction-related SaigeVision APIs.