2015-10-29 5 views
5

Mein Ziel ist es, ein Bild als eine Abfrage zu nehmen und seine beste Übereinstimmung in einer Bibliothek von Bildern zu finden. Ich verwende SURF-Funktionen in openCV 3.0.0 und den Bag of Words-Ansatz, um eine Übereinstimmung zu finden. Ich brauche einen Weg, um herauszufinden, ob das Abfragebild eine Übereinstimmung in der Bibliothek hat. Wenn dies der Fall ist, möchte ich den Index des Bildes kennen, das am ehesten übereinstimmt.C++/OpenCV: Wie kann BOWImgDescriptorExtractor verwendet werden, um festzustellen, welche Cluster zu welchen Bildern im Vokabular gehören?

Hier ist mein Code in allen Bildern (300 insgesamt in der Bibliothek der Bilder) zum Lesen und Extrahieren und Clustering mit den Merkmalen:

Mat training_descriptors(1, extractor->descriptorSize(), extractor->descriptorType()); 
//read in all images and set to binary 
char filepath[1000]; 
for (int i = 1; i < trainingSetSize; i++){ 
    cout << "in for loop, iteration: " << i << endl; 
    _snprintf_s(filepath, 100, "C:/Users/Randal/Desktop/TestCase1Training/%d.bmp", i); 
    Mat temp = imread(filepath, CV_LOAD_IMAGE_GRAYSCALE); 
    Mat tempBW; 
    adaptiveThreshold(temp, tempBW, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 11, 2); 
    detector->detect(tempBW, keypoints1); 
    extractor->compute(tempBW, keypoints1, descriptors1); 
    training_descriptors.push_back(descriptors1); 
    cout << "descriptors added" << endl; 

} 
cout << "Total descriptors: " << training_descriptors.rows << endl; 
trainer.add(training_descriptors); 

Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create("FlannBased"); 
BOWImgDescriptorExtractor BOW(extractor, matcher); 
Mat library = trainer.cluster(); 
BOW.setVocabulary(library); 

ich den folgenden Code in einem Versuch, schrieb eine Übereinstimmung zu finden. Das Problem ist, dass BOW.compute nur die Indizes von Clustern (Wörtern) zurückgibt, die sowohl im Bild als auch in der Bildbibliothek vorhanden sind. imgQ ist das Abfragebild.

Mat output; 
Mat imgQBW; 
adaptiveThreshold(imgQ, imgQBW, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 11, 2); 
imshow("query image", imgQBW); 
detector->detect(imgQBW, keypoints2); 
extractor->compute(imgQBW, keypoints2, descriptors2); 

BOW.compute(imgQBW, keypoints1, output); 
cout << output.row(0) << endl; 

Ich muss wissen, welche Cluster im Vorschiff, an die Bilder entsprechen. Meine Ausgabe jetzt - output.row (0) - ist nur ein Array mit allen Indizes von Clustern in der Bibliothek gefunden. Missverstehe ich diese Ausgabe? Gibt es eine Möglichkeit zu bestimmen, welches Bild die am meisten passenden Cluster hat?

Antwort

0

Ich habe auch etwas Ähnliches basierend auf diesem Code:

https://github.com/royshil/FoodcamClassifier/blob/master/training_common.cpp

Aber der obige Teil ist nach dem Clustering beendet hat. Was Sie tun müssen, ist mit Ihrem ML (ich benutzte SVM) und Ihre Cluster-Zentren, die visuelle Tasche von Wörtern, die Sie haben zu trainieren. Mehr, Sie müssen alle "nächsten" Punkte zu Ihren geclusterten Punkten finden und sie mit Histogrammen trainieren. Als nächstes haben Sie ein Histogramm von Häufigkeiten (Beutel mit Schlüsselpunkten), die Sie trainieren müssen.

Ptr<ifstream> ifs(new ifstream("training.txt")); 
int total_samples_in_file = 0; 
vector<string> classes_names; 
vector<string> lines; 

//read from the file - ifs and put into a vector 
for(int i=0;i<lines.size();i++) { 

    vector<KeyPoint> keypoints; 
    Mat response_hist; 
    Mat img; 
    string filepath; 

    string line(lines[i]); 
    istringstream iss(line); 

    iss >> filepath; 

    string class_to_train; 
    iss >> class_to_train; 
    class_ml = "class_" + class_to_train; 
    if(class_ml.size() == 0) continue; 

    img = imread(filepath); 

    detector->detect(img,keypoints); 
    bowide.compute(img, keypoints, response_hist); 

    cout << "."; cout.flush(); 
    //here create the logic for the class to train(class_0, e.g) and the data you need to train. 
} 

Mehr können Sie in diesem git Projekt finden:
https://github.com/royshil/FoodcamClassifier
Dokumentation hier:
http://www.morethantechnical.com/2011/08/25/a-simple-object-classifier-with-bag-of-words-using-opencv-2-3-w-code/

+0

Was ist die Art Ihrer Variable class_ml? ein Faden? Auch der Code, den Sie oben haben, soll nach all dem Clustering kommen, oder? – Phazoozoo

+0

Class_ml ist die Klasse, die der ml-Algorithmus zum Training empfängt. Die Benennung war wahrscheinlich nicht so gut. Es ist eine Zeichenfolge ja. Der Code kommt nach dem Clustering ja. –

Verwandte Themen