2013-10-30 14 views
6

Ich erkenne Markierungen auf Bildern von meinem iPad gefangen. Aus diesem Grund möchte ich Übersetzungen und Rotationen zwischen ihnen berechnen, ich möchte ändern Perspektive auf Bilder dieses Bild ändern, so dass es aussehen würde, als ob ich sie direkt über Markierungen gefangen bin.OpenCV: wrapPerspective für das ganze Bild

Im Moment bin ich mit

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)); 

Welche meine diese Ergebnisse gibt (Blick auf die rechte untere Ecke zum Ergebnis warpPerspective):

photo 1 photo 2 photo 3

Wie Wahrscheinlich sehen Sie, dass das Ergebnisbild eine erkannte Markierung in der linken oberen Ecke des Ergebnisbildes enthält. Mein Problem ist, dass ich das gesamte Bild (ohne Zuschneiden) erfassen möchte, damit ich später andere Markierungen auf diesem Bild erkennen kann.

Wie kann ich das tun? Vielleicht sollte ich Dreh-/Übersetzungsvektoren von solvePnP Funktion verwenden?

EDIT:

Unfortunatelly Ändern Größe von verzogenen Bild nicht viel helfen, weil Bild noch so Ecke links oben übersetzt von Marker ist in oberen linken Ecke des Bildes.

Zum Beispiel, wenn ich habe Größe verdoppelt werden:

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

Ich habe diese Bilder empfangen:

photo 4 photo 5

Antwort

3

Ihr Code scheint nicht vollständig zu sein, so Es ist schwer zu sagen, was das Problem ist.

In jedem Fall kann das verzerrte Bild im Vergleich zum Eingabebild völlig andere Dimensionen haben, daher müssen Sie den Größenparameter anpassen, den Sie für warpPerspective verwenden.

Zum Beispiel versuchen, die Größe zu verdoppeln:

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

Edit:

sicher zu gehen, das gesamte Bild innerhalb dieses Bildes ist, alle Ecken des Originalbilds muss verworfen werden im Innern des resultierenden zu sein Bild. Berechnen Sie einfach das verzerrte Ziel für jeden der Eckpunkte und passen Sie die Zielpunkte entsprechend an.

Um es zu machen einige Beispiel-Code löschen:

// 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

Ich weiß, dass Bildausgabe unterschiedliche dimenstions haben kann, ich habe sie mit Verdoppelung versucht (für Ergebnisse bei editierte Frage aussehen), aber es hat nicht gab mir nützliche Ergebnisse. Sie sagen, dass mein Code unvollständig ist - was soll ich hinzufügen? Ich benutze 'getPerspectiveTransform', um Transformationsmatrix zu erhalten, und verwende Koordinaten von Ecken von erkannten Markern dort als 'dst'-Matrix (laut OpenCV-Dokumentation - http://docs.opencv.org/modules/imgproc) /doc/geometric_transformations.html#getperspectivetransform). – Axadiw

+0

Nun, ich denke, Ihre Zielkoordinaten (-6, -6) usw. sind ein bisschen komisch. Das bedeutet, dass Ihr Zielrechteck im resultierenden Bild an diesen Koordinaten liegt. Um sie zu verschieben, verschieben Sie das Zielrechteck einfach in die Mitte des Zielbildes. – littleimp

+0

Danke - Ich habe herausgefunden, dass ich ein falsches points2D-Array gepostet habe (ich habe es gerade in der Frage bearbeitet). Das Verschieben dieser Punkte hat das gesamte Ausgabebild verschoben, aber ich schneide immer noch einige Teile davon. – Axadiw