1

I have already reffered to the following links: Link 1 and Link 2

From the above i have to managed to write the following :

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/ml/ml.hpp>

using namespace cv;
using namespace std;

int main(){
    int num_files = 2;
    int width = 128, height = 128;

    Mat image[2];
    image[0] = imread("Tomato.jpg");
    image[1] = imread("Melon.jpg");

    Mat new_image(2,height*width,CV_32FC1); //Training sample from input images

    int ii = 0;
    for (int i = 0; i < num_files; i++){
        Mat temp = image[i];
        ii = 0;
        for (int j = 0; j < temp.rows; j++){
            for (int k = 0; k < temp.cols; k++){
                new_image.at<float>(i, ii++) = temp.at<uchar>(j, k);
            }
        }
    }
    //new_image.push_back(image[0].reshape(0, 1));
    //new_image.push_back(image[1].reshape(0, 1));
    Mat labels(num_files, 1, CV_32FC1);
    labels.at<float>(0, 0) = 1.0;//tomato
    labels.at<float>(1, 0) = -1.0;//melon

    imshow("New image", new_image);
    printf("%f %f", labels.at<float>(0, 0), labels.at<float>(1, 0));

    CvSVMParams params;
    params.svm_type = CvSVM::C_SVC;
    params.kernel_type = CvSVM::LINEAR;
    params.gamma = 3;
    params.degree = 3;
    params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6);
    CvSVM svm;
    svm.train(new_image, labels, Mat(), Mat(), params);

    svm.save("svm.xml"); // saving
    svm.load("svm.xml"); // loading

    Mat test_img = imread("Tomato.jpg");
    test_img=test_img.reshape(0, 1);
    imshow("shit_image", test_img);
    test_img.convertTo(test_img, CV_32FC1);
    svm.predict(test_img);

    waitKey(0);
}

I get the following error:

unsupported format or combination of formats, input sample must have 32FC1 type in cvPreparePredictData ...

I followed all steps in the second link. All matrices are 32FC1 type. What am I missing? Is there something wrong with the svm parameters ? The error is caused when i try to predict a result.

3
  • 1
    Side comment: you declare twice the variables ì, j and k. Once is enough (inside the 'for') Commented Dec 23, 2015 at 12:52
  • Someone just posted the correct answer here and then removed the comment. Commented Dec 23, 2015 at 13:01
  • The issue was due to difference in the color space. Reading the files with grayscale( imread("tomato.jpg",0) ) fixed it. Commented Dec 23, 2015 at 13:02

1 Answer 1

1

check

1) Tomato.jpg and Melon.jpg size is 128*128 ?
2) both images are grayscale?

if not. try this code:
I just add resize(), cvtColor() and print result

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/ml/ml.hpp>
#include <opencv2\imgproc\imgproc.hpp>

using namespace cv;
using namespace std;

int main(){
    int num_files = 2;
    int width = 128, height = 128;

    Mat image[2];
    image[0] = imread("Tomato.jpg", 0);
    image[1] = imread("Melon.jpg", 0);

    resize(image[0], image[0], Size(width, height));
    resize(image[1], image[1], Size(width, height));

    Mat new_image(2, height*width, CV_32FC1); //Training sample from input images

    int ii = 0;
    for (int i = 0; i < num_files; i++){
        Mat temp = image[i];
        ii = 0;
        for (int j = 0; j < temp.rows; j++){
            for (int k = 0; k < temp.cols; k++){
                new_image.at<float>(i, ii++) = temp.at<uchar>(j, k);
            }
        }
    }
    //new_image.push_back(image[0].reshape(0, 1));
    //new_image.push_back(image[1].reshape(0, 1));
    Mat labels(num_files, 1, CV_32FC1);
    labels.at<float>(0, 0) = 1.0;//tomato
    labels.at<float>(1, 0) = -1.0;//melon

    imshow("New image", new_image);
    printf("%f %f", labels.at<float>(0, 0), labels.at<float>(1, 0));

    CvSVMParams params;
    params.svm_type = CvSVM::C_SVC;
    params.kernel_type = CvSVM::LINEAR;
    params.gamma = 3;
    params.degree = 3;
    params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6);
    CvSVM svm;
    svm.train(new_image, labels, Mat(), Mat(), params);

    svm.save("svm.xml"); // saving
    svm.load("svm.xml"); // loading

    Mat test_img = imread("Tomato.jpg", 0);
    resize(test_img, test_img, Size(width, height));
    test_img = test_img.reshape(0, 1);
    imshow("shit_image", test_img);
    test_img.convertTo(test_img, CV_32FC1);
    float res = svm.predict(test_img);
    if (res > 0)
        cout << endl << "Tomato";
    else
        cout << endl << "Melon";
    waitKey(0);
}
Sign up to request clarification or add additional context in comments.

2 Comments

I was able to fix the issue. The issue was because the training images and testing image were not in the space color space. I made all of them grayscale thereby fixing the code.
@PurusharthDwivedi please close your question then, or if the answer above helped - mark it

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.