SVM application causing my system to hang

asked 2017-08-18 08:49:29 -0600

marcus gravatar image

I am using OpenCV java to build a leaf classifier. I extract HOG features from two datasets, one containing 100 images of a target leaf and another containing 100 negative images, images are sized to 50x50 pixels for both datasets. The extracted HOG descriptors are feed into a SVM for training and the application then tests the classifier with a sample dataset containing images sized to the training set. Here is my code:

public static void main(String[] args)
{
    // load opencv library
    System.loadLibrary(Core.NATIVE_LIBRARY_NAME);

    // create new file to contain positive and negative images
    File images = null;
    // create String to hold absolute path of image file
    String imageAbsPathAsStr = "";
    // create an array of image file paths
    File[] imageFilePaths;

    // set size of leaf image data and labels for SVM
    final int leafFileSize = 100;
    // set size of negative image data
    final int negFileSize = 100;
    final int numFiles = leafFileSize + negFileSize;

    // set leaf/neg image width
    final int width = 64;
    // set leaf/neg image height
    final int height = 128;
    final int imageArea = width * height;

    // create matrix for gray scale leaf image
    Mat leafGrayMat = new Mat(1, 1, CvType.CV_32FC1);

    // create matrix for neg image
    Mat negGrayMat = new Mat(1, 1, CvType.CV_32FC1);

    // create matrix of SVMtrainingData
    MatOfFloat SVMtrainingData = new MatOfFloat(numFiles, imageArea, CvType.CV_32FC1);

    // create matrix of image labels
    Mat labels = new Mat(numFiles, 1, CvType.CV_32FC1);

    // create HOG descriptor
    HOGDescriptor hog = new HOGDescriptor();
    // display hog params
    //System.out.println("winSize: " + hog.get_winSize());
    //System.out.println("winSigma: " + hog.get_winSigma());
    //System.out.println("blockSize: " + hog.get_blockSize());
    //System.out.println("cellSize: " + hog.get_cellSize());
    //System.out.println("blockStride: " + hog.get_blockStride());
    //System.out.println("descriptorSize: " + hog.getDescriptorSize());
    //System.out.println("L2HysThrehold: " + hog.get_L2HysThreshold());

    // create HOG matrices
    MatOfFloat ders = new MatOfFloat(1, 1, CvType.CV_32FC1);
    MatOfPoint locs = new MatOfPoint();

    // try opening leaf image folder
    try
    {
        // initialise leaf images with file path to leaf image directory
        images = new File("Images//acer_campestre_100_images");

        // assign leaf image path names to imageFilePaths
        imageFilePaths = images.listFiles();

        // traverse leaf image file paths
        for(File path : imageFilePaths)
        {
            // get absolute path of leaf image file
            imageAbsPathAsStr = path.getAbsolutePath();

            // initialise gray leaf matrix with gray scale version of leaf image
            leafGrayMat = Highgui.imread(imageAbsPathAsStr, Highgui.CV_LOAD_IMAGE_GRAYSCALE);

            // resize leafGrayMat to HOG default size 64x128
            Imgproc.resize(leafGrayMat, leafGrayMat, new Size(64, 128));

            // reshape leafGrayMat from 2D to 1D
            leafGrayMat = leafGrayMat.reshape(0, 1);

            // compute HOG features winStride of 8 x 8 to match hog cellSize and padding to 64 x 128 to match hog winSize
            hog.compute(leafGrayMat, ders, new Size(8, 8), new Size(64, 128), locs);

            // push ders to SVM training data
            SVMtrainingData.push_back(ders);

            // update labels
            labels.push_back(Mat.ones(1, 1, CvType.CV_32FC1));
        }
    }
    catch(Exception e)
    {
        // display error
        e.printStackTrace();
    }

    // try opening negative image folder
    try
    {
        // initialise images with file path to negative image directory
        images = new File("Images//neg_images_100");

        // assign negative image path names to imageFilePaths
        imageFilePaths = images.listFiles();

        // traverse negative image file paths
        for(File path : imageFilePaths)
        {
            // get absolute path of negative image file
            imageAbsPathAsStr = path.getAbsolutePath();

            // initialise gray negative matrix with gray scale ...
(more)
edit retag flag offensive close merge delete

Comments

btw: negGrayMat = negGrayMat.reshape(0, 1 ); please don't do this to any of your images. hog.compute needs a 2d image, not an 1d one.(but you might have to reshape() the hog output from a column to a row vector.

berak gravatar imageberak ( 2017-08-18 08:54:38 -0600 )edit

you should add some print() s and timig code, to see, which part of your prog is the bottleneck.

can you check the size of the resulting hog features ? also the size of your svm trainData ?

(i'm somewhat guessing, your params for hog.compute() result in unreasonable large vectors)

berak gravatar imageberak ( 2017-08-18 08:56:05 -0600 )edit

I made the changes as you suggested regarding the images, I dont know how to reshape the hog. The size of the training data is 1x424116003 and since the labels are 1x200 this is now throwing the error: 'Sizes of input arguments do not match (Response array must contain as many elements as the total number of samples) in cvPreprocessCategoricalResponses' when training the classifier: svmClassifier.train(SVMtrainingData, labels, new Mat(), new Mat(), params);

marcus gravatar imagemarcus ( 2017-08-18 10:40:46 -0600 )edit

yea, your hog features need to be rows not cols (reshape)

also , if my calculation is correct, you get like 5.7mil features from hog.compute(), way too much (1760 for the standard person classifier.

your train Mat should have 200 rows, and like ~2000 cols (depending on the hog params)

SVMtrainingData.push_back(ders.reshape(1,1)); (reshape shouldbe applied onto the hog features, not the image)

berak gravatar imageberak ( 2017-08-18 10:50:36 -0600 )edit

I reshaped the HOG descriptors as you suggested. But the error keeps being generated because the training data and the label matrices are not equally sized in order for the train() method to work - labels matrix is 1x200 whereas the SVMtrainingData matrix is 1x424116003 . My understanding is that each image from the data set is given a flag value (for example 1 or 0) according to whether it is a positive image or a negative one. However, the training data for the HOG features will produce a much larger matrix. How can i resolve this conundrum?

marcus gravatar imagemarcus ( 2017-08-18 14:15:05 -0600 )edit