Main Content

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

映像安定化

この例では、ビデオ ストリームからカメラの動きの影響を排除する方法を説明します。

はじめに

この例では、まず追跡のターゲットを定義します。今の場合は自動車の後面とナンバー プレートです。また、動的な探索領域を設定しますが、その位置は、最後の既知のターゲット位置によって決まります。この領域内のみでターゲットを探索しますが、これによって、ターゲットの特定に必要な計算量が減ります。後続の各ビデオ フレームで、前のフレームと比べてターゲットがどれだけ動いたかを判定します。この情報を使用して望ましくないカメラの並進を排除し、画面の安定したビデオを生成します。

初期化

マルチメディア ファイルからビデオを読み取る 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™ の機能を使用すると、映像安定化のような複雑なシステムを簡単に実装できます。

付録

この例では次の補助関数が使用されています。