视频防抖
本示例演示了如何从视频流中消除相机运动带来的影响。
简介
例如,在此示例中,我们首先定义要跟踪的目标。在这种情况下,是汽车的后部和车牌。我们还建立了一个动态搜索区域,其位置由已知的最后目标位置决定。然后,我们仅在此搜索区域内搜索目标,从而减少了查找目标所需的计算量。在随后的每一帧视频中,我们都会确定目标相对于上一帧移动了多少。我们利用这些信息来消除不需要的平移相机运动,并生成一段稳定的视频。
初始化
创建一个 System object™ 来读取多媒体文件中的视频。我们将输出设置为仅包含亮度信息的视频。
% Input video file which needs to be stabilized. filename = "shaky_car.avi"; hVideoSource = VideoReader(filename);
创建一个模板匹配器 System object,用于计算目标在视频帧中最佳匹配的位置。我们利用该位置来计算相邻视频帧之间的位移。
hTM = vision.TemplateMatcher("ROIInputPort", true, ... "BestMatchNeighborhoodOutputPort", true);
创建一个名为 System object 的文件,用于显示原始视频和防抖后的视频。
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 = im2gray(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

结论
利用 MATLAB® 命令行中的 Computer Vision Toolbox™ 函数,可以轻松实现视频防抖等复杂系统。
附录
本示例中使用了以下辅助函数。