Я пытаюсь использовать класс сшивателя OpenCV для сшивания нескольких кадров из стереоустановки, в которой ни одна камера не движется. Я получаю плохие результаты сшивки при работе с несколькими кадрами. Я пробовал несколько разных способов, которые я попытаюсь объяснить здесь.
Используя stitcher.stitch( )
Учитывая стереопару представлений, я запустил следующий код для некоторых кадров (VideoFile
— это пользовательская оболочка для объекта OpenCV VideoCapture
):
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();
}
Это дало действительно неплохие результаты для каждого кадра, но, поскольку параметры оцениваются для каждого кадра, помещаемого в видео, вы могли видеть небольшие различия в сшивке, где параметры немного отличались.
Использование estimateTransform( )
и composePanorama( )
Чтобы обойти проблему вышеуказанного метода, я решил попробовать оценить параметры только на первом кадре, а затем использовать composePanorama( )
для сшивания всех последующих кадров.
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
}
К сожалению, существует ошибка (задокументирована здесь), из-за которой два представления расходятся в очень странным образом, как на изображениях ниже:
Кадр 1:
Кадр 2:
...
Кадр 8:
Очевидно, это бесполезно, но я подумал, что это может быть просто из-за ошибки, которая в основном продолжает умножать матрицу внутренних параметров на константу каждый раз, когда вызывается composePanorama()
. Поэтому я сделал небольшой патч для исправления ошибки, чтобы этого не происходило, но тогда результаты сшивания были плохими. Патч ниже (modules/stitching/src/stitcher.cpp
), результаты после него:
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;
Результаты:
Кто-нибудь знает, как я могу решить эту проблему? По сути, мне нужно выполнить преобразование один раз, а затем применить его к оставшимся кадрам (мы говорим о 30 минутах видео).
В идеале я ищу совет по исправлению класса сшивателя, но я хотел бы попробовать другое решение вручную. Более ранняя попытка, которая включала поиск точек SURF, их корреляцию и поиск гомографии, дала довольно плохие результаты по сравнению с классом сшивателя, поэтому я бы предпочел использовать его, если это возможно.