2011-09-04 13 views
17

Ho una domanda sugli oggetti corrispondenti a OpenCV. Sto utilizzando l'algoritmo SURF implementato in opencv 2.3 per rilevare le funzionalità su ogni immagine e quindi estrarre i descrittori di queste funzionalità. Il problema nell'abbinamento con Brute Force Matcher, non so come giudico che le due immagini siano abbinate o meno, come quando sto usando due immagini diverse ci sono linee tra i descrittori nelle due immagini!OpenCV - Corrispondenza degli oggetti usando i descrittori SURF e BruteForceMatcher

Queste uscite del mio codice, o le due immagini - confronto con esse - sono simili o diverse, l'immagine del risultato indica che le due immagini sono abbinate.

La domanda è: come posso distinguere tra le due immagini?

vero matching:

http://store1.up-00.com/Jun11/hxM00286.jpg

False corrispondenza !! :

http://store1.up-00.com/Jun11/D5H00286.jpg

Il mio codice:

Mat image1, outImg1, image2, outImg2; 

// vector of keypoints 
vector<KeyPoint> keypoints1, keypoints2; 

// Read input images 
image1 = imread("C://Google-Logo.jpg",0); 
image2 = imread("C://Alex_Eng.jpg",0); 

SurfFeatureDetector surf(2500); 
surf.detect(image1, keypoints1); 
surf.detect(image2, keypoints2); 
drawKeypoints(image1, keypoints1, outImg1, Scalar(255,255,255), DrawMatchesFlags::DRAW_RICH_KEYPOINTS); 
drawKeypoints(image2, keypoints2, outImg2, Scalar(255,255,255), DrawMatchesFlags::DRAW_RICH_KEYPOINTS); 

namedWindow("SURF detector img1"); 
imshow("SURF detector img1", outImg1); 

namedWindow("SURF detector img2"); 
imshow("SURF detector img2", outImg2); 

SurfDescriptorExtractor surfDesc; 
Mat descriptors1, descriptors2; 
surfDesc.compute(image1, keypoints1, descriptors1); 
surfDesc.compute(image2, keypoints2, descriptors2); 

BruteForceMatcher<L2<float>> matcher; 
vector<DMatch> matches; 
matcher.match(descriptors1,descriptors2, matches); 

nth_element(matches.begin(), matches.begin()+24, matches.end()); 
matches.erase(matches.begin()+25, matches.end()); 

Mat imageMatches; 
drawMatches(image1, keypoints1, image2, keypoints2, matches, imageMatches, Scalar(255,255,255)); 

namedWindow("Matched"); 
imshow("Matched", imageMatches); 

cv::waitKey(); 
return 0; 

risposta

17

Il problema è stato in utilizzando solo la forza bruta Matcher, ho trovato metodi per ottenere una serie di buone partite tra due punti di vista a "OpenCV 2 Computer Vision Application Programming Cookbook"

Ch9: le immagini corrispondenti usando campione casuale consenso

.210

Stanno usando K Vicini più vicini e RANSAC

E grazie

+2

Questo libro risulta essere piuttosto utile! –

+1

Devi accettare la tua risposta. –

8

Per rimuovere dati anomali RANSAC + omografia è un buon metodo quando si confrontano due immagini planari.

L'omografia è il modello che RANSAC cercherà di utilizzare per confrontare i punti di entrambe le immagini e troverà il miglior insieme di punti che meglio si adattano al modello di proiezione dell'omografia (la trasformazione da un piano all'altro).

cv::findHomography(srcPoints,dstPoints, RANSAC, status); 

La funzione precedente restituirà uno stato matrice che ha un 1 per indici considerati inliers e 0 per indici considerati valori anomali, in modo da poter rimuovere valori anomali controllando questo array di stato.

+1

L'uso di 'LMEDS' (' Calib3d.LMEDS' su Android) mi dà risultati migliori, non so perché, nel mio progetto di corso, RANSAC in Matlab ha dato risultati molto interessanti. Ma definitivamente, la rimozione di outliners è un must! – Mustafa

3

È necessario modificare l'Hssian, 2500 è troppo. Prova 50. Quando usi una grande iuta, il risultato è un sacco di punti chiave, risultando non necessari. Un'altra informazione su SURF è che il tuo marcatore deve essere più ricco, con maggiori dettagli.

Problemi correlati