Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Isolate object to better detect it

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;