2012-03-15 7 views
7

Oto mój problem. Ręcznie wyodrębniły funkcje punktów kluczowych z SURF na wielu obrazach. Ale już wiem, która para punktów będzie pasować. Chodzi o to, próbuję stworzyć moje pasujące pary, ale nie rozumiem jak. Próbowałem, patrząc na kod, ale to bałagan.Ręcznie dokonaj dopasowania parami w OpenCV z funkcji kluczowych punktów

W tej chwili wiem, że rozmiar features.descriptors, matrix, jest taki sam jak liczba kluczowych punktów (drugi wymiar to 1). W kodzie, aby wykryć pasujące pary, używa się tylko deskryptorów, więc porównuje ona wiersze (lub kolumny, nie jestem pewien) lub dwie matryce deskryptorów i określa, czy jest coś wspólnego.

Ale w moim przypadku już wiem, że istnieje dopasowanie między punktem kluczowym i od obrazu 1, a kluczem j z obrazu 2. Jak to opisuję jako wartość MatchesInfo. W szczególności dopasowania elementów typu std :: vector < cv :: DMatch>.

EDYCJA: W związku z tym nie muszę używać żadnych elementów dopasowujących ani niczego w tym stylu. Wiem, które pary idą w parze!

+0

W celu późniejszego odniesienia, należy postarać się, aby pytania były bardziej przejrzyste. Oparłem swój przykład na "Wiem, które pary idą razem" i "std :: vector ". Jeśli potrzebujesz dodatkowych wyjaśnień dotyczących odpowiedzi, spróbuj precyzyjniej odpowiedzieć na pytanie. – penelope

Odpowiedz

5

Jeśli zrozumiałem, że poprawnie podasz pytanie, zakładam, że chcesz, aby punkt końcowy pasował do std::vector<cv::DMatch> w celu narysowania ich za pomocą OpenCV cv::drawMatches lub użycia z jakąś podobną funkcją OpenCV. Ponieważ ja też robi dopasowanie „ręcznie” niedawno, tu jest mój kod, który sporządza arbitralne mecze zawarte pierwotnie w std::vector<std::pair <int, int> > aMatches i wyświetla je w oknie:

const cv::Mat& pic1 = img_1_var; 
const cv::Mat& pic2 = img_2_var; 
const std::vector <cv::KeyPoint> &feats1 = img_1_feats; 
const std::vector <cv::KeyPoint> &feats2 = img_2_feats; 
    // you of course can work directly with original objects 
    // but for drawing you only need const references to 
    // images & their corresponding extracted feats 

std::vector <std::pair <int, int> > aMatches; 
    // fill aMatches manually - one entry is a pair consisting of 
    //  (index_in_img_1_feats, index_in_img_2_feats) 


// the next code draws the matches: 
std::vector <cv::DMatch> matches; 
matches.reserve((int)aMatches.size()); 

for (int i=0; i < (int)aMatches.size(); ++i) 
    matches.push_back(cv::DMatch(aMatches[i].first, aMatches[i].second, 
         std::numeric_limits<float>::max())); 

cv::Mat output; 

cv::drawMatches(pic1, feats1, pic2, feats2, matches, output); 

cv::namedWindow("Match", 0); 
cv::setWindowProperty("Match", CV_WINDOW_FULLSCREEN, 1); 
cv::imshow("Match", output);  
cv::waitKey(); 
cv::destroyWindow("Match"); 

Alternatywnie, jeśli potrzebujesz pełniejszej informacji o meczach dla w celach bardziej skomplikowanych niż rysowanie, możesz również ustawić odległość między dopasowaniami na właściwą wartość. Na przykład. jeśli chcesz obliczyć odległości używając L2 odległość, należy wymienić następujące linie:

for (int i=0; i < (int)aMatches.size(); ++i) 
    matches.push_back(cv::DMatch(aMatches[i].first, aMatches[i].second, 
         std::numeric_limits<float>::max())); 

z tym (uwaga, bo to odniesienie do funkcji wektorów deskryptora jest również potrzebne):

cv::L2<float> cmp; 

const std::vector <std::vector <float> > &desc1 = img_1_feats_descriptors; 
const std::vector <std::vector <float> > &desc2 = img_2_feats_descriptors; 

for (int i=0; i < (int)aMatches.size(); ++i){ 
    float *firstFeat = &desc1[aMatches[i].first]; 
    float *secondFeat = &desc2[aMatches[i].second]; 
    float distance = cmp(firstFeat, secondFeat, firstFeat->size()); 
    matches.push_back(cv::DMatch(aMatches[i].first, aMatches[i].second, 
         distance)); 
} 

Należy zauważyć, że w ostatnim fragmencie, descX[i] jest deskryptorem dla featsX[i], przy czym każdy element wektora wewnętrznego jest jednym elementem wektora deskryptora. Zwróć też uwagę, że wszystkie wektory deskryptorów powinny mieć tę samą wymiarowość.

+0

Moje deskryptory są typu cv :: Mat, jak mogę przekonwertować je na wektor >? lub czy można go w naturalny sposób przekształcić? – widgg