2013-04-25 8 views
5

Non riesco a far funzionare questa funzione. Fondamentalmente sto facendo il rilevamento di funzionalità e la corrispondenza con un'immagine di riferimento. Voglio sovrapporre le caratteristiche corrispondenti sopra la mia immagine di input. Ecco il mio codice:Android OpenCV: disegno corrisponde a feature2d

public Mat startProcessing(Mat inputImage) { 

    Imgproc.cvtColor(inputImage, rgb, Imgproc.COLOR_GRAY2RGB); 
    myFeatures.detect(rgb, keypoints); 
    descriptorExtractor.compute(inputImage, keypoints, imageDescriptors); 
    descriptorMatcher.match(templateDescriptors, imageDescriptors, matches); 

    Features2d.drawMatches(rgb, keypoints, templateImage, templateKeypoints, matches, rgb); 

    Imgproc.cvtColor(rgb, outputImage, Imgproc.COLOR_RGB2RGBA); 
    return outputImage; 
} 

È Caratteri2d.drawMatch che è specificamente il problema. Secondo l'errore di Android che ho ottenuto, alcune dimensioni non si stanno allineando. A dire il vero, non sono nemmeno sicuro di come drawMatches funzioni su Android perché non c'è documentazione da nessuna parte.

Quello che voglio essere in grado di fare è disegnare le corrispondenze sopra l'inputImage. Ho ottenuto il Feature2d.drawKeypoints per funzionare, ma non sono sicuro di come procedere per la conversione di MatOfDMatch matches in un oggetto MatOfKeypoint. Inoltre non sono nemmeno sicuro che sia così che funziona MatOfDMatch - non ha qualche associatività all'interno di esso corrispondente ai descrittori?

Ci scusiamo per essere ovunque, sto attraversando un periodo davvero difficile con OpenCV con Android. La documentazione del C++ è buona, ma c'è poco materiale per Android. Grazie per qualsiasi aiuto!

risposta

6

La prima cosa che ho notato è che si stanno convertendo le immagini da uno spazio cromatico all'altro. È un po 'confuso. Se si desidera disegnare corrispondenze su immagini in scala di grigi, non è necessario eseguire questa conversione dell'immagine. Altra cosa, si sta rilevando punti chiave immagine RGB su e poi l'estrazione di descrittori da immagine originale (come posso vedere che è in scala di grigi)

Inoltre vi consiglio di controllare all'interno della vostra funzione se le immagini sono dello stesso tipo. Basta stampare nel log inputImage e vedere se entrambi sono del tipo CV_8UC3 o equivalente. Fondamentalmente il codice dovrebbe essere simile a questo:

Mat imageOut = inputImage.clone(); 
Features2d.drawMatches(inputImage, keypoints, templateImage, templateKeypoints, matches, imageOut); 
Highgui.imwrite("result_match.jpeg", imageOut); 

Rispondere a un altro le tue domande:

D: Sono sicuri di come vorrei andare sulla conversione MatOfDMatch partite a un oggetto MatOfKeypoint. A: Non è necessario, perché la funzione drawMatches riceve MatOfKeypoint dell'immagine di input e anche dell'immagine modello. Quindi quando passi MatOfDMatch disegna corrispondenze tra i kripo ricevuti corrispondenti.

D: Inoltre non sono nemmeno sicuro che sia così che funziona MatOfDMatch - non ha qualche associatività all'interno di esso corrispondente ai descrittori? A: Sì. Se farai matches.toList(0).queryIdx e matches.toList(0).trainIdx otterrai l'indice del keypoint inputImage, che corrisponde al punto chiave templateImage della prima partita.

+0

Grazie finora. Ho iniziato a usare imageOut = inputImage.clone() e questo fa funzionare drawMatches. Tuttavia, voglio restituire questa immagine, ma ciò che l'utente vede sulla fotocamera, ma le dimensioni sono leggermente diverse: è 704 * 480 invece della risoluzione della mia fotocamera di 640 * 480. Dato che la mia immagine modello ha larghezza 64, sembra che drawMatches li stia mettendo fianco a fianco. Posso semplicemente mostrare un rettangolo o qualcosa sopra l'area corrispondente sull'immagine di input? – JDS

+2

Sì, penso di si. Trasforma corrispondenze e punti chiave per elencare 'Elenco matches_list = matches.toList(); Elenco kp_list = keypoints.toList();' e quindi scorrere l'elenco 'kp_list.get (matches_list.get (i) .queryIdx)' e trova le X e Y minime e massime dei punti chiave corrispondenti per incontrare due punti che definiranno il tuo rettangolo.Quindi definisci un rettangolo 'Rect roi = new Rect (new Point (minX, minY), new Point (maxX, maxY))' e poi fai 'Mat imageFinal = new Mat (inputImage, roi);' e ritaglierà solo l'area abbinata – andriy