Лучший алгоритм для стабилизации видео

Я создаю программу для стабилизации видеопотока. На данный момент моя программа работает на основе алгоритма фазовой корреляции. Я рассчитываю смещение между двумя изображениями — базовым и текущим. Затем я корректирую текущее изображение в соответствии с новыми координатами. Эта программа работает, но результат не является удовлетворительным. По соответствующим ссылкам вы можете обнаружить, что обработанное видео кажется нежелательным, а встряхивание всего видео становится все хуже.
Оригинальное видео
Неподтвержденное видео
Вот моя текущая реализация:
Расчет смещения между изображениями:

Point2d calculate_offset_phase_optimized(Mat one, Mat& two) {

if(two.type() != CV_64F) {
cvtColor(two, two, CV_BGR2GRAY);
two.convertTo(two, CV_64F);
}

cvtColor(one, one, CV_BGR2GRAY);
one.convertTo(one, CV_64F);

return phaseCorrelate(one, two);

}

Сдвиг изображения по этой координате:

void move_image_roi_alt(Mat& img, Mat& trans, const Point2d& offset) {

trans = Mat::zeros(img.size(), img.type());
img(
Rect(
_0(static_cast<int>(offset.x)),
_0(static_cast<int>(offset.y)),
img.cols-abs(static_cast<int>(offset.x)),
img.rows-abs(static_cast<int>(offset.y))
)
).copyTo(trans(
Rect(
_0ia(static_cast<int>(offset.x)),
_0ia(static_cast<int>(offset.y)),
img.cols-abs(static_cast<int>(offset.x)),
img.rows-abs(static_cast<int>(offset.y))
)
));
}

int _0(const int x) {
return x < 0 ? 0 : x;
}

int _0ia(const int x) {
return x < 0 ? abs(x) : 0;
}

Я просматривал документ авторов стабилизатора YouTube и алгоритм, основанный на обнаружении углов, показался мне привлекательным, но мне не совсем понятно, как он работает.
Поэтому мой вопрос заключается в том, как эффективно решить эту проблему.
Одно из условий — программа будет работать на медленных компьютерах, поэтому тяжелые алгоритмы могут не подойти.
Спасибо!
Постскриптум
Я прошу прощения за любые ошибки в тексте — это автоматический перевод.

5

Решение

Вы можете использовать дескрипторы изображений, такие как ПРОСЕЯТЬ в каждом кадре и рассчитать крепкий Матчи между кадрами. Тогда вы можете рассчитать гомография между кадрами и используйте это, чтобы выровнять их. Использование разреженных функций может привести к более быстрой реализации, чем использование плотной корреляции.

Альтернативно, если вы знаете параметры камеры вы можете рассчитать 3D-позиции точек и камер и перепроектировать изображения на устойчивую плоскость проекции. В результате вы также получите редкая 3D реконструкция сцены (несколько неточно, как правило, это должно быть оптимизированный быть пригодным для использования). Это то, что, например, AutoStitch сделал бы, но это довольно сложно реализовать, однако.

Обратите внимание, что параметры камеры также могут быть вычисленный, но это еще сложнее.

2

Другие решения

OpenCV может сделать это за вас в 3 строки кода (это, безусловно, самый короткий путь, может быть, даже лучший):

t = estimateRigidTransform(newFrame, referenceFrame, 0); // 0 means not all transformations (5 of 6)
if(!t.empty()){
warpAffine(newFrame, stableFrame, t, Size(newFrame.cols, newFrame.rows)); // stableFrame should be stable now
}

Вы можете отключить какие-то преобразования, изменив матрицу t, это может привести к более стабильному результату. Это просто основная идея, тогда вы можете изменить ее так, как вы хотите: изменить referenceFrame, сгладить набор параметров преобразования из матрицы t и т. Д.

2

По вопросам рекламы [email protected]