2015-10-29 18 views
5

Moim celem jest zrobienie zdjęcia jako zapytania i znalezienie najlepszego dopasowania w bibliotece obrazów. Używam funkcji SURF w openCV 3.0.0 i podejścia Bag of Words, aby znaleźć dopasowanie. Potrzebuję sposobu, aby sprawdzić, czy obraz zapytania pasuje do biblioteki. Jeśli tak, chcę znać indeks obrazu, który jest najbliższym dopasowaniem.C++/OpenCV: Jak używać BOWImgDescriptorExtractor do określenia, które klastry odnoszą się do obrazów w słowniku?

Oto mój kod do czytania we wszystkich zdjęć (300 w sumie w bibliotece obrazów) i ekstrakcji i grupowanie cech:

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); 

Napisałem następujący kod w próbie znalezienia meczu. Problem polega na tym, że BOW.compute zwraca tylko indeksy klastrów (słów), które istnieją zarówno w obrazie, jak i bibliotece obrazów. imgQ to obraz zapytania.

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; 

Muszę wiedzieć, które klastry w BoW odpowiadają, które obrazy. Moje wyjście w tej chwili - output.row (0) - jest po prostu tablicą z wszystkimi indeksami klastrów znalezionych w bibliotece. Czy nie rozumiem tego wyniku? Czy istnieje sposób na określenie, który obraz ma najbardziej pasujące klastry?

Odpowiedz

0

Zrobiłem też coś podobnego w oparciu o ten kod:

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

Ale przede część jest po zakończeniu klastrów. Co musisz zrobić, to ćwiczyć używając ML (ja użyłem SVM) i twoich centrów klastra, wizualnego worka słów, które masz. Co więcej, musisz znaleźć wszystkie "najbliższe" punkty w swoich punktach i ćwiczyć je za pomocą histogramów. Następnie będziesz miał histogram częstotliwości (worek kluczowych punktów), który musisz wyszkolić.

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. 
} 

Więcej można znaleźć w tym projekcie git:
https://github.com/royshil/FoodcamClassifier
Dokumentacja tutaj:
http://www.morethantechnical.com/2011/08/25/a-simple-object-classifier-with-bag-of-words-using-opencv-2-3-w-code/

+0

Jaki jest typ zmiennej class_ml? ciąg znaków? Ponadto, kod, który masz powyżej, ma przyjść po wszystkich grupowaniu, prawda? – Phazoozoo

+0

Class_ml to klasa, którą algorytm ml otrzymuje podczas treningu. Naming prawdopodobnie nie był tak dobry. To jest łańcuch tak. Kod przychodzi po klastrowaniu tak. –

Powiązane problemy