Klasa Stitcher OpenCV z nakładającymi się stacjonarnymi kamerami

Próbuję użyć klasy zszywacza OpenCV do łączenia wielu klatek z konfiguracji stereo, w której żadna kamera się nie porusza. Dostaję słabe wyniki łączenia podczas uruchamiania wielu klatek. Próbowałem kilku różnych sposobów, które spróbuję wyjaśnić tutaj.

Za pomocąstitcher.stitch( )

Biorąc pod uwagę stereofoniczną parę widoków, uruchomiłem następujący kod dla niektórych ramek (VideoFile to niestandardowe opakowanie dla OpenCVVideoCapture obiekt):

VideoFile f1( ... );
VideoFile f2( ... );
cv::Mat output_frame;
cv::Stitcher stitcher = cv::Stitcher::createDefault(true);

for( int i = 0; i < num_frames; i++ ) {
    currentFrames.push_back(f1.frame( ));
    currentFrames.push_back(f2.frame( ));
    stitcher.stitch( currentFrames, output_mat );

    // Write output_mat, put it in a named window, etc...

    f1.next_frame();
    f2.next_frame();
    currentFrames.clear();
}

Dało to naprawdę całkiem dobre wyniki na każdej klatce, ale ponieważ parametry są szacowane dla każdej klatki umieszczonej w filmie, można było zobaczyć małe różnice w szyciu, gdzie parametry były nieco inne.

Za pomocąestimateTransform( ) & composePanorama( )

Aby ominąć problem powyższej metody, postanowiłem spróbować oszacować parametry tylko na pierwszej klatce, a następnie użyćcomposePanorama( ) zszyć wszystkie kolejne klatki.

for( int i = 0; i < num_frames; i++ ) {
    currentFrames.push_back(f1.frame( ));
    currentFrames.push_back(f2.frame( ));

    if( ! have_transform ) {
        status = stitcher.estimateTransform( currentFrames );
    }

    status = stitcher.composePanorama(currentFrames, output_frame );

    // ... as above
}

Niestety wydaje się, że jest błąd (udokumentowane tutaj) powodując, że dwa widoki rozsuwają się w bardzo dziwny sposób, jak na zdjęciach poniżej:

Ramka 1:

Ramka 2:

...

Ramka 8:

Najwyraźniej jest to bezużyteczne, ale pomyślałem, że może to być spowodowane błędem, który w zasadzie ciągle powtarza macierz parametrów wewnętrznych przez stałą za każdym razemcomposePanorama() jest nazywany. Zrobiłem więc niewielką poprawkę na błąd, uniemożliwiając to, ale potem wyniki łączenia były słabe. Patch poniżej (modules/stitching/src/stitcher.cpp), wyniki później:

243             for (size_t i = 0; i < imgs_.size(); ++i)
244             {
245                 // Update intrinsics
246                // change following to *=1 to prevent scaling error, but messes up stitching.
247                 cameras_[i].focal *= compose_work_aspect;
248                 cameras_[i].ppx *= compose_work_aspect;
249                 cameras_[i].ppy *= compose_work_aspect; 

Wyniki:

Czy ktoś ma pojęcie, jak mogę rozwiązać ten problem? Zasadniczo muszę wypracować transformacjępewnego razu, a następnie użyj go w pozostałych klatkach (mówimy o 30 minutach wideo).

Idealnie szukam porady na temat łatania klasy zszywacza, ale chętnie spróbuję zakodować inne rozwiązanie. Wcześniejsza próba polegająca na znalezieniu punktów SURF, skorelowaniu ich i znalezieniu homografii dała dość słabe wyniki w porównaniu z klasą zszywaczy, więc wolałbym ją wykorzystać, jeśli to możliwe.

questionAnswers(1)

yourAnswerToTheQuestion