2014-06-27 16 views
10

OpenCV non fornisce una funzione RANSAC di per sé o almeno in tale forma che puoi semplicemente chiamarla e farla (es. cv::ransac(...)). Tutte le funzioni/metodi che sono in grado di usare RANSAC hanno un flag che lo abilita. Tuttavia questo non è sempre utile se in realtà vuoi fare qualcos'altro con i calcoli inresensivi di RANSAC dopo aver stimato un'omografia/matrice fondamentale, ad esempio, creare un buon grafico in Octave o software/libreria simile dei punti, applicare algoritmi aggiuntivi sul restante serie di corrispondenze filtrate ecc.OpenCV: come ottenere punti iniziali usando findHomography()/findFundamental() e RANSAC

Dopo aver abbinato due immagini si ottiene un vettore di corrispondenze. Insieme a questo abbiamo ovviamente 2 set di punti chiave (uno per ogni immagine) che sono stati utilizzati nel processo di abbinamento. Usando le corrispondenze e i punti chiave creiamo due vettori di punti (ad esempio cv::Point2f points) e li passiamo a findHomography(). Dai post this e this ho scoperto come esattamente gli inlier sono contrassegnati usando una maschera, che passiamo a quella funzione. Ogni riga all'interno della maschera si riferisce a un valore inlier/outlier. Tuttavia non sono in grado di capire come utilizzare le informazioni dell'indice delle righe dai miei due insiemi di punti. Guardare il codice sorgente di OpenCV non mi ha portato troppo lontano. In findFundamental() (simile a findHomography() quando si tratta della sua firma e della parte maschera) usano compressPoints(), che sembra in qualche modo combinare i due set che abbiamo come input (punti di origine e destinazione) in uno. Durante il test per determinare la natura della maschera ho provato 2 set di punti abbinati (convertito da cv::Keypoints a cv::Point2f - una procedura standard). Ogni set contiene 300 punti quindi in totale abbiamo 600 punti. La maschera restituita contiene 300 righe (i valori non sono importanti per questo argomento).

EDIT: Mentre scrivevo questo ho scoperto la risposta (vedi sotto) ma ho deciso di postare comunque questa domanda nel caso qualcuno avesse bisogno di queste informazioni il prima possibile e in forma compatta. Nota che abbiamo ancora bisogno di una funzione di OpenCV, che supporti RANSAC. Quindi, se hai una serie di punti ma non hai intenzione di calcolare l'omografia o la matrice fondamentale, questo non è ovviamente il modo e oserei dire che non sono riuscito a trovare nulla di utile nell'API di OpenCV che possa aiutare a evitare questo ostacolo, quindi devi usare una libreria esterna.

risposta

10

La soluzione è in realtà piuttosto banale. Come sappiamo, ogni riga nella nostra maschera fornisce informazioni se abbiamo un valore inerte o un valore anomalo. Tuttavia abbiamo come input 2 insiemi di punti, quindi come esattamente una riga contenente un singolo valore rappresenta due punti? La natura di questo tipo di indicizzazione è apparsa nella mia mente mentre pensavo a come effettivamente queste due serie di punti appaiono in findHomography() (nel mio caso stavo calcolando l'omografia tra due immagini). Entrambi gli insiemi hanno un numero uguale di punti in loro a causa del semplice fatto che vengono estratti dalle corrispondenze tra la nostra coppia di immagini. Ciò significa che una riga nella nostra maschera è l'indice effettivo dei punti nei due set e anche l'indice nel vettore di corrispondenze per le due immagini. Sono riuscito a fare riferimento manualmente a un piccolo sottoinsieme di punti corrispondenti in base a questo e i risultati sono come previsto. È importante non modificare l'ordine delle partite e i punti 2D che hai estratto da loro utilizzando i punti chiave a cui si fa riferimento in ogni cv::DMatch. Qui sotto puoi vedere un semplice esempio per un singolo paio di inlier.

for(int i = 0; i < matchesObjectScene.size(); ++i) 
{ 
    // extract points from keypoints based on matches 
    pointsObject.push_back(keypointsObject.at(matchesObjectScene.at(i).queryIdx).pt); 
    pointsScene.push_back(keypointsScene.at(matchesObjectScene.at(i).trainIdx).pt); 
} 
// compute homography using RANSAC 
cv::Mat mask; 
cv::Mat H = cv::findHomography(pointsObject, pointsScene, CV_RANSAC, ransacThreshold, mask); 

Nell'esempio di cui sopra, se il risultato della stampa alcune inlier

int maskRow = 10; 
std::cout << "POINTS: object(" << pointsObject.at(maskRow).x << "," << pointsObject.at(maskRow).y << ") - scene(" << pointsScene.at(maskRow).x << "," << pointsScene.at(maskRow).y << ")" << std::endl; 

e poi di nuovo, ma questa volta usando i nostri punti chiave (si può fare anche con i punti 2D estratti)

std::cout << "POINTS (via match-set): object(" << keypointsObject.at(matchesCurrentObject.at(maskRow).queryIdx).pt.x << "," << keypointsObject.at(matchesCurrentObject.at(maskRow).queryIdx).pt.y << ") - scene(" << keypointsScene.at(matchesCurrentObject.at(maskRow).trainIdx).pt.x << "," << keypointsScene.at(matchesCurrentObject.at(maskRow).trainIdx).pt.y << ")" << std::endl; 

in realtà otteniamo lo stesso risultato:

POINTS: object(462,199) - sscene(485,49) 
POINTS (via match-set): object(462,199) - scene(485,49) 

Per ottenere inlier effettivo dobbiamo semplicemente controllare se la riga corrente nella maschera contiene effettivamente un 0 o valore diverso da zero:

if((unsigned int)mask.at<uchar>(maskRow)) 
    // store match or keypoints or points somewhere where you can access them later 
+1

Per la prima frase, in realtà la riga in maschera non costituiscono inlier. La riga rappresenta lo stato di inlier o outlier. Fare riferimento a questo post [collegamento] (http://stackoverflow.com/questions/15815304/opencv-c-findhomography-mask-values-meaning) per ulteriori spiegazioni. –

+0

Sì, è corretto e questo è ciò che intendevo, ma ora che rileggo questa frase vedo come può essere male interpretato. Lo cambierò. – rbaleksandar

+0

Ma la riga rappresenta lo stato di inlier o valori anomali ma non vi è alcun punto chiave su ogni stato di inlier o di valori anomali. i punti chiave sono memorizzati nel vettore. quindi, come possiamo ottenere il corrispondente punto chiave di inlier nella maschera? – Abc

Problemi correlati