Open videostabilize.m in the Editor
Run in the Command Window

# Video Stabilization

This demo uses the Computer Vision System Toolbox™ to remove the effect of camera motion from a video stream. This demo is supported only on Windows® platforms.

## Contents

- Introduction
- Initialization
- Stream Processing Loop
- Release
- Conclusion
- Appendix

## Introduction

In this demo we first define the target to track. In this case, it is the back of a car and the license plate. We also establish a dynamic search region, whose position is determined by the last known target location. We then search for the target only within this search region, which reduces the number of computations required to find the target. In each subsequent video frame, we determine how much the target has moved relative to the previous frame. We use this information to remove unwanted translational camera motions and generate a stabilized video.

## Initialization

Create a System object to read video from a multimedia file. We set the output to be of intensity only video.

    % Input video file which needs to be stabilized.
    filename = 'shaky_car.avi';

    hVideoSource = vision.VideoFileReader(filename, ...
                                          'ImageColorSpace', 'Intensity',...
                                          'VideoOutputDataType', 'double');

Create a geometric translator System object used to compensate for the camera movement.

    hTranslate = vision.GeometricTranslator( ...
                                  'OutputSize', 'Same as input image', ...
                                  'OffsetSource', 'Input port');

Create a template matcher System object to compute the location of the best match of the target in the video frame. We use this location to find translation between successive video frames.

    hTM = vision.TemplateMatcher('ROIInputPort', true, ...
                                'BestMatchNeighborhoodOutputPort', true);

Create a System object to highlight the search region and target in the video by drawing rectangles around them.

    hShapeInserter = vision.ShapeInserter('BorderColor', 'White');

Create a System object to show the displacement values on the video.

    hTextInserter = vision.TextInserter('(%+05.1f,%+05.1f)', ...
                                       'Location', [191 215], ...
                                       'Color', 1, ...
                                       'FontSize', 16);

Create a System object to display the original video and the stabilized video.

    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];

Here we initialize some variables used in the processing loop.

    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);
    fileInfo = info(hVideoSource);
    W = fileInfo.VideoSize(1); % Width in pixels
    H = fileInfo.VideoSize(2); % 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 = fileInfo.VideoSize;
    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;

## Stream Processing Loop

This is the main processing loop which uses the objects we instantiated above to stabilize the input video.

    while ~isDone(hVideoSource)
        input = step(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 = step(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 = step(hTranslate, input, fliplr(Offset));

        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 = step(hShapeInserter, input, [TargetRect; SearchRegionRect]);

        % Display the offset values on the input image
        input = step(hTextInserter, input, Offset);

        % Display video
        step(hVideoOut, [input Stabilized]);
    end

## Release

Here you call the release method on the objects to close any open files and devices.

    release(hVideoSource);

## Conclusion

Using the Computer Vision System Toolbox™ functionality from MATLAB® command line it is easy to implement complex systems like video stabilization.

## Appendix

The following helper function is used in this demo.

- updatesearch.m