SVM train doesn't accept my data
I've been trying to figure out how to use the svm train function. From what i understand from some online sources, you have to have an array of your data followed by another array that labels the positions to be either good or bad data. What i have is code that finds contours in the picture, extracts the properties, puts them in a vector and then the vector is put into a Mat which is them passed into the train function. But everytime i get to the train function it crashes with an exception at memory location. I believe that vectors aren't accepted by the Mat constructor and this could possibly be the source of the problem. I would like to know what the problem is if it is not that. And if it is, would there be a way to get it to work with the vectors?
The function for the detection and training: http://pastebin.com/GgN6k3Pb
All the code: http://pastebin.com/ZvN8eukr
void contourDetection(){
//Vector that represents the hierarchy of the contours
vector< Vec4i > hierarchy;
///Find contours and store in a contours, then store the contour hierarchies in hierarchy
cv::findContours(dst, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE);
double area;
int count = 0, all = 0;
CvSVM detector;
bool exit = false;
vector<vector<double>> allData;
vector<float> labels;
//Load the training data
detector.load("Muskrat_Counting_SVM.xml");
//Size of the whole picture
int totSize = dst.total();
//Iterate through all parent contours
for (int i = 0; i < contours.size() && exit == false; i = hierarchy[i][0])
{
//Find the size of the outer contours (lakes)
area = contourArea(contours[i]);
//Find the biggest contours (presumed to be the lakes)**Needs optimization
if (area > totSize*.20)// && area < totSize*.5)
{
//Draw the lake
draw(contours[i], "red");
//Using hierarchy array to determine hierarchy, this loop is for the child contours
for (int j = hierarchy[i][2]; hierarchy[j][0] > 0 && exit == false; j = hierarchy[j][0]){
//Find contour size
double contArea = contourArea(contours[j]);
if (contArea > 20 && contArea < 300){ //When size of the contour is inbetween those area
//Get the location of the center of the contour for zooming
Moments mu = moments(contours[j], false);
pCen = Point2f(mu.m10 / mu.m00, mu.m01 / mu.m00);
all++;
//Draw current contour
draw(contours[j], "orange");
//Evaluate next contour
zoom(Mat(frame));
//Output question
cout << "Is this a contour? (Y or N) ";
string input;
while (exit == false){
//Retrieve user input
getline(cin, input);
cout << endl;
cout << "\n\nGetting next contour...";
//If user enters Y
if (strUpper(input) == "Y" || strUpper(input) == "N")
{
if (strUpper(input) == "Y"){
//Draw the correct contour green
draw(contours[j], "green");
//Count the drawn contours
count++;
labels.push_back(1);
}
else{
draw(contours[j], "red");
labels.push_back(-1);
}
///////////////////////###################Get training data############################////////////////////////////
//Get aspect ratio
Rect rect = boundingRect(contours[j]);
double aspect_ratio = float(rect.width) / rect.height;
//Get extent
double rect_area = float(rect.width)*rect.height;
double extent = float(contArea) / rect_area;
//Get solidity
vector<Point> hull;
convexHull(contours[j], hull);
double hull_area = contourArea(hull);
double solidity ...
Better to Post your code here , your url's are not working .
vector<vector<double>> allData;
Mat trainingData(amount, 6, CV_32FC1, &allData); // you're passing in double data, so make it CV_64FC1
I changed it and still got an exception.
ah, sorry. it expects continuos memory for the data ptr, so allData is probably the wrong thing here
can't you push your svm-rows straight into the (empty) trainingMat and later reshape it ?
So your saying i should use the Mat to store my data from the start and then just put it into the train function at the end? If so, i don't think it will work because i don't think Mat's support dynamic sizes. In the code Mat trainingData(amount, 6, CV_64FC1, &allData); , amount is dynamic so the size of the matrix always changes. If Mat's support dynamic sizing then this would be great. But that is why I'm using vectors because the support dynamic sizes.
oh, it does allow the same dynamic push_back operations as a vector
So it automatically resets to the next colomn once 6 have been pushed?
it should.
when you can't assume this, still push one thing after another, then finally:
It doesn't order it properly when pushed. It just puts them next to eachother instead of in the same colomn. In other words it stays a one dimensional array.