Main Content

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

イメージ内の距離の測定

この例では、ライン ROI を使用してイメージ内の距離を測定する方法を説明します。測定値を実際値に対してキャリブレーションして、単位を指定することもできます。この例では、特定の描画モードに入ることなく、ROI をシームレスに追加、編集、および削除する方法を示します。

イメージのワークスペースへの読み取りとイメージの表示

イメージをワークスペースに読み取ります。

im = imread('concordorthophoto.png');

サイズなど、イメージに関するデータを収集し、コールバック関数に渡すことができる構造体にデータを格納します。

sz = size(im);
myData.Units = 'pixels';
myData.MaxValue = hypot(sz(1),sz(2));
myData.Colormap = hot;
myData.ScaleFactor = 1;

座標軸にイメージを表示します。

hIm = imshow(im);

イメージの ButtonDownFcn コールバックにコールバック関数を指定します。myData 構造体をコールバック関数に渡します。このコールバック関数は、ライン オブジェクトを作成して、ROI の描画を開始します。

hIm.ButtonDownFcn = @(~,~) startDrawing(hIm.Parent,myData);

ROI の描画を開始するコールバック関数の作成

ButtonDownFcn コールバックでライン ROI を作成するために使用する関数を作成します。この関数は次の操作を行います。

1.ライン ROI オブジェクトをインスタンス化する。

2.クリックと ROI の移動に応答するリスナーを設定する。

3.ROI に 'Delete All' オプションが含まれるカスタム コンテキスト メニューを追加する。

4.イメージ内で開始点としてクリックされたポイントを使用して、ROI の描画を開始する。

function startDrawing(hAx,myData)

% Create a line ROI object. Specify the initial color of the line and
% store the |myData| structure in the |UserData| property of the ROI.
h = images.roi.Line('Color',[0, 0, 0.5625],'UserData',myData);

% Set up a listener for movement of the line ROI. When the line ROI moves,
% the |updateLabel| callback updates the text in the line ROI label and
% changes the color of the line, based on its length.
addlistener(h,'MovingROI',@updateLabel);

% Set up a listener for clicks on the line ROI. When you click on the line
% ROI, the |updateUnits| callback opens a GUI that lets you specify the
% known distance in real-world units, such as, meters or feet.
addlistener(h,'ROIClicked',@updateUnits);

% Get the current mouse location from the |CurrentPoint| property of the
% axes and extract the _x_ and _y_ coordinates.
cp = hAx.CurrentPoint;
cp = [cp(1,1) cp(1,2)];

% Begin drawing the ROI from the current mouse location. Using the
% |beginDrawingFromPoint| method, you can draw multiple ROIs.
h.beginDrawingFromPoint(cp);

% Add a custom option to the line ROI context menu to delete all existing
% line ROIs.
c = h.UIContextMenu;
uimenu(c,'Label','Delete All','Callback',@deleteAll);

end

ROI のラベルと色を更新するコールバック関数の作成

ライン ROI が移動するたび、すなわち 'MovingROI' イベントの発生時に呼び出される関数を作成します。この関数は、ラインの長さで ROI のラベルを更新し、その長さに基づいてラインの色を変更します。

この関数は、ROI が移動するたびに呼び出されます。移動の終了時にのみ ROI を更新するには、代わりに 'ROIMoved' イベントをリッスンします。

function updateLabel(src,evt)

% Get the current line position.
pos = evt.Source.Position;

% Determine the length of the line.
diffPos = diff(pos);
mag = hypot(diffPos(1),diffPos(2));

% Choose a color from the colormap based on the length of the line. The
% line changes color as it gets longer or shorter.
color = src.UserData.Colormap(ceil(64*(mag/src.UserData.MaxValue)),:);

% Apply the scale factor to line length to calibrate the measurements.
mag = mag*src.UserData.ScaleFactor;

% Update the label.
set(src,'Label',[num2str(mag,'%30.1f') ' ' src.UserData.Units],'Color',color);

end

測定単位を更新するコールバック関数の作成

ROI のラベルをダブルクリックするたびに呼び出される関数を作成します。この関数は、実際の距離と単位に関する情報を入力できるポップアップ ダイアログ ボックスを開きます。

この関数は 'ROIClicked' イベントをリッスンし、イベント データを使用してクリックのタイプとクリックされた ROI の部分をチェックします。

ポップアップ ダイアログ ボックスでは、この測定値の既知の距離と単位を入力するように求められます。この情報を使用して、実際の単位に対してすべての ROI の測定値をキャリブレーションすることができます。

function updateUnits(src,evt)

% When you double-click the ROI label, the example opens a popup dialog box
% to get information about the actual distance. Use this information to
% scale all line ROI measurements.
if strcmp(evt.SelectionType,'double') && strcmp(evt.SelectedPart,'label')

    % Display the popup dialog box.
    answer = inputdlg({'Known distance','Distance units'},...
        'Specify known distance',[1 20],{'10','meters'});

    % Determine the scale factor based on the inputs.
    num = str2double(answer{1});

    % Get the length of the current line ROI.
    pos = src.Position;
    diffPos = diff(pos);
    mag = hypot(diffPos(1),diffPos(2));

    % Calculate the scale factor by dividing the known length value by the
    % current length, measured in pixels.
    scale = num/mag;

    % Store the scale factor and the units information in the |myData|
    % structure.
    myData.Units = answer{2};
    myData.MaxValue = src.UserData.MaxValue;
    myData.Colormap = src.UserData.Colormap;
    myData.ScaleFactor = scale;

    % Reset the data stored in the |UserData| property of all existing line
    % ROI objects. Use |findobj| to find all line ROI objects in the axes.
    hAx = src.Parent;
    hROIs = findobj(hAx,'Type','images.roi.Line');
    set(hROIs,'UserData',myData);

    % Update the label in each line ROI object, based on the information
    % collected in the input dialog.
    for i = 1:numel(hROIs)

        pos = hROIs(i).Position;
        diffPos = diff(pos);
        mag = hypot(diffPos(1),diffPos(2));

        set(hROIs(i),'Label',[num2str(mag*scale,'%30.1f') ' ' answer{2}]);

    end

    % Reset the |ButtonDownFcn| callback function with the current |myData|
    % value.
    hIm = findobj(hAx,'Type','image');
    hIm.ButtonDownFcn = @(~,~) startDrawing(hAx,myData);

end

end

すべての ROI を削除するコールバック関数の作成

すべての ROI を削除する関数を作成します。コールバック関数 startDrawing で各ライン ROI にカスタム コンテキスト メニュー項目を追加しています。これは、そのカスタム コンテキスト メニューに関連付けられたコールバックです。このコールバックは、関数 findobj を使用して ROI タイプを検索し、見つかった ROI を削除します。

function deleteAll(src,~)

hFig = ancestor(src,'figure');
hROIs = findobj(hFig,'Type','images.roi.Line');
delete(hROIs)

end

参考

| | |

関連するトピック