diff options
Diffstat (limited to 'sci_gateway1/cpp/opencv_trainImageCategoryClassifier.cpp')
-rw-r--r-- | sci_gateway1/cpp/opencv_trainImageCategoryClassifier.cpp | 349 |
1 files changed, 349 insertions, 0 deletions
diff --git a/sci_gateway1/cpp/opencv_trainImageCategoryClassifier.cpp b/sci_gateway1/cpp/opencv_trainImageCategoryClassifier.cpp new file mode 100644 index 0000000..e2a504a --- /dev/null +++ b/sci_gateway1/cpp/opencv_trainImageCategoryClassifier.cpp @@ -0,0 +1,349 @@ +/*************************************************** +Author : Rohit Suri +***************************************************/ +#include <iostream> +#include <opencv2/opencv.hpp> +#include <opencv2/nonfree/nonfree.hpp> +#include <opencv2/ml/ml.hpp> + +using namespace std; +using namespace cv; + +extern "C" +{ + #include "api_scilab.h" + #include "Scierror.h" + #include "BOOL.h" + #include <localization.h> + #include "sciprint.h" + int opencv_trainImageCategoryClassifier(char *fname, unsigned long fname_len) + { + // Error management variables + SciErr sciErr; + + //------Local variables------// + int upright = 1; + Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create("FlannBased"); + Ptr<DescriptorExtractor> extractor = new SurfDescriptorExtractor(1, 4, 2, 1, int(upright)); + BOWImgDescriptorExtractor bowDE(extractor, matcher); + SurfFeatureDetector detector(1, 4, 2, 1, int(upright)); + char *fileName = NULL; + Mat dictionary,inp,features; + vector<KeyPoint> keyPoints; + + + int *piAddr = NULL; + int *piChild = NULL; + int iRows, iCols; + char **pstData = NULL; + int *piLen = NULL; + int *count = NULL; + char **description = NULL; + char ***location = NULL; + char *bagOfFeaturesLocation = NULL; + int descriptionCount; + char *classifierLocation = "classifier.yml"; + char *objectType = "classifier"; + //------Check number of parameters------// + CheckInputArgument(pvApiCtx, 2, 2); + CheckOutputArgument(pvApiCtx, 1, 1); + + //------Get input arguments------// + sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddr); + if (sciErr.iErr) + { + printError(&sciErr, 0); + return 0; + } + if(!isListType(pvApiCtx, piAddr)) + { + Scierror(999, "Error: The input argument #1 is not of type imageSet.\n"); + return 0; + } + + // Extracting object type and checking if type is imageSet + sciErr = getMatrixOfStringInList(pvApiCtx, piAddr, 1, &iRows, &iCols, NULL, NULL); + if(sciErr.iErr) + { + printError(&sciErr, 0); + return 0; + } + + piLen = (int*)malloc(sizeof(int) * iRows * iCols); + + sciErr = getMatrixOfStringInList(pvApiCtx, piAddr, 1, &iRows, &iCols, piLen, NULL); + if(sciErr.iErr) + { + printError(&sciErr, 0); + return 0; + } + + pstData = (char**)malloc(sizeof(char*) * iRows * iCols); + + for(int iter = 0 ; iter < iRows * iCols ; iter++) + { + pstData[iter] = (char*)malloc(sizeof(char) * (piLen[iter] + 1));//+ 1 for null termination + } + + sciErr = getMatrixOfStringInList(pvApiCtx, piAddr, 1, &iRows, &iCols, piLen, pstData); + if(sciErr.iErr) + { + printError(&sciErr, 0); + return 0; + } + + if(!(strcmp(pstData[0],"imageSet")==0)) + { + Scierror(999, "Error: The input argument #1 is not of type imageSet.\n"); + return 0; + } + + // Extracting Description attribute of input argument + sciErr = getMatrixOfStringInList(pvApiCtx, piAddr, 2, &iRows, &iCols, NULL, NULL); + if(sciErr.iErr) + { + printError(&sciErr, 0); + return 0; + } + + piLen = (int*)malloc(sizeof(int) * iRows * iCols); + + sciErr = getMatrixOfStringInList(pvApiCtx, piAddr, 2, &iRows, &iCols, piLen, NULL); + if(sciErr.iErr) + { + printError(&sciErr, 0); + return 0; + } + + description = (char**)malloc(sizeof(char*) * iRows * iCols); + + for(int iter = 0 ; iter < iRows * iCols ; iter++) + { + description[iter] = (char*)malloc(sizeof(char) * (piLen[iter] + 1));//+ 1 for null termination + } + + sciErr = getMatrixOfStringInList(pvApiCtx, piAddr, 2, &iRows, &iCols, piLen, description); + if(sciErr.iErr) + { + printError(&sciErr, 0); + return 0; + } + descriptionCount = iRows; + + // Extracting Count attribute of input argument + sciErr = getMatrixOfInteger32InList(pvApiCtx, piAddr, 3, &iRows, &iCols, &count); + if(sciErr.iErr) + { + printError(&sciErr, 0); + return 0; + } + + location = (char***) malloc(sizeof(char**) * descriptionCount); + sciErr = getListItemAddress(pvApiCtx, piAddr, 4, &piChild); + if(sciErr.iErr) + { + printError(&sciErr, 0); + return 0; + } + for(int iter = 1; iter<=descriptionCount; iter++) + { + sciErr = getMatrixOfStringInList(pvApiCtx, piChild, iter, &iRows, &iCols, NULL, NULL); + if(sciErr.iErr) + { + printError(&sciErr, 0); + return 0; + } + + piLen = (int*)malloc(sizeof(int) * iRows * iCols); + + sciErr = getMatrixOfStringInList(pvApiCtx, piChild, iter, &iRows, &iCols, piLen, NULL); + if(sciErr.iErr) + { + printError(&sciErr, 0); + return 0; + } + + location[iter-1] = (char**)malloc(sizeof(char*) * iRows * iCols); + + for(int colIter = 0 ; colIter < iRows * iCols ; colIter++) + { + location[iter-1][colIter] = (char*)malloc(sizeof(char) * (piLen[colIter] + 1));//+ 1 for null termination + } + + sciErr = getMatrixOfStringInList(pvApiCtx, piChild, iter, &iRows, &iCols, piLen, location[iter-1]); + if(sciErr.iErr) + { + printError(&sciErr, 0); + return 0; + } + } + // Second argument + sciErr = getVarAddressFromPosition(pvApiCtx, 2, &piAddr); + if (sciErr.iErr) + { + printError(&sciErr, 0); + return 0; + } + if(!isListType(pvApiCtx, piAddr)) + { + Scierror(999, "Error: The input argument #2 is not of type bagOfFeatures.\n"); + return 0; + } + + // Extracting object type and checking if type is bagOfFeatures + sciErr = getMatrixOfStringInList(pvApiCtx, piAddr, 1, &iRows, &iCols, NULL, NULL); + if(sciErr.iErr) + { + printError(&sciErr, 0); + return 0; + } + + piLen = (int*)malloc(sizeof(int) * iRows * iCols); + + sciErr = getMatrixOfStringInList(pvApiCtx, piAddr, 1, &iRows, &iCols, piLen, NULL); + if(sciErr.iErr) + { + printError(&sciErr, 0); + return 0; + } + + pstData = (char**)malloc(sizeof(char*) * iRows * iCols); + + for(int iter = 0 ; iter < iRows * iCols ; iter++) + { + pstData[iter] = (char*)malloc(sizeof(char) * (piLen[iter] + 1));//+ 1 for null termination + } + + sciErr = getMatrixOfStringInList(pvApiCtx, piAddr, 1, &iRows, &iCols, piLen, pstData); + if(sciErr.iErr) + { + printError(&sciErr, 0); + return 0; + } + + if(!(strcmp(pstData[0],"bagOfFeatures")==0)) + { + Scierror(999, "Error: The input argument #2 is not of type bagOfFeatures.\n"); + return 0; + } + // Extracting name of next argument takes three calls to getMatrixOfString + sciErr = getMatrixOfStringInList(pvApiCtx, piAddr, 2, &iRows, &iCols, NULL, NULL); + if (sciErr.iErr) + { + printError(&sciErr, 0); + return 0; + } + + piLen = (int*) malloc(sizeof(int) * iRows * iCols); + + sciErr = getMatrixOfStringInList(pvApiCtx, piAddr, 2, &iRows, &iCols, piLen, NULL); + if (sciErr.iErr) + { + printError(&sciErr, 0); + return 0; + } + + pstData = (char**) malloc(sizeof(char*) * iRows * iCols); + for(int iterPstData = 0; iterPstData < iRows * iCols; iterPstData++) + { + pstData[iterPstData] = (char*) malloc(sizeof(char) * piLen[iterPstData] + 1); + } + + sciErr = getMatrixOfStringInList(pvApiCtx, piAddr, 2, &iRows, &iCols, piLen, pstData); + if (sciErr.iErr) + { + printError(&sciErr, 0); + return 0; + } + + if(iRows!=1 || iCols!=1) + { + Scierror(999, "1x1 Matrix expected for bagOfFeatures argument."); + return 0; + } + bagOfFeaturesLocation = pstData[0]; + //------Actual processing------// + FileStorage fs(bagOfFeaturesLocation, FileStorage::READ); + fs["dictionary"] >> dictionary; + fs.release(); + if(dictionary.rows==0 || dictionary.cols==0) + { + sciprint("Error: The provided file for bagOfFeatures may be invalid.\n"); + } + sciprint("Training an image category classifier for %d categories.\n",descriptionCount); + sciprint("-------------------------------------------------------\n\n"); + for(int i=0;i<descriptionCount;i++) + { + sciprint("# Category %d: %s\n",i+1,description[i]); + } + sciprint("\n"); + int dictionarySize = dictionary.rows; + Mat labels(0, 1, CV_32FC1); + Mat trainingData(0, dictionarySize, CV_32FC1); + bowDE.setVocabulary(dictionary); + for(int i=0; i<descriptionCount;i++) + { + sciprint("# Encoding features for Category %d ...",i+1); + for(int j=0; j<count[i]; j++) + { + features.release(); + keyPoints.clear(); + fileName = location[i][j]; + inp = imread(fileName); + detector.detect(inp,keyPoints); + bowDE.compute(inp,keyPoints,features); + trainingData.push_back(features); + labels.push_back((float) i); + } + sciprint("done.\n"); + } + sciprint("\n# Training the category classifier..."); + CvSVMParams params; + params.kernel_type=CvSVM::RBF; + params.svm_type=CvSVM::C_SVC; + params.gamma=0.50625000000000009; + params.C=312.50000000000000; + params.term_crit=cvTermCriteria(CV_TERMCRIT_ITER,100,0.000001); + CvSVM svm; + svm.train(trainingData,labels,cv::Mat(),cv::Mat(),params); + svm.save(classifierLocation); + sciprint("done.\n"); + //------Create output arguments------// + sciErr = createList(pvApiCtx, nbInputArgument(pvApiCtx) + 1, 4, &piAddr); + if(sciErr.iErr) + { + printError(&sciErr, 0); + return 0; + } + sciErr = createMatrixOfStringInList(pvApiCtx, nbInputArgument(pvApiCtx)+1, piAddr, 1, 1, 1, &objectType); + if(sciErr.iErr) + { + printError(&sciErr, 0); + return 0; + } + sciErr = createMatrixOfStringInList(pvApiCtx, nbInputArgument(pvApiCtx)+1, piAddr, 2, 1, 1, &classifierLocation); + if(sciErr.iErr) + { + printError(&sciErr, 0); + return 0; + } + sciErr = createMatrixOfStringInList(pvApiCtx, nbInputArgument(pvApiCtx)+1, piAddr, 3, 1, 1, &bagOfFeaturesLocation); + if(sciErr.iErr) + { + printError(&sciErr, 0); + return 0; + } + sciErr = createMatrixOfStringInList(pvApiCtx, nbInputArgument(pvApiCtx)+1, piAddr, 4, descriptionCount, 1, description); + if(sciErr.iErr) + { + printError(&sciErr, 0); + return 0; + } + + //------Return Arguments------// + AssignOutputVariable(pvApiCtx, 1) = nbInputArgument(pvApiCtx)+1; + ReturnArguments(pvApiCtx); + return 0; + } + /* ==================================================================== */ +} |