В этом примере показано, как стабилизировать видео, которое было записано с нервной платформы. Один способ стабилизировать видео состоит в том, чтобы отследить существенную функцию в изображении и использовать это в качестве точки привязки, чтобы уравновесить все возмущения относительно него. Эта процедура, однако, должна быть загружена со знанием того, где такая существенная функция находится в первом видеокадре. В этом примере мы исследуем метод видео стабилизации, которая работает без любого такого априорного ведома. Это вместо этого автоматически ищет "фоновую плоскость" в видео последовательности и использует ее наблюдаемое искажение, чтобы откорректировать для движения камеры.
Этот алгоритм стабилизации включает два шага. Во-первых, мы определяем аффинные преобразования изображений между всеми соседними системами координат видео последовательности с помощью estimateGeometricTransform2D
функция, примененная к соответствиям точки между двумя изображениями. Во-вторых, мы деформируем видеокадры, чтобы достигнуть стабилизированного видео. Мы будем использовать Computer Vision Toolbox™, и для алгоритма и для отображения.
Здесь мы читаем в первых двух системах координат видео последовательности. Мы читаем их, когда интенсивность отображает, поскольку цвет не необходим для алгоритма стабилизации, и потому что использование полутоновых изображений улучшает скорость. Ниже мы показываем обе системы координат рядом друг с другом, и мы производим красно-голубой цветной составной объект, чтобы проиллюстрировать мудрое пикселем различие между ними. Между двумя системами координат существует, очевидно, большое вертикальное и горизонтальное смещение.
filename = 'shaky_car.avi'; hVideoSrc = VideoReader(filename); imgA = rgb2gray(im2single(readFrame(hVideoSrc))); % Read first frame into imgA imgB = rgb2gray(im2single(readFrame(hVideoSrc))); % Read second frame into imgB figure; imshowpair(imgA, imgB, 'montage'); title(['Frame A', repmat(' ',[1 70]), 'Frame B']);
figure; imshowpair(imgA,imgB,'ColorChannels','red-cyan'); title('Color composite (frame A = red, frame B = cyan)');
Наша цель состоит в том, чтобы определить преобразование, которое откорректирует для искажения между двумя системами координат. Мы можем использовать estimateGeometricTransform2D
функция для этого, которое возвратит смежное преобразование. Как введено мы должны предоставить этой функции набор соответствий точки между двумя системами координат. Чтобы сгенерировать эти соответствия, мы сначала собираем интересные места из обеих систем координат, затем избранные вероятные соответствия между ними.
На этом шаге мы производим эти точки кандидата для каждой системы координат. Чтобы иметь лучшую возможность, что эти точки будут иметь соответствующие точки в другой системе координат, мы хотим точки вокруг существенных функций изображений, таких как углы. Для этого мы используем detectFASTFeatures
функция, которая реализует один из самых быстрых угловых алгоритмов обнаружения.
Обнаруженные точки от обеих систем координат показаны на рисунке ниже. Наблюдайте, сколько из них покрывает те же функции изображений, такие как точки вдоль древовидной линии, углов большого дорожного знака и углов автомобилей.
ptThresh = 0.1; pointsA = detectFASTFeatures(imgA, 'MinContrast', ptThresh); pointsB = detectFASTFeatures(imgB, 'MinContrast', ptThresh); % Display corners found in images A and B. figure; imshow(imgA); hold on; plot(pointsA); title('Corners in A');
figure; imshow(imgB); hold on; plot(pointsB); title('Corners in B');
Затем мы выбираем соответствия между точками, выведенными выше. Для каждой точки мы извлекаем дескриптор Fast Retina Keypoint (FREAK), сосредоточенный вокруг этого. Стоимостью соответствия, которую мы используем между точками, является Расстояние Хемминга, поскольку дескрипторы FREAK являются двоичными. Точки в кадре A и кадре B являются соответствующими предполагаемо. Обратите внимание на то, что нет никакого ограничения уникальности, таким образом, точки от кадра B могут соответствовать нескольким точкам в кадре A.
% Extract FREAK descriptors for the corners
[featuresA, pointsA] = extractFeatures(imgA, pointsA);
[featuresB, pointsB] = extractFeatures(imgB, pointsB);
Совпадайте с функциями, которые были найдены в токе и предыдущих системах координат. Поскольку дескрипторы FREAK являются двоичным файлом, matchFeatures
функционируйте использует Расстояние Хемминга, чтобы найти соответствующие точки.
indexPairs = matchFeatures(featuresA, featuresB); pointsA = pointsA(indexPairs(:, 1), :); pointsB = pointsB(indexPairs(:, 2), :);
На рисунке ниже показан тот же композитный цвет, что и выше, но добавлены точки из кадра а в красном цвете и точки из кадра B в зеленом цвете. Желтые линии рисуются между точками, чтобы показать соответствие, выбранное вышеописанной процедурой. Многие из этих соответствий верны, но существует также значительное число выбросов.
figure; showMatchedFeatures(imgA, imgB, pointsA, pointsB); legend('A', 'B');
Многие соответствия точки, полученные на предыдущем шаге, являются неправильными. Но мы можем все еще вывести устойчивую оценку геометрического преобразования между двумя изображениями с помощью Демонстрационного Согласия M-средства-оценки (MSAC) алгоритм, который является вариантом алгоритма RANSAC. Алгоритм MSAC реализован в estimateGeometricTransform2D
функция. Эта функция, когда дали набор соответствий точки, будет искать допустимые inlier соответствия. От них это затем выведет смежное преобразование, которое делает inliers из первого соответствия набора точек наиболее тесно с inliers от второго набора. Это смежное преобразование будет 3х3 матрицей формы:
[a_1 a_3 0; a_2 a_4 0; t_x t_y 1]
Параметры задайте шкалу, вращение и эффекты сдвига преобразования, в то время как параметры параметры перевода. Это преобразование может использоваться, чтобы деформировать изображения, таким образом, что их соответствующие функции будут перемещены в то же расположение изображения.
Ограничение смежного преобразования - то, что оно может только изменить плоскость обработки изображений. Таким образом это является неподходящим к нахождению общего искажения, между двумя системами взятого 3-D сцены, такой как с этим видео, снятым от движущегося автомобиля. Но это действительно работает при определенных обстоятельствах, которые мы опишем вскоре.
[tform, inlierIdx] = estimateGeometricTransform2D(... pointsB, pointsA, 'affine'); pointsBm = pointsB(inlierIdx, :); pointsAm = pointsA(inlierIdx, :); imgBp = imwarp(imgB, tform, 'OutputView', imref2d(size(imgB))); pointsBmp = transformPointsForward(tform, pointsBm.Location);
Ниже цветной кадр A показа составного объекта, наложенный с повторно спроектированным кадром B, наряду с повторно спроектированными соответствиями точки. Результаты превосходны с inlier соответствиями, почти точно совпадающими. Ядра изображений оба хорошо выравниваются, такие, что красно-голубой цветной составной объект становится почти чисто черно-белым в той области.
Отметьте, как inlier соответствия - все в фоновом режиме изображения, не на переднем плане, который самом не выравнивается. Это вызвано тем, что фоновые функции достаточно удалены, что они ведут себя, как будто они были на бесконечно удаленной плоскости. Таким образом, даже при том, что смежное преобразование ограничивается изменением только плоскости обработки изображений, здесь который достаточен, чтобы выровнять фоновые плоскости обоих изображений. Кроме того, если мы принимаем, что фоновая плоскость не переместилась или значительно изменилась между системами координат, затем это преобразование на самом деле получает движение камеры. Поэтому исправление для этого стабилизирует видео. Это условие будет содержать, пока движение камеры между системами координат мало достаточно, или, с другой стороны, если частота видеокадров достаточно высока.
figure; showMatchedFeatures(imgA, imgBp, pointsAm, pointsBmp); legend('A', 'B');
Учитывая набор видеокадров , мы можем теперь использовать вышеупомянутую процедуру, чтобы оценить искажение между всеми системами координат и как смежные преобразования, . Таким образом совокупное искажение системы координат относительно первой системы координат будет продукт всех предыдущих межкадровых преобразований, или
Мы могли использовать все шесть параметров смежного преобразования выше, но, для числовой простоты и устойчивости, мы принимаем решение переоборудовать матрицу как более простое преобразование масштаб-поворот-перевод. Это имеет только четыре свободных параметра по сравнению с шестью полного смежного преобразования: один масштабный коэффициент, один угол и два перевода. Это новое преобразовывает матрицу, имеет форму:
[s*cos(ang) s*-sin(ang) 0; s*sin(ang) s*cos(ang) 0; t_x t_y 1]
Мы показываем, что эта процедура преобразования ниже путем подбора кривой вышеупомянутому - полученный преобразовывает с эквивалентным переводом вращения шкалы, Чтобы показать, что ошибка преобразования преобразования минимальна, мы перепроектируем кадр B с обоими преобразованиями и покажем два изображения ниже в виде красно-голубого цветного композита. Поскольку изображение выглядит черно-белым, очевидно, что пиксельная разница между различными репроекциями незначительна.
% Extract scale and rotation part sub-matrix. H = tform.T; R = H(1:2,1:2); % Compute theta from mean of two possible arctangents theta = mean([atan2(R(2),R(1)) atan2(-R(3),R(4))]); % Compute scale from mean of two stable mean calculations scale = mean(R([1 4])/cos(theta)); % Translation remains the same: translation = H(3, 1:2); % Reconstitute new s-R-t transform: HsRt = [[scale*[cos(theta) -sin(theta); sin(theta) cos(theta)]; ... translation], [0 0 1]']; tformsRT = affine2d(HsRt); imgBold = imwarp(imgB, tform, 'OutputView', imref2d(size(imgB))); imgBsRt = imwarp(imgB, tformsRT, 'OutputView', imref2d(size(imgB))); figure(2), clf; imshowpair(imgBold,imgBsRt,'ColorChannels','red-cyan'), axis image; title('Color composite of affine and s-R-t transform outputs');
Теперь мы применяем перечисленные выше шаги, чтобы сглаживать видео последовательность. Для удобочитаемости вышеупомянутая процедура оценки преобразования между двумя изображениями была помещена в функцию MATLAB® cvexEstStabilizationTform. Функция cvexTformToSRT также преобразует общее смежное преобразование в преобразование масштаб-поворот-перевод.
На каждом шаге мы вычисляем преобразование между существующими системами координат. Мы соответствуем этому, когда s-R-t преобразовывает, . Затем мы комбинируем это совокупное преобразование, , который описывает все движение камеры начиная с первой системы координат. Последние две системы координат сглаживавшего видео показывают в Видеоплеере как красно-голубой составной объект.
С помощью этого кода вы также можете вывести условие раннего выхода, чтобы цикл обработал все видео.
% Reset the video source to the beginning of the file. read(hVideoSrc, 1); hVPlayer = vision.VideoPlayer; % Create video viewer % Process all frames in the video movMean = rgb2gray(im2single(readFrame(hVideoSrc))); imgB = movMean; imgBp = imgB; correctedMean = imgBp; ii = 2; Hcumulative = eye(3); while hasFrame(hVideoSrc) && ii < 10 % Read in new frame imgA = imgB; % z^-1 imgAp = imgBp; % z^-1 imgB = rgb2gray(im2single(readFrame(hVideoSrc))); movMean = movMean + imgB; % Estimate transform from frame A to frame B, and fit as an s-R-t H = cvexEstStabilizationTform(imgA,imgB); HsRt = cvexTformToSRT(H); Hcumulative = HsRt * Hcumulative; imgBp = imwarp(imgB,affine2d(Hcumulative),'OutputView',imref2d(size(imgB))); % Display as color composite with last corrected frame step(hVPlayer, imfuse(imgAp,imgBp,'ColorChannels','red-cyan')); correctedMean = correctedMean + imgBp; ii = ii+1; end correctedMean = correctedMean/(ii-2); movMean = movMean/(ii-2); % Here you call the release method on the objects to close any open files % and release memory. release(hVPlayer);
Во время расчета мы вычисляли среднее значение необработанных видеокадров и исправленных кадров. Эти средние значения показывают рядом друг с другом ниже. Левое изображение показывает среднее значение необработанных входных кадров, доказывая, что в исходном видео было много искажений. Среднее значение исправленных кадров справа, однако, показывает ядро изображения почти без искажений. В то время как детали переднего плана были размыты (как необходимый результат движения автомобиля вперед), это показывает эффективность алгоритма стабилизации.
figure; imshowpair(movMean, correctedMean, 'montage'); title(['Raw input mean', repmat(' ',[1 50]), 'Corrected sequence mean']);
[1] Тордофф, B; Мюррей, DW. "Ведомая выборка и согласие для оценки движения". Европейская Конференция n Компьютерное зрение, 2002.
[2] Ли, KY; Чуан, YY; Чен, BY; Ouhyoung, M. "Видео Стабилизация с помощью Устойчивых Траекторий Функции". Национальный университет Тайваня, 2009.
[3] Литвин, A; Конрад, J; Карл, WC. "Вероятностная видео стабилизация с помощью Кальмана, фильтрующего и mosaicking". Симпозиум IS&T/SPIE по Электронной Обработке изображений, Изображению и Video Communications и Proc., 2003.
[4] Matsushita, Y; Ofek, E; сильный запах, X; Shum, HY. "Стабилизация видео полной системы координат". Microsoft® Research Asia. CVPR 2005.