diff options
author | shamikam | 2017-01-16 02:56:17 +0530 |
---|---|---|
committer | shamikam | 2017-01-16 02:56:17 +0530 |
commit | a6df67e8bcd5159cde27556f4f6a315f8dc2215f (patch) | |
tree | e806e966b06a53388fb300d89534354b222c2cad /sci_gateway1/cpp/opencv_detectMSERFeatures.cpp | |
download | FOSSEE_Image_Processing_Toolbox-a6df67e8bcd5159cde27556f4f6a315f8dc2215f.tar.gz FOSSEE_Image_Processing_Toolbox-a6df67e8bcd5159cde27556f4f6a315f8dc2215f.tar.bz2 FOSSEE_Image_Processing_Toolbox-a6df67e8bcd5159cde27556f4f6a315f8dc2215f.zip |
Diffstat (limited to 'sci_gateway1/cpp/opencv_detectMSERFeatures.cpp')
-rw-r--r-- | sci_gateway1/cpp/opencv_detectMSERFeatures.cpp | 451 |
1 files changed, 451 insertions, 0 deletions
diff --git a/sci_gateway1/cpp/opencv_detectMSERFeatures.cpp b/sci_gateway1/cpp/opencv_detectMSERFeatures.cpp new file mode 100644 index 0000000..a437c16 --- /dev/null +++ b/sci_gateway1/cpp/opencv_detectMSERFeatures.cpp @@ -0,0 +1,451 @@ +/******************************************************************************************************************************************************************************************************** +* Author: Umang Agrawal * +* Code: detectMSERFeatures.cpp * +* Function Format: [ list_pixels, ......] = detectMSERFeatures( image, Optional Arguments........) * +* Input Arguments: 1. Image (Grayscale or RGB) * +* 2. ThresholdDelta Value: (0:100] Expressed in Percentage * +* 3. RegionAreaRange Value: [ Min_Area , Max_Area ] * +* 4. MaxAreaVariation Value: Scalar Double typical range from 0.25 - 4 * +* 5. ROI Value: [ x_cord , y_cord , width , height ] * +* * +* Output Argument: 1. List Of Pixels stating the Locus of all features detected * +* 2. Count * +* 3. Location: Centroid of each Locus * +* 4. Axes: Major and Minor axis length of ellipse * +* 5. Orientation: Tilt of the elliptical fit * +* * +********************************************************************************************************************************************************************************************************/ + + +#include <iostream> +#include <numeric> +#include <vector> +#include <string> +#include "opencv2/core/core.hpp" +#include "opencv2/features2d/features2d.hpp" +#include "opencv2/nonfree/features2d.hpp" +#include "opencv2/highgui/highgui.hpp" +#include "opencv2/nonfree/nonfree.hpp" +#include "opencv2/imgproc/imgproc.hpp" + +using namespace cv; +using namespace std; + +extern "C" +{ + #include "api_scilab.h" + #include "Scierror.h" + #include "BOOL.h" + #include <localization.h> + #include "sciprint.h" + #include "../common.h" + + int opencv_detectMSERFeatures(char *fname, unsigned long fname_len) + { + //Various Declarations + //Error Variables + SciErr sciErr; + int sca_read; + + //Mat containers for image + Mat image; + Mat cropped; + + //Address of Various Arguments + int *piAddr = NULL; + int *piAddr2 = NULL; + int *piAddr3 = NULL; + + int inp_params, out_params; //Count of Parameters + double arg_val; //Memory for Scalar Argument Value + int Rows, Cols; //Rows and Columns for Matrix Argument Value + double *roi_arg = NULL; //Memory for Matrix Argument Value + int *pilen = NULL; //For String Matrix Reading: Length of String + char **arg = NULL; //For String Matrix Reading: String + int count_area = 0, count_tres = 0, count_var = 0, count_roi = 0; //Count of all the optional Arguments + double x = 0, y = 0, width = 0, height = 0; //Initials of all Cropped Varaibles + + int i,j; //Iterator + + int delta = 5, min_area = 60, max_area = 14400, max_evolution = 200, edge_blur_size = 5; //Arguments of MSER function with default values + double max_variation = 0.25, min_diversity = 0.2, area_threshold = 1.01, min_margin = 0.003; //Arguments of MSER function with default values + + double *pixellist = NULL; //Output Argument Pixellist + int count[1] ; //Output Argument Count + double *location = NULL; //Output Argument Location + double *axes = NULL; //Output Argument Axes + double *orientation = NULL; //Output Argument Orientation + + vector< vector<Point> > mser_points; //3D vector for storing the locus of each detected feature + vector< RotatedRect > regions; //RotatedRect vector for storing each region associated with a feature + + CheckInputArgument(pvApiCtx, 1, 9); //Check on Number of Input Arguments + CheckOutputArgument(pvApiCtx, 1, 5); //Check on Number of Output Arguments + + //Read Image + retrieveImage(image, 1); + + //Getting Number of Input Arguments + inp_params = *getNbInputArgument(pvApiCtx); + + //Based on the number of Input Arguments, alter the arguments of the MSER funtion. + for(i=2; i<=inp_params; i++) + { + if( inp_params == 2 || inp_params == 4 || inp_params == 6 || inp_params == 8) + { + Scierror(999,"Either Argument Name or its Value missing\n"); + return 0; + } + //Reading the Name of the Argument + sciErr = getVarAddressFromPosition(pvApiCtx, i, &piAddr2); + if(sciErr.iErr) + { + printError(&sciErr, 0); + return 0; + } + //Check for Argument type + if( !isStringType(pvApiCtx, piAddr2)) + { + Scierror(999, "%s: Wrong type of argument #%d. A string is expected.\n", fname, 1); + return 0; + } + //Matrix of Stings + sciErr = getMatrixOfString(pvApiCtx, piAddr2, &Rows, &Cols, NULL, NULL); + if(sciErr.iErr) + { + printError(&sciErr, 0); + return 0; + } + pilen = (int*)malloc(sizeof(int) * Rows * Cols); + //second call to retrieve the length of the string + sciErr = getMatrixOfString(pvApiCtx, piAddr2, &Rows, &Cols, pilen, NULL); + if(sciErr.iErr) + { + printError(&sciErr, 0); + free(pilen); + return 0; + } + arg = (char**)malloc(sizeof(char*) * Rows * Cols); + for(int j=0;j< Rows * Cols; j++) + { + arg[j] = (char*)malloc(sizeof(char) * (pilen[j] + 1)); + } + + //third call to retrieve data + sciErr = getMatrixOfString(pvApiCtx, piAddr2, &Rows, &Cols, pilen, arg); + if(sciErr.iErr) + { + printError(&sciErr, 0); + free(pilen); + free(arg); + return 0; + } + + if(strcmp(arg[0],"ThresholdDelta") == 0) + { + if(count_tres == 0) + { + sciErr = getVarAddressFromPosition(pvApiCtx, i+1, &piAddr3); + if(sciErr.iErr) + { + printError(&sciErr, 0); + return 0; + } + //Checking the type of value + if( !isDoubleType(pvApiCtx, piAddr3)) + { + Scierror(999,"Not a valid type of value.\n"); + return 0; + } + //Reading the Value of the argument + sca_read = getScalarDouble(pvApiCtx, piAddr3, &arg_val); + if(sca_read) + { + Scierror(999,"Not a valid value.\n"); + return 0; + } + //Check for valid range + if(arg_val <= 0 && arg_val > 100) + { + Scierror(999,"Not a valid range.Should be between 0 and 100.\n"); + return 0; + } + delta = arg_val; + i++; + count_tres += 1; + } + else + { + Scierror(999,"ThresholdDelta has been specified twice.Check the Arguments\n"); + return 0; + } + } + else if(strcmp(arg[0],"RegionAreaRange") == 0) + { + if(count_area == 0) + { + sciErr = getVarAddressFromPosition(pvApiCtx, i+1, &piAddr3); + if(sciErr.iErr) + { + printError(&sciErr, 0); + return 0; + } + //Checking the type of argument + if( !(isDoubleType(pvApiCtx, piAddr3) || isIntegerType(pvApiCtx, piAddr3)) ) + { + Scierror(999,"Not a valid type of value.\n"); + return 0; + } + //Reading the Value of the argument + sciErr = getMatrixOfDouble(pvApiCtx, piAddr3, &Rows, &Cols, &roi_arg); + if(sciErr.iErr) + { + printError(&sciErr, 0); + return 0; + } + if( Rows*Cols != 2 ) + { + Scierror(999,"Only 2 values are expected.Neither less nor more\n"); + return 0; + } + if( roi_arg[0] >= roi_arg[1] ) + { + Scierror(999,"Max Area should be greater than Min Area\n"); + return 0; + } + //Assigning the elements of the list to their proper function + min_area = roi_arg[0]; + max_area = roi_arg[1]; + i++; + count_area += 1; + } + else + { + Scierror(999,"RegionAreaRange has been specified twice.Check the Arguments\n"); + return 0; + } + } + else if(strcmp(arg[0],"MaxAreaVariation") == 0) + { + if(count_var == 0) + { + sciErr = getVarAddressFromPosition(pvApiCtx, i+1, &piAddr3); + if(sciErr.iErr) + { + printError(&sciErr, 0); + return 0; + } + //Checking the type of value + if( !isDoubleType(pvApiCtx, piAddr3)) + { + Scierror(999,"Not a valid type of value.\n"); + return 0; + } + //Reading the Value of the argument + sca_read = getScalarDouble(pvApiCtx, piAddr3, &arg_val); + if(sca_read) + { + Scierror(999,"Not a valid value.\n"); + return 0; + } + max_variation = arg_val; + i++; + count_var += 1; + } + else + { + Scierror(999,"MaxAreaVariation has been specified twice.Check the Arguments\n"); + return 0; + } + } + else if(strcmp(arg[0],"ROI") == 0) + { + if(count_roi == 0) + { + sciErr = getVarAddressFromPosition(pvApiCtx, i+1, &piAddr3); + if(sciErr.iErr) + { + printError(&sciErr, 0); + return 0; + } + //Checking the type of argument + if( !(isDoubleType(pvApiCtx, piAddr3) || isIntegerType(pvApiCtx, piAddr3)) ) + { + Scierror(999,"Not a valid type of value.\n"); + return 0; + } + //Reading the Value of the argument + sciErr = getMatrixOfDouble(pvApiCtx, piAddr3, &Rows, &Cols, &roi_arg); + if(sciErr.iErr) + { + printError(&sciErr, 0); + return 0; + } + if( Rows*Cols != 4 ) + { + Scierror(999,"Expected 4 arguments in format [x,y,width,height]\n"); + return 0; + } + //Assigning the elements of the list to their proper function + x = roi_arg[0]; + y = roi_arg[1]; + width = roi_arg[2]; + height = roi_arg[3]; + if(x>=image.cols || y>=image.rows || x<0 || y<0) + { + sciprint("Invalid x or y value\n"); + return 0; + } + if(width<=0 || height<=0 || x+width > image.cols || y+height > image.rows) + { + sciprint("Invalid width or height value\n"); + return 0; + } + Rect myROI(x, y, width, height); + Mat croppedRef(image, myROI); + croppedRef.copyTo(cropped); + i++; //Incrementing iterator to count for the value argument read + count_roi += 1; //Indicating ROI has been called once + } + else + { + Scierror(999,"ROI has been specified twice.Check the Arguments\n"); + return 0; + } + } + else + { + Scierror(999,"Invalid Argument\n"); + return 0; + } + } + + //Creating an MSER class Object with specified conditions + MSER img_ms = MSER(delta, min_area, max_area, max_variation, min_diversity, max_evolution, area_threshold, min_margin, edge_blur_size); + + //Checking if have to operate on original image or cropped one + // 1st Argument: Image on which MSER features has to be detected + // 2nd Argument: Locus of all the points detected + // 3rd Argument: Mask of empty Mat container + if(count_roi == 0) + img_ms( image, mser_points, Mat()); + else + img_ms( cropped, mser_points, Mat()); + + // Extracting Regions from the mser_points locus and approximating them to an elliptic fit + for(i=0; i<mser_points.size(); i++) + regions.push_back(fitEllipse(mser_points[i])); + + //Memory Allocation for all the output parameters + location = (double *)malloc(sizeof(double) * mser_points.size() * 2); + axes = (double *)malloc(sizeof(double) * mser_points.size() * 2); + orientation = (double *)malloc(sizeof(double) * mser_points.size()); + + //Output Arguments: Pixel_list, Count, Location, Axes, Orientation + count[0] = mser_points.size(); //Count + for(i=0; i<mser_points.size(); i++) + { + location[i] = regions[i].center.x + x; //Location X co-ordinate + location[mser_points.size() + i] = regions[i].center.y + y; //Location Y co-ordinate + if( regions[i].size.width >= regions[i].size.height ) + { + axes[i] = regions[i].size.width; //Axis: Major Axis of Ellipse + axes[mser_points.size() + i] = regions[i].size.height; //Axis: Minor Axis of Ellipse + } + else + { + axes[i] = regions[i].size.height; //Axis: Major Axis of Ellipse + axes[mser_points.size() + i] = regions[i].size.width; //Axis: Minor Axis of Ellipse + } + orientation[i] = regions[i].angle; //Orientation + } + + //Reading the number of output Arguments user demands + + //Assigning Pixel_List + out_params = *getNbOutputArgument(pvApiCtx); + if( out_params >= 1 ) + { + sciErr = createList(pvApiCtx, nbInputArgument(pvApiCtx) + 1, mser_points.size(), &piAddr); + if(sciErr.iErr) + { + printError(&sciErr, 0); + return 0; + } + for(i = 0; i<mser_points.size(); i++) + { + pixellist = (double *)malloc(sizeof(double) * mser_points[i].size() * 2); + for( j=0; j<mser_points[i].size(); j++) + { + pixellist[j] = mser_points[i][j].x + x; + pixellist[mser_points[i].size() + j] = mser_points[i][j].y + y; + } + sciErr = createMatrixOfDoubleInList(pvApiCtx, nbInputArgument(pvApiCtx) + 1, piAddr, i+1, mser_points[i].size(), 2, pixellist); + if(sciErr.iErr) + { + printError(&sciErr, 0); + return 0; + } + free(pixellist); + } + AssignOutputVariable(pvApiCtx, 1) = nbInputArgument(pvApiCtx) + 1; + } + + //Assigning Count + if( out_params >= 2 ) + { + sciErr = createMatrixOfInteger32(pvApiCtx, nbInputArgument(pvApiCtx) + 2, 1, 1, count); + if(sciErr.iErr) + { + printError(&sciErr, 0); + return 0; + } + AssignOutputVariable(pvApiCtx, 2) = nbInputArgument(pvApiCtx) + 2; + } + + //Assigning Location + if( out_params >= 3 ) + { + sciErr = createMatrixOfDouble(pvApiCtx, nbInputArgument(pvApiCtx) + 3, mser_points.size(), 2, location); + if(sciErr.iErr) + { + printError(&sciErr, 0); + return 0; + } + AssignOutputVariable(pvApiCtx, 3) = nbInputArgument(pvApiCtx) + 3; + } + + //Assigning Axes + if( out_params >= 4 ) + { + sciErr = createMatrixOfDouble(pvApiCtx, nbInputArgument(pvApiCtx) + 4, mser_points.size(), 2, axes); + if(sciErr.iErr) + { + printError(&sciErr, 0); + return 0; + } + AssignOutputVariable(pvApiCtx, 4) = nbInputArgument(pvApiCtx) + 4; + } + + //Assigning Orientation + if( out_params == 5 ) + { + sciErr = createMatrixOfDouble(pvApiCtx, nbInputArgument(pvApiCtx) + 5, mser_points.size(), 1, orientation); + if(sciErr.iErr) + { + printError(&sciErr, 0); + return 0; + } + AssignOutputVariable(pvApiCtx, 5) = nbInputArgument(pvApiCtx) + 5; + } + + //Releasing all the memory Captured + free(location); + free(axes); + free(orientation); + + //Returning the Output Arguments + ReturnArguments(pvApiCtx); + return 0; + } +} |