2013-10-30 18 views
6

Sto rilevando i contrassegni sulle immagini catturate dal mio iPad. Per questo motivo voglio calcolare le traduzioni e le rotazioni tra di loro, voglio cambiare il punto di vista delle immagini su queste immagini, quindi sembrerebbe che le stia catturando direttamente sopra i marker.OpenCV: wrapPerspective su immagine intera

Proprio ora sto usando

points2D.push_back(cv::Point2f(0, 0)); 
points2D.push_back(cv::Point2f(50, 0)); 
points2D.push_back(cv::Point2f(50, 50)); 
points2D.push_back(cv::Point2f(0, 50)); 

Mat perspectiveMat = cv::getPerspectiveTransform(points2D, imagePoints); 
cv::warpPerspective(*_image, *_undistortedImage, M, cv::Size(_image->cols, _image->rows)); 

che dà le mie questi risultati (guarda nell'angolo in basso a destra per risultato di warpPerspective):

photo 1 photo 2 photo 3

Come probabilmente vedi l'immagine del risultato contenente un marker riconosciuto nell'angolo in alto a sinistra dell'immagine del risultato. Il mio problema è che voglio catturare l'intera immagine (senza ritagliare) in modo da poter rilevare altri marcatori su quell'immagine in seguito.

Come posso farlo? Forse dovrei usare i vettori di rotazione/traduzione dalla funzione solvePnP?

EDIT:

Purtroppo la modifica delle dimensioni dell'immagine distorta non aiutano molto, perché l'immagine è ancora tradotto in modo superiore sinistro del marcatore è in alto a sinistra dell'immagine.

Per esempio, quando ho raddoppiato dimensioni utilizzando:

cv::warpPerspective(*_image, *_undistortedImage, M, cv::Size(2*_image->cols, 2*_image->rows)); 

ho recieved queste immagini:

photo 4 photo 5

risposta

3

Il codice non sembra essere completa, così è difficile dire quale sia il problema.

In ogni caso l'immagine deformata potrebbe avere completamente dimensioni diverse rispetto all'immagine in ingresso in modo da avere per regolare la dimensione paramter utilizzato per warpPerspective.

Per esempio cercare di raddoppiare le dimensioni:

cv::warpPerspective(*_image, *_undistortedImage, M, 2*cv::Size(_image->cols, _image->rows)); 

Edit:

Per assicurarsi che l'intera immagine è all'interno di questa immagine, tutti gli angoli della vostra immagine originale deve essere deformato per essere dentro la risultante Immagine. Così semplicemente calcolare la destinazione deformato per ciascuno dei punti d'angolo e regolare i punti di destinazione di conseguenza.

Per renderlo più chiaro alcuni esempi di codice:

// calculate transformation 
cv::Matx33f M = cv::getPerspectiveTransform(points2D, imagePoints); 

// calculate warped position of all corners 

cv::Point3f a = M.inv() * cv::Point3f(0, 0, 1); 
a = a * (1.0/a.z); 

cv::Point3f b = M.inv() * cv::Point3f(0, _image->rows, 1); 
b = b * (1.0/b.z); 

cv::Point3f c = M.inv() * cv::Point3f(_image->cols, _image->rows, 1); 
c = c * (1.0/c.z); 

cv::Point3f d = M.inv() * cv::Point3f(_image->cols, 0, 1); 
d = d * (1.0/d.z); 

// to make sure all corners are in the image, every position must be > (0, 0) 
float x = ceil(abs(min(min(a.x, b.x), min(c.x, d.x)))); 
float y = ceil(abs(min(min(a.y, b.y), min(c.y, d.y)))); 

// and also < (width, height) 
float width = ceil(abs(max(max(a.x, b.x), max(c.x, d.x)))) + x; 
float height = ceil(abs(max(max(a.y, b.y), max(c.y, d.y)))) + y; 

// adjust target points accordingly 
for (int i=0; i<4; i++) { 
    points2D[i] += cv::Point2f(x,y); 
} 

// recalculate transformation 
M = cv::getPerspectiveTransform(points2D, imagePoints); 

// get result 
cv::Mat result; 
cv::warpPerspective(*_image, result, M, cv::Size(width, height), cv::WARP_INVERSE_MAP); 
+0

So che l'immagine di uscita può avere diverse dimenstions, ho provato con loro raddoppio (guarda domanda curato per risultati), ma non ha mi ha dato risultati utili Hai detto che il mio codice è incompleto - cosa dovrei aggiungere di? Sto utilizzando 'getPerspectiveTransform' per ottenere matrice di trasformazione, e sto usando coordinate di angoli di marcatore rilevato là come' dst' matrice (secondo la documentazione OpenCV - http://docs.opencv.org/modules/imgproc /doc/geometric_transformations.html#getperspectivetransform). – Axadiw

+0

Beh, penso che le coordinate del tuo obiettivo di (-6, -6) ecc. Siano un po 'strane. Perché ciò significa che il tuo rettangolo target sarà a queste coordinate nell'immagine risultante. Per spostarli semplicemente sposta il rettangolo di destinazione al centro dell'immagine di destinazione. – littleimp

+0

Grazie - Ho capito di aver postato l'array point2D sbagliato (l'ho modificato nella domanda in questo momento). Spostando un po 'questi punti si è spostato tutta l'immagine in uscita, ma ne sto ancora ritagliando alcune parti. – Axadiw