2017-12-15 2 views
0

도움을 주셔서 감사합니다 ...이미지가 포함 된 SVM 교육 및 예측하기

나는 움직이는 비디오의 움직이는 비디오에서 성공적으로 자동차를 감지합니다. 따라서이 코드의 출력과이 코드의 최종 입력을 150x200 크기의 차량 이미지로 간주 할 수 있습니다.

내가 구현하려고하는 것은 그 차량을 타고 세단과 SUV 사이에서 분류 할 수있는 SVM입니다. (세단 형 자동차와 SUV 만 있다고 가정). https://docs.opencv.org/3.0-beta/doc/tutorials/ml/introduction_to_svm/introduction_to_svm.html 이 링크 : using OpenCV and SVM with images

이 링크와 제휴 구문의 SVM의 최신 버전에 SVM 구현을위한 약간 오래된 것을주의

다음 코드 밀접하게 링크의 정보에 따라 구현 나는 가지고있다.

//Used to read multiple files from folder 
stringstream ss; 
string name = "Vehicle_"; 
string type = ".jpg"; 

int num_train_images = 29;  //29 images will be used to train the SVM 
int image_area = 150 * 200; 
Mat training_mat(num_train_images, image_area, CV_32FC1); // Creates a 29 rows by 30000 columns... 29 150x200 images will be put into 1 row per image 

//Converts 29 2D images into a really long row per image 
for (int file_count = 1; file_count < (num_train_images + 1); file_count++) 
{ 
    ss << name << file_count << type;  //'Vehicle_1.jpg' ... 'Vehicle_2.jpg' ... etc ... 
    string filename = ss.str(); 
    ss.str(""); 

    Mat training_img = imread(filename, 1);  //Reads the training images from the folder 
    int ii = 0;         //Scans each column 
    for (int i = 0; i < training_img.rows; i++) 
    { 
     for (int j = 0; j < training_img.cols; j++) 
     { 
      training_mat.at<float>(file_count - 1, ii) = training_img.at<uchar>(i, j); //Fills the training_mat with the read image 
      ii++; 
     } 
    } 
} 

//Labels are used as the supervised learning portion of the SVM. If it is a 1, its an SUV test image. -1 means a sedan. 
float labels[29] = { 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1 }; 

//Place the labels into into a 29 row by 1 column matrix. 
Mat labels_mat(num_train_images, 1, CV_32FC1, labels); 

cout << "Beginning Training..." << endl; 

//Set SVM Parameters (not sure about these values) 
Ptr<SVM> svm = SVM::create(); 
svm->setType(SVM::C_SVC); 
svm->setKernel(SVM::LINEAR); 
svm->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 100, 1e-6)); 

svm->train(training_mat, ROW_SAMPLE, labels_mat); 

cout << "End Training" << endl; 

waitKey(0); 

Mat test_image(1, image_area, CV_32FC1);  //Creates a 1 x 30000 matrix to house the test image. 

Mat SUV_image = imread("SUV_1.jpg", 0);   //Read the file folder 
int jj = 0; 
for (int i = 0; i < SUV_image.rows; i++) 
{ 
    for (int j = 0; j < SUV_image.cols; j++) 
    { 
     test_image.at<float>(0, jj) = SUV_image.at<uchar>(i, j); //Fills the training_mat 
     jj++; 
    } 
} 

//Should return a 1 if its an SUV, or a -1 if its a sedan 
svm->predict(test_image); 

waitKey(0); 

그래서 제가 여기 일은 I의 시험 화상을 다음 training_mat 30,000 열의 행에서 1 행에 200 상으로 각각 (150)을 변형한다.

labels_mat는 교육 이미지가 SUV 또는 세단인지 여부를 알려주는 SVM의 감독 학습 부분입니다.

코드가 잘 작성되었지만 불행히도 svm-> train에 도달하면 오류가 발생하며 "OpenCV 오류 : 잘못된 인수 (응답이 범주화되어 있어야합니다. cv :: ml :: SVMImpl :: train에서 TrainData를 만들 때 varType을 지정하거나 정수 응답을 전달하십시오.

이것이 의미하는 바가 무엇인지 확실하지 않습니다. 매개 변수에 문제가있을 수 있습니다. 친구는 SVM에 이미지를 제공하기 전에 필자가 이미지의 기능을 추출해야한다고 제안했다.

감사

+0

원시 픽셀을 피쳐로 사용할 수는 있지만 종종 유용하지는 않습니다. 그래서 일반적으로 먼저 기능을 추출합니다. 객체 감지/분류를 위해 SVM에서 널리 사용되는 기능은 HoG (방향 그라디언트의 히스토그램)입니다. 요즘 많은 사람들이 SVM 대신 깊은 학습 회선 네트워크를 사용합니다. ConvNets의 한 가지 장점은 원본 이미지 만 피드에 추가하면 유용한 기능 (회선 필터처럼)을 배우게된다는 것입니다. – Micka

답변

0

이 문제 CV_32S에 labels_mat을 변경함으로써 해결되었다는 정수형한다. 불행하게도, svm-> predict (test_image)가 -1 또는 1이 아닌 큰 값을 반환한다는 새로운 문제는 여전히 남아 있습니다.

관련 문제