Ask Your Question
0

Error predict using SVM and BOW?

asked 2018-04-22 03:42:24 -0600

sayaandreas gravatar image

updated 2018-04-22 03:55:59 -0600

Im trying to do 3 class classification with 5 samples for each class on android But im getting this error OpenCV Error: Assertion failed (nsamples == 1) in virtual float cv::ml::SVMImpl::predict ?

Here is my code

public ImageDetection(Context mContext) throws IOException {
        context = mContext;
        TermCriteria tc = new TermCriteria(CV_TERMCRIT_ITER, 10, 0.001);
        dictionarySize = 1500;
        int retries = 1;
        bowTrainer = new BOWKMeansTrainer(dictionarySize, tc, retries, KMEANS_PP_CENTERS);

        descriptorMatcher = DescriptorMatcher.create(DescriptorMatcher.FLANNBASED);
        bowImgDescriptorExtractor = new BOWImgDescriptorExtractor(descriptorExtractor, descriptorMatcher);

        trainDescriptor = new MatVector();
        evalDescriptor = new Mat();
        trainLabs = new int[15];
        evalLabs = new int[15];

        initializeSVM();
        collectClassCentroids();
        startClustering();
        evaluate();

    }

    private void initializeSVM() {
        svm.setKernel(SVM.RBF);
        svm.setType(SVM.C_SVC);
        svm.setGamma(0.50625000000000009);
        svm.setC(312.50000000000000);
        svm.setTermCriteria(new TermCriteria(CV_TERMCRIT_ITER, 100, 0.000001));
    }

    private void collectClassCentroids() throws IOException {
        int[][] train = new int[][]{{R.drawable.train1_1, R.drawable.train1_2, R.drawable.train1_3, R.drawable.train1_4, R.drawable.train1_5},
                {R.drawable.train2_1, R.drawable.train2_2, R.drawable.train2_3, R.drawable.train2_4, R.drawable.train2_5},
                {R.drawable.train3_1, R.drawable.train3_2, R.drawable.train3_3, R.drawable.train3_4, R.drawable.train3_5}};

        int counter1 = 0;
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 5; j++) {
                Mat src = loadResource(train[i][j]);
                if (!src.empty()) {
                    cvtColor(src,src, CV_RGBA2GRAY);
                    KeyPointVector mKeypoint = new KeyPointVector();
                    featureDetector.detect(src, mKeypoint);
                    Mat mFeatures = new Mat();
                    descriptorExtractor.compute(src, mKeypoint, mFeatures);
                    trainLabs[counter1] = i;
                    counter1++;
                    bowTrainer.add(mFeatures);
                }
            }
        }

    }

    public void startClustering() throws IOException {

        trainDescriptor = bowTrainer.getDescriptors();
        int countRow = 0;
        for (int i = 0; i < trainDescriptor.size(); i++) {
            countRow += trainDescriptor.get(i).rows();
        }

        Mat dictionary = bowTrainer.cluster();
        bowImgDescriptorExtractor.setVocabulary(dictionary);

        trainLabel = new Mat(trainLabs);

        Mat trainingData = new Mat(0, dictionarySize, CV_32FC1);

        KeyPointVector keyPointVector1 = new KeyPointVector();
        Mat bowDescriptor1 = new Mat();

        int[][] train = new int[][]{{R.drawable.train1_1, R.drawable.train1_2, R.drawable.train1_3, R.drawable.train1_4, R.drawable.train1_5},
                {R.drawable.train2_1, R.drawable.train2_2, R.drawable.train2_3, R.drawable.train2_4, R.drawable.train2_5},
                {R.drawable.train3_1, R.drawable.train3_2, R.drawable.train3_3, R.drawable.train3_4, R.drawable.train3_5}};

        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 5; j++) {
                Mat src = loadResource(train[i][j]);
                cvtColor(src, src, CV_RGBA2GRAY);
                featureDetector.detect(src, keyPointVector1);
                bowImgDescriptorExtractor.compute(src, keyPointVector1, bowDescriptor1);
                trainingData.push_back(bowDescriptor1);
            }
        }

        System.out.println("Training Data "+trainingData.rows()+","+trainingData.cols());
        System.out.println("Training Label "+trainLabel.rows()+","+trainLabel.cols());
        svm.train(trainingData, ROW_SAMPLE, trainLabel);
    }

    public void evaluate() throws IOException {

        int [] evalLabel = trainLabs;
        Mat groundTruth = new Mat(evalLabel);
        Mat evalData = new Mat(0,dictionarySize,CV_32FC1);
        KeyPointVector keyPointVectorEval = new KeyPointVector();
        Mat bowDescriptor = new Mat();

        Mat results = new Mat(0,1,CV_32FC1);

        int[][] eval = new int[][]{{R.drawable.train1_1, R.drawable.train1_2, R.drawable.train1_3, R.drawable.train1_4, R.drawable.train1_5},
                {R.drawable.train2_1, R.drawable.train2_2, R.drawable.train2_3, R.drawable.train2_4, R.drawable.train2_5},
                {R.drawable.train3_1, R.drawable.train3_2, R.drawable.train3_3, R.drawable.train3_4, R.drawable.train3_5}};

        for (int i = 0; i < 3; i++) {
            for (int j = 0; j <5 ; j++) {
                Mat rImg = loadResource(eval[i][j]);
                cvtColor(rImg, rImg, CV_RGBA2GRAY ...
(more)
edit retag flag offensive close merge delete

Comments

just curious, is that really using javacv ?

(afaik, you can't even create an instance of BOWImgDescriptorExtractor , using opencv's java wrappers)

berak gravatar imageberak ( 2018-04-22 04:11:17 -0600 )edit
1

Yes sir im using javacv and javacpp preset for opencv

sayaandreas gravatar imagesayaandreas ( 2018-04-22 04:37:33 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
0

answered 2018-04-22 04:08:54 -0600

berak gravatar image

updated 2018-04-22 04:12:48 -0600

your evalData is growing with any pass Mat you push to it, so you cannot use

float response = svm.predict(evalData)

if you want to do a single prediction (inside that loop), use:

 float response = svm.predict(pass);

if you want to collect your bow vectors, and do a bulk prediction, move it after the loop, and use:

Mat result = new Mat();
svm.predict( evalData, result );

also:

Mat mat = imdecode(new Mat(bytes), CV_32FC1); 
// wrong flag here, should be IMREAD_COLOR or similar
edit flag offensive delete link more

Comments

thank sir its work. can you give me some sugestions to improve the accuracy? the prediction is pretty bad right now.

sayaandreas gravatar imagesayaandreas ( 2018-04-22 04:43:27 -0600 )edit

3 classes, and 5 samples each ? that's for sure not enough. you need A LOT MORE, like 500 per class.

also, your dictionary is quite large(1500), again, the longer your features are, the more data you need to get them seperated nicely

then, play with different SVM kernels , params, trainAuto().

berak gravatar imageberak ( 2018-04-22 04:52:05 -0600 )edit
1

Got it. Thank you for saving my future sir

sayaandreas gravatar imagesayaandreas ( 2018-04-22 04:56:57 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2018-04-22 03:42:24 -0600

Seen: 216 times

Last updated: Apr 22 '18