Hello everyone, it's me again: i'm trying to detect dome trees in a pictures and I tryed different ways. At the end I chose a BOW+SVM approach, by creating a dictionary and then applying it to the .train(...) of my SVM. I found out that this isn't enough for what I have to do, since classification gives me wrong result. So I tried a treshold on my test images by applying a clustering for colors, but of course, grass is detected too, so it's not very helpful. My training images (for dictionary and SVM training) are all .png images (so tress without background) and that's why I'm trying to segment my test images to isolate trees. I have tried some basic OpenCV segmentation tecniques (found here) but they don't seem to work. Here's my code:
Mat dictionary;
FileStorage fs("myDictionary.yml", FileStorage::READ);
fs["vocabulary"] >> dictionary;
fs.release();
Ptr<SIFT> detector = SIFT::create(); //detector to detect SIFT features
Ptr<DescriptorExtractor> extractor = SIFT::create();
Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create(DescriptorMatcher::FLANNBASED);
BOWImgDescriptorExtractor bowDE(extractor, matcher);
bowDE.setVocabulary(dictionary);
cout << "extracting histograms in the form of BOW for each Training image " << endl;
Mat labels(0, 1, CV_32S);
cout << labels.size() << endl;
int dictSize = 200;
Mat trainingData;
int k = 0;
vector<KeyPoint> keypoint;
Mat bowDescriptor;
Mat img;
vector<String> fn;
glob("C:/Users/albma/Desktop/train/*.png", fn, true);
for (size_t i = 0; i < fn.size(); i++) { //trees: label = 1
printf("Training Image = %s\n", fn[i]);
img = imread(fn[i], 0);
detector->detect(img, keypoint); //detect keypoints
bowDE.compute(img, keypoint, bowDescriptor); //compute descriptors
trainingData.push_back(bowDescriptor);
labels.push_back((int)1); //push labels in a matrix.. 1
}
cout << trainingData.size() << endl;
cout << labels.size() << endl;
//SVM Part
Ptr<ml::SVM> svm = ml::SVM::create();
svm->setType(SVM::ONE_CLASS);
svm->setNu(0.5);
/*svm->setKernel(SVM::LINEAR);
svm->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 100, 1e-6));*/
printf("Training SVM\n");
Ptr<TrainData> td = TrainData::create(trainingData, ROW_SAMPLE, labels); //start training SVM
svm->train(td);
Mat testData(0, dictSize, CV_32FC1);
k = 0;
vector<KeyPoint> keypoint2;
Mat bowDescriptor2;
printf("Training Done... loading Test images \n");
vector<String> fnb;
glob("C:/Users/albma/Desktop/Università/Computer Vision/final_project_test/Benchmark_step_1/*.jpg", fnb, true);
Mat results(0, 1, CV_32FC1);
Mat segm;
Mat test = imread("Figure 1.jpg");
inRange(test, Scalar(0, 23, 0), Scalar(11, 255, 34), segm);
imshow("test", segm);
for (int i = 0; i < fnb.size(); i++) {
printf("Test Image = %s\n", fnb[i]);
img = imread(fnb[i]);
//--------------->COLOR_SEGMENTATION
Mat data;
img.convertTo(data, CV_32F);
data = data.reshape(1, data.total());
Mat labels, centers;
kmeans(data, 8, labels, TermCriteria(TermCriteria::MAX_ITER, 10, 1.0), 3,
KMEANS_PP_CENTERS, centers);
centers = centers.reshape(3, centers.rows);
data = data.reshape(3, data.rows);
Vec3f *p = data.ptr<Vec3f>();
for (size_t i = 0; i < data.rows; i++) {
int center_id = labels.at<int>(i);
p[i] = centers.at<Vec3f>(center_id);
}
img = data.reshape(3, img.rows);
img.convertTo(img, CV_8U);
inRange(img, Scalar(0, 23, 0), Scalar(11, 255, 34), segm);
imshow("segm", segm);
//-------------------->END_SEGMENTATION
detector->detect(segm, keypoint2);
bowDE.compute(segm, keypoint2, bowDescriptor2); //compute descriptors
float predicted_label = svm->predict(bowDescriptor2);// predict computed descriptors from the dictionary we initially made
results.push_back(predicted_label);
printf("response = %f\n", predicted_label);
if (predicted_label == 1) {
putText(img, "Tree", Point(70, 30), FONT_HERSHEY_COMPLEX_SMALL, 2, Scalar(255, 100, 150), 1, LINE_AA);
}
imshow("Display Image", img);
waitKey(0);
destroyWindow("Display Image");
//cv::destroyAllWindows();
}
printf("results rows = %d cols = %d\n", results.rows, results.cols);
cout << "results = " << results << endl;
return 0;