Ich benutze 4 stationäre Kameras. Kameras bewegen sich nicht relativ zueinander . Und ich möchte Videobilder von ihnen in Echtzeit in das Videobild einfügen.
Ich verwende für diese OpenCV 2.4.10 und cv:stitcher
Klasse, so:
Ich bekomme nur 10 FPS (Bild pro Sekunde), aber ich brauche 25 FPS. Wie kann ich dieses Beispiel beschleunigen?
Wenn ich stitcher.setWarper(new cv::PlaneWarperGpu());
verwende, dann bekomme ich ein sehr vergrößertes Bild, das brauche ich nicht.
Ich brauche nur - Übersetzungen .
Zum Beispiel bin ich bereit, nicht zu verwenden:
Wie kann ich es tun? Oder wie komme ich von cv::Stitcher stitcher
parameters x,y
der Übersetzungen für jedes Bild?
UPDATE - Profilerstellung in MSVS 2013 unter Windows 7 x64:
cv::Stitcher
ist ziemlich langsam. Wenn sich Ihre Kameras definitiv nicht relativ zueinander bewegen und die Transformation so einfach ist, wie Sie sagen, sollten Sie in der Lage sein, die Bilder auf einer leeren Leinwand zu überlagern, indem Sie einfach Homographien .
Das Folgende ist etwas mathematisch - wenn das nicht klar ist, kann ich es richtig mit LaTeX schreiben, aber SO unterstützt keine schöne Mathematik:)
Sie haben einen Satz von 4 Kameras, von links nach rechts, (C_1, C_2, C_3, C_4)
, was einen Satz von 4 Bildern (I_1, I_2, I_3, I_4)
ergibt.
Um von I_1
nach I_2
zu transformieren, haben Sie eine 3x3 Transformationsmatrix, eine Homographie. Wir nennen das H_12
. Ähnlich haben wir für I_2
bis I_3
H_23
und für I_3
bis I_4
haben Sie H_34
.
Sie können diese Homographien vorab mit der Standardmethode ( Punktabgleich zwischen den Überlappungen) vorkalibrieren Kameras ).
Sie müssen eine leere Matrix erstellen, die als Leinwand fungiert. Sie können die Größe schätzen (4 * image_size würde genügen) oder Sie können die obere rechte Ecke nehmen (nennen Sie P1_tr
) und transformieren Sie sie nach den drei Homographien, geben Sie einen neuen Punkt oben rechts im Panorama , PP_tr
(im Folgenden wird angenommen, dass P1_tr
in eine Matrix konvertiert wurde):
Was das macht, ist P1_tr
zu übernehmen und es zuerst in Kamera 2 zu transformieren, dann von C_2
nach C_3
und schließlich von C_3
nach C_4
Sie müssen eine davon erstellen, um Bilder 1 und 2, Bilder 1,2 und 3 und schließlich Bilder 1-4 zu kombinieren. Ich werde sie als V_12
, V_123
und V_1234
bezeichnen. jeweils.
Verwenden Sie Folgendes, um das Bild auf die Leinwand zu verzerren:
%Vor%Machen Sie dasselbe mit den nächsten Bildern:
%Vor%Jetzt haben Sie vier Leinwände, von denen alle die Breite der 4 kombinierten Bilder sind, und eines der Bilder an jeder Stelle in den entsprechenden Platz transformiert wird.
Es bleibt nur noch übrig, die transformierten Bilder aufeinander zu verschmelzen. Dies wird leicht durch die Verwendung von Regionen von Interesse erreicht.
Das Erstellen der ROI-Masken kann im Voraus erfolgen, bevor die Bildaufnahme beginnt.
Beginnen Sie mit einem leeren Bild (Nullen), das der Größe Ihrer Leinwände entspricht. Setzen Sie das linke Rechteck auf die Größe von I_1
auf weiß. Dies ist die Maske für dein erstes Bild. Wir nennen es M_1
.
Als nächstes, um die Maske für das zweite transformierte Bild zu erhalten, machen wir
%Vor%Um alle Bilder zu einem Panorama zusammenzufügen, tun Sie:
%Vor%Was Sie hier tun, ist Kopieren des relevanten Bereichs jeder Zeichenfläche auf das Ausgabebild, pano - eine schnelle Operation.
Sie sollten dies alles auf der GPU tun können, indem Sie cv::gpu::Mat
für cv::Mats
und cv::gpu::warpAffine
für sein Nicht-GPU-Pendant ersetzen.
Hinweis: Ich überlasse diese Antwort nur als eine Dokumentation von dem, was versucht wurde, da die von mir vorgeschlagene Methode nicht zu funktionieren scheint, während die GPU anscheinend bereits verwendet wird, wenn cv :: Mat verwendet wird.
Versuchen Sie es mit gpu::GpuMat
:
Tags und Links c++ opencv opencv3.0 image-stitching opencv-stitching