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