В этом примере показано, как удалить эффект движения камеры из видеопотока.
В этом примере мы сначала задаем цель для отслеживания. В этом случае это задняя часть автомобиля и номерной знак. Мы также устанавливаем динамическую область поиска, положение которой определяется последним известным целевым местоположением. Затем мы ищем цель только в этой области поиска, что уменьшает количество расчетов, необходимых для поиска цели. В каждом последующем видеокадре мы определяем, насколько цель переместилась относительно предыдущей системы координат. Мы используем эту информацию, чтобы удалить нежелательные поступательные движения камеры и сгенерировать стабилизированное видео.
Создайте Системную object™ для чтения видео из мультимедийного файла. Мы устанавливаем выход только видео интенсивности.
% Input video file which needs to be stabilized. filename = 'shaky_car.avi'; hVideoSource = VideoReader(filename);
Создайте шаблон matcher Системный объект, чтобы вычислить местоположение наилучшего соответствия цели в видеокадре. Мы используем это место, чтобы найти перевод между последующими видеокадрами.
hTM = vision.TemplateMatcher('ROIInputPort', true, ... 'BestMatchNeighborhoodOutputPort', true);
Создайте Системный объект для отображения исходного видео и стабилизированного видео.
hVideoOut = vision.VideoPlayer('Name', 'Video Stabilization'); hVideoOut.Position(1) = round(0.4*hVideoOut.Position(1)); hVideoOut.Position(2) = round(1.5*(hVideoOut.Position(2))); hVideoOut.Position(3:4) = [650 350];
Здесь мы инициализируем некоторые переменные, используемые в цикле обработки.
pos.template_orig = [109 100]; % [x y] upper left corner pos.template_size = [22 18]; % [width height] pos.search_border = [15 10]; % max horizontal and vertical displacement pos.template_center = floor((pos.template_size-1)/2); pos.template_center_pos = (pos.template_orig + pos.template_center - 1); W = hVideoSource.Width; % Width in pixels H = hVideoSource.Height; % Height in pixels BorderCols = [1:pos.search_border(1)+4 W-pos.search_border(1)+4:W]; BorderRows = [1:pos.search_border(2)+4 H-pos.search_border(2)+4:H]; sz = [W, H]; TargetRowIndices = ... pos.template_orig(2)-1:pos.template_orig(2)+pos.template_size(2)-2; TargetColIndices = ... pos.template_orig(1)-1:pos.template_orig(1)+pos.template_size(1)-2; SearchRegion = pos.template_orig - pos.search_border - 1; Offset = [0 0]; Target = zeros(18,22); firstTime = true;
Это основной цикл обработки, который использует объекты, которые мы создали выше, чтобы стабилизировать вход видео.
while hasFrame(hVideoSource) input = rgb2gray(im2double(readFrame(hVideoSource))); % Find location of Target in the input video frame if firstTime Idx = int32(pos.template_center_pos); MotionVector = [0 0]; firstTime = false; else IdxPrev = Idx; ROI = [SearchRegion, pos.template_size+2*pos.search_border]; Idx = hTM(input,Target,ROI); MotionVector = double(Idx-IdxPrev); end [Offset, SearchRegion] = updatesearch(sz, MotionVector, ... SearchRegion, Offset, pos); % Translate video frame to offset the camera motion Stabilized = imtranslate(input, Offset, 'linear'); Target = Stabilized(TargetRowIndices, TargetColIndices); % Add black border for display Stabilized(:, BorderCols) = 0; Stabilized(BorderRows, :) = 0; TargetRect = [pos.template_orig-Offset, pos.template_size]; SearchRegionRect = [SearchRegion, pos.template_size + 2*pos.search_border]; % Draw rectangles on input to show target and search region input = insertShape(input, 'Rectangle', [TargetRect; SearchRegionRect],... 'Color', 'white'); % Display the offset (displacement) values on the input image txt = sprintf('(%+05.1f,%+05.1f)', Offset); input = insertText(input(:,:,1),[191 215],txt,'FontSize',16, ... 'TextColor', 'white', 'BoxOpacity', 0); % Display video hVideoOut([input(:,:,1) Stabilized]); end
Используя функциональность Computer Vision Toolbox™ из командной строки MATLAB ®, легко реализовать такие сложные системы, как стабилизация видео.
В этом примере используется следующая вспомогательная функция.