summaryrefslogtreecommitdiff
path: root/sci_gateway1/cpp/opencv_trainImageCategoryClassifier.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sci_gateway1/cpp/opencv_trainImageCategoryClassifier.cpp')
-rw-r--r--sci_gateway1/cpp/opencv_trainImageCategoryClassifier.cpp349
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;
+ }
+ /* ==================================================================== */
+}