exponenta event banner

Измерение расстояний в изображении

В этом примере показано, как использовать 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, включающее параметр «Удалить все».

4. Начинает рисование окупаемости инвестиций, используя в качестве начальной точки точку, выбранную на изображении.

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 color map 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.

Во всплывающем диалоговом окне предлагается ввести известное расстояние и единицы измерения для данного измерения. С помощью этой информации можно откалибровать все измерения окупаемости инвестиций в реальные единицы измерения.

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. Вы добавили пользовательский пункт контекстного меню к каждой строке ROI в startDrawing функция обратного вызова. Это обратный вызов, связанный с этим пользовательским контекстным меню. Этот обратный вызов использует findobj функция для поиска типа ROI и удаления всех найденных ROI.

function deleteAll(src,~)

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

end

См. также

| | |

Связанные темы