2012-01-18 24 views
5

Qual è il modo migliore in OpenCV per applicare la correzione su un'immagine proiettata su una superficie 3D come nei miei esempi o mostrata in Projection on 3D surface?Correzione dell'immagine per proiezione su superficie con OpenCV

Le mie prime prove con rilevamento angolo scacchiera OpenCV non sembravano molto promettenti. Se l'angolo della fotocamera era troppo ripido, l'immagine era troppo distorta o troppo piccola (troppo lontana) non è stato rilevato alcun angolo. Anche se la scacchiera aveva troppi campi.

La mia idea era di usare un algoritmo come se fosse usato negli scanner 3D per rilevare superfici (oggetti), ma non ho idea se questo sia possibile con OpenCV. Anche se non sarebbe possibile con OpenCV, quali sono gli algoritmi utilizzati per tale scansione degli oggetti?

Queste immagini mostrano come appare senza alcuna correzione. Uncorrected projection on surface

I rettangoli verdi sono le proiezioni corrette. Corrected projection (green)

+0

Che tipo di dettagli stai cercando? –

+0

Innanzitutto grazie per la risposta. Puoi spiegare alcune nozioni di base su come rilevare la distorsione (algoritmo). Quindi, se i dati di correzione vengono trovati in qualche modo, quali metodi OpenCV sono i migliori da utilizzare per la correzione? Sfortunatamente la documentazione di OpenCV è molto scarsa. – bkausbk

+0

Ok, vorrei chiarire qualcosa prima. I rettangoli verdi che visualizzi come "corretti", come vengono corretti esattamente? Non sembrano adattarsi bene a qualsiasi cosa io possa vedere nello screenshot ... A proposito, ci sono molti dettagli su queste cose su questo sito http://www.vision.caltech.edu/bouguetj/calib_doc/ e in questo libro "Multiple View Geometry in Computer Vision" http://www.robots.ox.ac.uk/~vgg/hzbook/, questi sono buoni riferimenti. In ogni caso, fammi sapere come si qualificano i rettangoli verdi come "corretti", grazie –

risposta

2

I marker, come da utilizzo per ProCamCalib, devono essere rilevati in modo più robusto rispetto al motivo a scacchiera. Puoi usare ARToolkitPlus come con ProCamCalib, ma ci sono altre alternative, oppure potresti creare il tuo piccolo rilevatore. :) Quindi, con le coordinate dell'angolo rilevate dei marker, possiamo calibrare allo stesso modo, usando il resto delle funzioni di calibrazione di OpenCV.

E con esso posso fare anche cose interessanti, come mostrato nella pagina di ProCamTracker.

EDIT: Ora che ho capito meglio la domanda, possiamo farlo abbastanza facilmente per le scene statiche, anche se OpenCV non ci aiuterà molto. Innanzitutto, posizioniamo la telecamera nella posizione da cui vorremmo che un osservatore visualizzasse una proiezione corretta. Quindi, proiettiamo schemi binari (che assomigliano a punti lampeggianti localmente) e acquisiamo immagini di quei pattern a punti. (Possiamo renderli più densi, fino a quando non diventano barre, una tecnica nota come luce strutturata.) Dopo aver rilevato dalle immagini della telecamera e decodificato quei punti in codici binari, otteniamo la fotocamera < -> corrispondenza pixel del proiettore, bene una certa quantità di vertici comunque, e da lì è il 100% della grafica. Qui è una carta che copre questi passi in qualche dettaglio in più:

Zollmann, S., Langlotz, T. e Bimber, O.
passivo-attivo di calibrazione geometrica per proiezioni view-dependent Onto arbitrarie Superfici
http://140.78.90.140/medien/ar/Pub/PAGC_final.pdf
Demo video: http://140.78.90.140/medien/ar/Pub/PAGC.avi

EDIT2: proiettando un tipo di motivo, possiamo calcolare le coordinate dei pixel nell'immagine del proiettore che corrisponde a un dato pixel nell'immagine della telecamera. Spesso usiamo schemi di punti temporali perché è facile da rilevare e decodificare ... E in realtà, OpenCV potrebbe rivelarsi utile per questo. Il modo in cui penso che proverei a farlo sarebbe qualcosa di simile. Prendiamo solo 2 bit per semplicità. Abbiamo quindi quattro immagini: 00, 01, 10 e 11. Dal momento che controlliamo l'immagine del proiettore, le conosciamo, ma dobbiamo trovarle anche nell'immagine della videocamera. Per prima cosa prenderei l'ultima immagine (fotocamera), 11, e la sottrai dalla prima immagine (fotocamera) 00, usando cvAbsDiff(), quindi esegui il binarize del risultato con cvThreshold(), e trova i contorni (o blob) nel binario immagine con cvFindContours(). Dovremmo assicurarci che ogni contorno abbia un'area appropriata con cvContourArea(), mentre possiamo trovare il suo centroide con cvMoments(). Quindi possiamo iniziare a fare cose con le altre immagini. Per ogni contorno, proverei a prendere il cvBoundingRect() in cvCountNonZero() pixel nelle altre immagini (anche binarizzate con cvThreshold() camera), all'interno di questi rettangoli di delimitazione, che possiamo impostare tramite cvSetImageROI().Se il conteggio diverso da zero è grande, dovrebbe essere registrato come 1, in caso contrario, a 0.

Una volta che hai tutti i bit, hai il codice e il gioco è fatto.

+0

Grazie, era esattamente quello che stavo cercando. Non capisco perché utilizzare i dot pattern e come costruire la mappa di spostamento da esso, ma questo dovrebbe essere chiaro dopo aver studiato il documento. – bkausbk

+0

Suona come quello che ti serve, fantastico! Aggiungerò un po 'di dettagli in più per la completezza ... –

Problemi correlati