Main Content

このページの翻訳は最新ではありません。ここをクリックして、英語の最新版を参照してください。

カスタム ユーザー インターフェイスでのビデオ表示

この例では、カスタムのグラフィカル ユーザー インターフェイス (GUI) に複数のビデオ ストリームを表示する方法を説明します。

概要

動画処理を行うプロジェクトの作業では、カスタムのユーザー インターフェイスを作成することがよくあります。これが必要とされるのは、入力ビデオ ストリームに対するアルゴリズムの効果の可視化や実証を行う場合などです。この例では、2 つの座標軸をもつ Figure ウィンドウを作成して、2 つのビデオ ストリームを表示する方法を説明します。また、ボタンとそれに対応するコールバックを設定する方法についても説明します。

この例では、本体部分が上部にあり、ヘルパー ルーチンが入れ子関数の形式になっている関数として記述されています。

function VideoInCustomGUIExample()

ビデオ リーダーを初期化します。

videoSrc = vision.VideoFileReader('vipmen.avi', 'ImageColorSpace', 'Intensity');

入力ビデオおよび処理されたビデオを表示するための Figure ウィンドウと 2 つの座標軸を作成します。

[hFig, hAxes] = createFigureAndAxes();

ビデオの再生を制御するボタンを追加します。

insertButtons(hFig, hAxes, videoSrc);

新しいユーザー インターフェイスの操作

GUI が作成されたので、再生ボタンを押して、後述する関数 getAndProcessFrame で定義されているメインの動画処理ループをトリガーできます。

% Initialize the display with the first frame of the video
frame = getAndProcessFrame(videoSrc, 0);
% Display input video frame on axis
showFrameOnAxis(hAxes.axis1, frame);
showFrameOnAxis(hAxes.axis2, zeros(size(frame)+60,'uint8'));

各ビデオ フレームが軸のボックスの中央に配置されていることに注意してください。座標軸のサイズがフレーム サイズより大きい場合、ビデオ フレームの境界は背景色で埋められます。座標軸のサイズがフレーム サイズより小さい場合は、スクロール バーが追加されます。

Figure、座標軸、タイトルの作成

2 つのビデオを表示するため、Figure ウィンドウおよびタイトル付きの 2 つの座標軸を作成します。

    function [hFig, hAxes] = createFigureAndAxes()

        % Close figure opened by last run
        figTag = 'CVST_VideoOnAxis_9804532';
        close(findobj('tag',figTag));

        % Create new figure
        hFig = figure('numbertitle', 'off', ...
               'name', 'Video In Custom GUI', ...
               'menubar','none', ...
               'toolbar','none', ...
               'resize', 'on', ...
               'tag',figTag, ...
               'renderer','painters', ...
               'position',[680 678 480 240],...
               'HandleVisibility','callback'); % hide the handle to prevent unintended modifications of our custom UI

        % Create axes and titles
        hAxes.axis1 = createPanelAxisTitle(hFig,[0.1 0.2 0.36 0.6],'Original Video'); % [X Y W H]
        hAxes.axis2 = createPanelAxisTitle(hFig,[0.5 0.2 0.36 0.6],'Rotated Video');

    end

座標軸とタイトルの作成

座標軸は uipanel コンテナー オブジェクト上に作成されます。これにより、GUI のレイアウトをより細かく制御できるようになります。ビデオのタイトルは uicontrol を使って作成します。

    function hAxis = createPanelAxisTitle(hFig, pos, axisTitle)

        % Create panel
        hPanel = uipanel('parent',hFig,'Position',pos,'Units','Normalized');

        % Create axis
        hAxis = axes('position',[0 0 1 1],'Parent',hPanel);
        hAxis.XTick = [];
        hAxis.YTick = [];
        hAxis.XColor = [1 1 1];
        hAxis.YColor = [1 1 1];
        % Set video title using uicontrol. uicontrol is used so that text
        % can be positioned in the context of the figure, not the axis.
        titlePos = [pos(1)+0.02 pos(2)+pos(3)+0.3 0.3 0.07];
        uicontrol('style','text',...
            'String', axisTitle,...
            'Units','Normalized',...
            'Parent',hFig,'Position', titlePos,...
            'BackgroundColor',hFig.Color);
    end

ボタンの挿入

ビデオの再生と一時停止を行うボタンを挿入します。

    function insertButtons(hFig,hAxes,videoSrc)

        % Play button with text Start/Pause/Continue
        uicontrol(hFig,'unit','pixel','style','pushbutton','string','Start',...
                'position',[10 10 75 25], 'tag','PBButton123','callback',...
                {@playCallback,videoSrc,hAxes});

        % Exit button with text Exit
        uicontrol(hFig,'unit','pixel','style','pushbutton','string','Exit',...
                'position',[100 10 50 25],'callback', ...
                {@exitCallback,videoSrc,hFig});
    end

再生ボタンのコールバック

このコールバック関数は、入力ビデオ フレームを回転させて、元の入力ビデオ フレームと回転させたフレームを座標軸上に表示します。ユーザー定義の軸上にビデオのフレームを表示するのは、関数 showFrameOnAxis です。この関数は showFrameOnAxis.m というファイルで定義されています。

    function playCallback(hObject,~,videoSrc,hAxes)
       try
            % Check the status of play button
            isTextStart = strcmp(hObject.String,'Start');
            isTextCont  = strcmp(hObject.String,'Continue');
            if isTextStart
               % Two cases: (1) starting first time, or (2) restarting
               % Start from first frame
               if isDone(videoSrc)
                  reset(videoSrc);
               end
            end
            if (isTextStart || isTextCont)
                hObject.String = 'Pause';
            else
                hObject.String = 'Continue';
            end

            % Rotate input video frame and display original and rotated
            % frames on figure
            angle = 0;
            while strcmp(hObject.String, 'Pause') && ~isDone(videoSrc)
                % Get input video frame and rotated frame
                [frame,rotatedImg,angle] = getAndProcessFrame(videoSrc,angle);
                % Display input video frame on axis
                showFrameOnAxis(hAxes.axis1, frame);
                % Display rotated video frame on axis
                showFrameOnAxis(hAxes.axis2, rotatedImg);
            end

            % When video reaches the end of file, display "Start" on the
            % play button.
            if isDone(videoSrc)
               hObject.String = 'Start';
            end
       catch ME
           % Re-throw error message if it is not related to invalid handle
           if ~strcmp(ME.identifier, 'MATLAB:class:InvalidHandle')
               rethrow(ME);
           end
       end
    end

動画処理のアルゴリズム

この関数は、再生ボタンが有効になると呼び出されるメイン アルゴリズムを定義します。

    function [frame,rotatedImg,angle] = getAndProcessFrame(videoSrc,angle)

        % Read input video frame
        frame = step(videoSrc);

        % Pad and rotate input video frame
        paddedFrame = padarray(frame, [30 30], 0, 'both');
        rotatedImg  = imrotate(paddedFrame, angle, 'bilinear', 'crop');
        angle       = angle + 1;
    end

終了ボタンのコールバック

このコールバック関数は、System object を解放して Figure ウィンドウを閉じます。

    function exitCallback(~,~,videoSrc,hFig)

        % Close the video file
        release(videoSrc);
        % Close the figure window
        close(hFig);
    end
end