SaigeVision C/C++  1.4.7
SaigeVision API document for C/C++
ExampleClsRuntimeBatchInspection.cpp

This is an example of how to inspect sample images by using Batch inspection mode Classification module. More details about this example.

#include "SRUtils.h"
/* define this variable when user want to use new additional score other than preset values. */
//#define SR_USE_NEW_ADDITIONAL_SCORE
/* define this variable when user want to limit the forward time of classfication algorithm. */
//#define SR_USE_FORWARD_TIME_LIMIT
int main()
{
/***********************************************************
* 최대 이미지 수 설정 , Set max # of images to inspect at once
* - 한번에 검사할 최대 이미지 수를 설정합니다. (Set maximum number of images to inspect at once)
* - 기본적으로 2의 배수로 설정할 것을 추천드리며 크게 설정할 수록
* GPU 메모리 할당량이 커지니 메모리가 부족하다면 더 작은 수로 설정해주세요.
* (Recommend to set this value as multiple of 2, and if GPU memory is low, set the value as lower number.)
* - 최대 이미지 수 보다 많은 이미지가 들어올 시에 내부적으로 여러번의 검사를 수행하게 됩니다.
* (If more images than nMaxImages are passed to the inspection function, multiple inspections are conducted internally.)
***********************************************************/
int nMaxImages = 8; /* 4, 8, 16, 32, 64 */
std::wstring data_dir = L"../../../examples/data";
// trained model path
std::wstring trainedModelPath = data_dir + L"/models/textile_sample_model.srCls";
// image paths to classify
std::vector<std::wstring> imagePaths(6);
imagePaths[0] = data_dir + L"/images/Textile/class1_ok/000001.png";
imagePaths[1] = data_dir + L"/images/Textile/class1_ng/000002.png";
imagePaths[2] = data_dir + L"/images/Textile/class2_ok/000001.png";
imagePaths[3] = data_dir + L"/images/Textile/class2_ng/000002.png";
imagePaths[4] = data_dir + L"/images/Textile/class3_ok/000001.png";
imagePaths[5] = data_dir + L"/images/Textile/class3_ng/000002.png";
/***********************************************************
* 0. 이미지 인풋 타입 설정
* inputImageType -
* UCGrayImage: from memory(8bit unsigned char gray image)
* UCColorImage: from memory(8bit unsigned char color image)
* UIColorImage: from memory(32bit unsigned int color image)
***********************************************************/
//eSRInputImageType inputImageType = eSRInputImageType::UCGrayImage;
eSRInputImageType inputImageType = eSRInputImageType::UCColorImage;
//eSRInputImageType inputImageType = eSRInputImageType::UIColorImage;
/***********************************************************
* 0-1. 정보 띄우기 단계 설정 (Verbosity)
* verbosity -
* 0: only warning
* 1: warning + model info
* 2: warning + model info + result info
* 3: warning + model info + result info + image display
* displayTime - 결과 이미지 display 하는 시간 (milliseconds)
* resizeFactor - 결과 이미지 display 하는 스케일 (display 크기 = 원본 크기 * resizeFactor)
***********************************************************/
int verbosity = 3;
int displayTime = 100;
double resizeFactor = 1.0;
/***********************************************************
* 0-2. GPU 번호 설정
* gpuIndex - 사용하고자 하는 gpu의 번호
* Multi GPU 가 가능한 License의 경우에 한하여 gpuIndex를
* 0~3까지 설정해 줄 수 있다. 아닌 경우 gpuIndex는 0을 사용하여야 한다.
***********************************************************/
int gpuIndex = 0;
/***********************************************************
* 1. 모델 파일 handle 생성,
* Create handles for model files and inspection results
***********************************************************/
ClsTestHandle handle = SR_CreateClsTestHandleByWideCharPath(trainedModelPath.c_str());
if (handle == nullptr)
{
std::wcout << "Saige Vision failed: Please check the file path of trained model." << std::endl;
}
int nTotalImages = imagePaths.size();
std::vector<ClsTestResult> clsTestResults(nTotalImages);
for (size_t i_img = 0; i_img < nTotalImages; i_img++)
{
clsTestResults[i_img] = SR_MakeClsTestResult();
}
/***********************************************************
* 2. 클래스 정보 확인 (Optional)
* Check class information
***********************************************************/
// Print classification Test Parameters() by calling one fuctions
srStatus = SR_PrintClsTestParameters(handle);
if (srStatus != NO_ERROR_OUT)
{
PrintErrorType(srStatus, verbosity);
// if you get this error, it's possible that the handle is not created.
return -1;
}
// Get classification test parameters one by one
int numberOfClassesOutput = 0;
int maxStrLenOfClassName = 0;
// Get the number of classes
srStatus = SR_GetClsTestNumberOfClasses(handle, &numberOfClassesOutput);
if (srStatus != NO_ERROR_OUT)
{
PrintErrorType(srStatus, verbosity);
// if you get this error, it's possible that input pointer is not allocated (nullptr).
return -1;
}
// Get the maximum length of class names
srStatus = SR_GetClsTestMaxStrLenOfClassName(handle, &maxStrLenOfClassName);
if (srStatus != NO_ERROR_OUT)
{
PrintErrorType(srStatus, verbosity);
// if you get this error, it's possible that input pointer is not allocated (nullptr).
return -1;
}
std::vector<std::string> classNames(numberOfClassesOutput);
std::vector<std::wstring> wClassNames(numberOfClassesOutput);
std::vector<int> classColorsOutput(numberOfClassesOutput);
std::vector<int> additionalScoreOutput(numberOfClassesOutput);
char* classNameOutput = new char[maxStrLenOfClassName];
wchar_t* wClassNameOutput = new wchar_t[maxStrLenOfClassName];
for (int i = 0; i < numberOfClassesOutput; i++)
{
// Get a color of single class
srStatus = SR_GetClsTestOneClassColor(handle, i, &(classColorsOutput[i]));
if (srStatus != NO_ERROR_OUT)
{
PrintErrorType(srStatus, verbosity);
// if you get this error, it's possible that the input index is out of bound(# of classes) or input pointer is not allocated (nullptr).
return -1;
}
// Get a name of single class by multi byte char (char*)
srStatus = SR_GetClsTestOneClassNameWithMultiByteChar(handle, i, classNameOutput);
if (srStatus != NO_ERROR_OUT)
{
PrintErrorType(srStatus, verbosity);
// if you get this error, it's possible that the input index is out of bound(# of classes) or input pointer is not allocated (nullptr).
return -1;
}
// Get a name of single class by wide char (wchar_t*)
srStatus = SR_GetClsTestOneClassNameWithWideChar(handle, i, wClassNameOutput);
if (srStatus != NO_ERROR_OUT)
{
PrintErrorType(srStatus, verbosity);
// if you get this error, it's possible that the input index is out of bound(# of classes) or input pointer is not allocated (nullptr).
return -1;
}
classNames[i] = classNameOutput;
wClassNames[i] = wClassNameOutput;
}
delete[] classNameOutput;
delete[] wClassNameOutput;
/***********************************************************
* 3. 검사 옵션 확인 및 수정 (Optional)
* Check inspection options and set new values
***********************************************************/
// Get the additional score for each class
srStatus = SR_GetClsTestAdditionalScore(handle, additionalScoreOutput.data());
if (srStatus != NO_ERROR_OUT)
{
PrintErrorType(srStatus, verbosity);
// if you get this error, it's possible that input pointer is not allocated (nullptr).
return -1;
}
#ifdef SR_USE_NEW_ADDITIONAL_SCORE
std::vector<int> additionalScore(numberOfClassesOutput);
for (int i = 0; i < numberOfClassesOutput; i++)
{
additionalScore[i] = 10;
}
srStatus = SR_SetClsTestAdditionalScore(handle, numberOfClassesOutput, additionalScore.data(), true);
if (srStatus != NO_ERROR_OUT)
{
PrintErrorType(srStatus, verbosity);
// if you get this error, it's possible that the input's [# of classes] does not match the model's or input pointer is not allocated (nullptr).
return -1;
}
#endif
#ifdef SR_USE_FORWARD_TIME_LIMIT
float timeLimit = 1000; // milliseconds
srStatus = SR_SetClsTestForwardTimeLimitVariables(handle, timeLimit, true, true);
if (srStatus != NO_ERROR_OUT)
{
PrintErrorType(srStatus, verbosity);
// if you get this error, it's possible that handle is not created.
return -1;
}
#endif
#ifndef SR_USE_FORWARD_TIME_LIMIT
srStatus = SR_SetClsTestIsToUseForwardTimeLimit(handle, false, true);
if (srStatus != NO_ERROR_OUT)
{
PrintErrorType(srStatus, verbosity);
// if you get this error, it's possible that handle is not created.
return -1;
}
#endif
/***********************************************************
* 4. 메모리를 GPU 및 CPU에 할당합니다.
* Allocate GPU and CPU memory
***********************************************************/
srStatus = SR_LoadClsTestNetworkInGPU(handle, gpuIndex, nMaxImages);
if (srStatus != NO_ERROR_OUT)
{
PrintErrorType(srStatus, verbosity);
// if you get this error, it's possible that the inserted index is not applicable.
return -1;
}
std::vector<int> heights(nTotalImages, 0);
std::vector<int> widths(nTotalImages, 0);
unsigned char** ucImageData = new unsigned char*[nTotalImages]; // arrays of unsigned char image data
unsigned int** uiImageData = new unsigned int*[nTotalImages]; // arrays of unsigned int image data
for (size_t i_img = 0; i_img < nTotalImages; i_img++)
{
uiImageData[i_img] = nullptr;
ucImageData[i_img] = nullptr;
if (inputImageType == eSRInputImageType::UIColorImage)
{
uiImageData[i_img] = (unsigned int*)GetImageDataByInputImageType(imagePaths[i_img], inputImageType, heights[i_img], widths[i_img]);
}
else
{
ucImageData[i_img] = (unsigned char*)GetImageDataByInputImageType(imagePaths[i_img], inputImageType, heights[i_img], widths[i_img]);
}
}
/***********************************************************
* 5. 이미지 검사하기, Inspect images
***********************************************************/
eErrorType errorType = NO_ERROR_OUT;
if (inputImageType == eSRInputImageType::UCGrayImage)
{
errorType = SR_ApplyClsTestFromMultiple8bitCharGrayArrays(handle, nTotalImages, ucImageData, heights.data(), widths.data(), clsTestResults.data());
}
else if (inputImageType == eSRInputImageType::UCColorImage)
{
errorType = SR_ApplyClsTestFromMultiple8bitCharColorArrays(handle, nTotalImages, ucImageData, heights.data(), widths.data(), clsTestResults.data());
}
else if (inputImageType == eSRInputImageType::UIColorImage)
{
errorType = SR_ApplyClsTestFromMultipleUnsignedIntColorArrays(handle, nTotalImages, uiImageData, heights.data(), widths.data(), clsTestResults.data());
}
if (srStatus != NO_ERROR_OUT)
{
PrintErrorType(srStatus, verbosity);
std::cout << "Fail to classify" << std::endl;
}
else
{
/***********************************************************
* 6. 검사 결과 받아오기, Retrieve inspection results
***********************************************************/
if (verbosity >= 2)
{
long inspectionTimeOutput = 0, loadImageTimeOutput = 0;
// Get the inspection time
srStatus = SR_GetClsTestInspectionTime(clsTestResults[0], &inspectionTimeOutput);
if (srStatus != NO_ERROR_OUT)
{
// if you get this error, it's possible that the input pointer is not allocated (nullptr).
PrintErrorType(srStatus, verbosity);
}
// Get the image-loading time
srStatus = SR_GetClsTestLoadImageTime(clsTestResults[0], &loadImageTimeOutput);
if (srStatus != NO_ERROR_OUT)
{
// if you get this error, it's possible that the input pointer is not allocated (nullptr).
PrintErrorType(srStatus, verbosity);
}
std::cout << "====== classification Test Result (Total) ======" << std::endl;
std::cout << " - Total Image Loading time: " << loadImageTimeOutput << std::endl;
std::cout << " - Total Inspection time: " << inspectionTimeOutput << std::endl;
}
for (size_t i_img = 0; i_img < nTotalImages; i_img++)
{
std::vector<int> scoreOutput(numberOfClassesOutput);
int classOutput = -1;
srStatus = SR_GetClsTestResultScore(clsTestResults[i_img], numberOfClassesOutput, scoreOutput.data(), true);
if (srStatus != NO_ERROR_OUT)
{
PrintErrorType(srStatus, verbosity);
// if you get this error, it's possible that the input's [# of classes] does not match the result's or input pointer is not allocated (nullptr).
continue; // jump to next image
}
srStatus = SR_GetClsTestResultClass(clsTestResults[i_img], &classOutput);
if (srStatus != NO_ERROR_OUT)
{
PrintErrorType(srStatus, verbosity);
// if you get this error, it's possible that input pointer is not allocated (nullptr).
continue; // jump to next image
}
// Display and draw
if (verbosity >= 2)
{
std::cout << "====== classification Test Result (Single) ======" << std::endl;
std::wcout << imagePaths[i_img] << std::endl;
for (int j = 0; j < numberOfClassesOutput; j++)
{
std::cout << " - " << j << "-th class score: " << scoreOutput[j] << std::endl;
}
std::cout << " - Result Class: " << classOutput << std::endl;
}
if (verbosity >= 3)
{
cv::Mat image = cv::Mat();
if (inputImageType == eSRInputImageType::UCGrayImage)
{
image = cv::Mat(heights[i_img], widths[i_img], CV_8UC1, ucImageData[i_img]);
image = image.clone(); /* to prevent modifying raw data */
}
else if (inputImageType == eSRInputImageType::UCColorImage)
{
image = cv::Mat(heights[i_img], widths[i_img], CV_8UC3, ucImageData[i_img]);
image = image.clone(); /* to prevent modifying raw data */
}
else if (inputImageType == eSRInputImageType::UIColorImage)
{
image = cv::Mat(heights[i_img], widths[i_img], CV_8UC4, uiImageData[i_img]);
image = image.clone(); /* to prevent modifying raw data */
}
else
{
int isSuccess = OpenImageFile(imagePaths[i_img].c_str(), image);
if (isSuccess == 0)
{
std::cout << "Saige Vision FAILED: Fail to open image file to display" << std::endl;
continue;
}
}
if (image.channels() == 4)
{
cv::cvtColor(image, image, cv::COLOR_BGRA2BGR);
}
if (image.channels() == 1)
{
cv::cvtColor(image, image, cv::COLOR_GRAY2BGR);
}
// get class color
int colorTmp = classColorsOutput[classOutput];
unsigned char r = (colorTmp >> 16) & 0xFF;
unsigned char g = (colorTmp >> 8) & 0xFF;
unsigned char b = (colorTmp) & 0xFF;
cv::Scalar classColor = cv::Scalar(b, g, r);
cv::putText(image, classNames[classOutput],
cv::Point(int(image.size().width * 0.1), int(image.size().height * 0.9)), // Coordinates
cv::FONT_HERSHEY_COMPLEX_SMALL, // Font
2.0, // Scale. 2.0 = 2x bigger
classColor, // BGR Color
4 // Line Thickness (Optional)
);
cv::namedWindow("classification Result", cv::WINDOW_NORMAL);
cv::resizeWindow("classification Result", image.size().width * resizeFactor, image.size().height * resizeFactor);
cv::imshow("classification Result", image);
cv::waitKey(displayTime);
}
}
}
/***********************************************************
* 7. Handle 파괴, Destruct handles
***********************************************************/
srStatus = SR_DestroyClsTestHandle(handle);
if (srStatus != NO_ERROR_OUT)
{
PrintErrorType(srStatus, verbosity);
// if you get this error, it's possible that the input pointer is not allocated (nullptr).
return -1;
}
for (size_t i_img = 0; i_img < nTotalImages; i_img++)
{
srStatus = SR_DeleteClsTestResult(clsTestResults[i_img]);
if (srStatus != NO_ERROR_OUT)
{
PrintErrorType(srStatus, verbosity);
// if you get this error, it's possible that the input pointer is not allocated (nullptr).
return -1;
}
if (ucImageData[i_img] != nullptr)
{
delete[] ucImageData[i_img];
ucImageData[i_img] = nullptr;
}
if (uiImageData[i_img] != nullptr)
{
delete[] uiImageData[i_img];
uiImageData[i_img] = nullptr;
}
}
delete[] uiImageData;
delete[] ucImageData;
std::cout << "SaigeVision successfully completed, please press enter key to terminate" << std::endl;
std::cin.get();
return 0;
}
SR_DestroyClsTestHandle
eErrorType SR_DestroyClsTestHandle(ClsTestHandle handle)
Destruct a ClsTestHandle.
ClsTestHandle
void * ClsTestHandle
Classification file handler.
Definition: ClassifierTestDLL.h:56
SR_GetClsTestOneClassNameWithWideChar
eErrorType SR_GetClsTestOneClassNameWithWideChar(ClsTestHandle handle, const int classIdx, wchar_t *className)
Get a wide char name of certain class by given index.
SR_GetClsTestOneClassColor
eErrorType SR_GetClsTestOneClassColor(ClsTestHandle handle, const int classIdx, int *classColor)
Get a color of certain class by given index.
SR_CreateClsTestHandleByWideCharPath
ClsTestHandle SR_CreateClsTestHandleByWideCharPath(const wchar_t *filePath)
Create a ClsTestHandle via wide char path.
SR_GetClsTestNumberOfClasses
eErrorType SR_GetClsTestNumberOfClasses(ClsTestHandle handle, int *numberOfClasses)
Get the number of classes.
SR_SetClsTestAdditionalScore
eErrorType SR_SetClsTestAdditionalScore(ClsTestHandle handle, int numOfClasses, int *additionalScores, bool writeOnModelFile=true)
Set Additional scores.
SR_GetClsTestOneClassNameWithMultiByteChar
eErrorType SR_GetClsTestOneClassNameWithMultiByteChar(ClsTestHandle handle, const int classIdx, char *className)
Get a multi byte char name of certain class by given index.
SR_GetClsTestResultScore
eErrorType SR_GetClsTestResultScore(ClsTestResult clsTestResult, const int numClasses, int *scores, bool includeAddScore=false)
Get scores for each class.
GetImageDataByInputImageType
void * GetImageDataByInputImageType(const std::wstring imagePath, const eSRInputImageType inputType, int &height, int &width, int *channel=nullptr)
Get image data from a file path and image size by an allocated pointer for example projects.
Definition: SRUtils.h:138
SR_ApplyClsTestFromMultiple8bitCharColorArrays
eErrorType SR_ApplyClsTestFromMultiple8bitCharColorArrays(ClsTestHandle handle, int numberOfImages, unsigned char **imageData, int *heights, int *widths, ClsTestResult *clsTestResults)
Apply classification algorithm to 3-channels(BGR) images by 8-bit data (Batch inspection mode).
SR_ApplyClsTestFromMultipleUnsignedIntColorArrays
eErrorType SR_ApplyClsTestFromMultipleUnsignedIntColorArrays(ClsTestHandle handle, int numberOfImages, unsigned int **imageData, int *heights, int *widths, ClsTestResult *clsTestResults)
Apply classification algorithm to 4-channels(BGRA) images by 8-bit data (Batch inspection mode).
SR_LoadClsTestNetworkInGPU
eErrorType SR_LoadClsTestNetworkInGPU(ClsTestHandle handle, int GPUNumber, int batchSize=1)
Allocate required cpu & gpu memory.
SR_GetClsTestMaxStrLenOfClassName
eErrorType SR_GetClsTestMaxStrLenOfClassName(ClsTestHandle handle, int *len)
Get a maximum length of class name.
SR_DeleteClsTestResult
eErrorType SR_DeleteClsTestResult(ClsTestResult clsTestResult)
Destruct a ClsTestResult.
SR_SetClsTestIsToUseForwardTimeLimit
eErrorType SR_SetClsTestIsToUseForwardTimeLimit(ClsTestHandle handle, bool bIsToUseForwardTimeLimit, bool writeOnModelFile=true)
Set the boolean whether the current model is using time limit or not.
eSRInputImageType
eSRInputImageType
Data Type of input Image for example projects.
Definition: SRUtils.h:23
SR_MakeClsTestResult
ClsTestResult SR_MakeClsTestResult()
Construct a ClsTestResult.
SR_GetClsTestInspectionTime
eErrorType SR_GetClsTestInspectionTime(ClsTestResult clsTestResult, long *inspectionTimeInLong)
Get the inspection time.
SR_GetClsTestAdditionalScore
eErrorType SR_GetClsTestAdditionalScore(ClsTestHandle handle, int *additionalScores)
Get Additional scores.
SR_GetClsTestResultClass
eErrorType SR_GetClsTestResultClass(ClsTestResult clsTestResult, int *classIdx)
Get final class index.
SR_GetClsTestLoadImageTime
eErrorType SR_GetClsTestLoadImageTime(ClsTestResult clsTestResult, long *imageLoadingTimeInLong)
Get the image loading time.
ClassifierTestDLL.h
Header file for Classification Module.
eErrorType
eErrorType
Enumerator indicating error codes.
Definition: CommonHeaderDLL.h:25
SRUtils.h
Header file of util functions for example projects.
SR_PrintClsTestParameters
eErrorType SR_PrintClsTestParameters(ClsTestHandle handle)
Print a model parameters (Classification's class information, inspection options.....
SR_SetClsTestForwardTimeLimitVariables
eErrorType SR_SetClsTestForwardTimeLimitVariables(ClsTestHandle handle, float forwardTimeLimit, bool bIsToUseForwardTimeLimit, bool writeOnModelFile=true)
Set the Forward time limit variables.
NO_ERROR_OUT
@ NO_ERROR_OUT
Definition: CommonHeaderDLL.h:26
OpenImageFile
bool OpenImageFile(const std::wstring imagePath, cv::Mat &image, bool asCV8U=false)
Open image file for example projects.
Definition: SRUtils.h:74
SR_ApplyClsTestFromMultiple8bitCharGrayArrays
eErrorType SR_ApplyClsTestFromMultiple8bitCharGrayArrays(ClsTestHandle handle, int numberOfImages, unsigned char **imageData, int *heights, int *widths, ClsTestResult *clsTestResults)
Apply classification algorithm to 1-channel images by 8-bit data (Batch inspection mode).