Main Content

Medir distancias en una imagen

Este ejemplo muestra cómo utilizar los ROI de línea para medir las distancias en una imagen. También puede calibrar las mediciones a valores del mundo real y especificar las unidades. En el ejemplo se muestra cómo agregar, editar y eliminar ROI sin problemas sin necesidad de entrar en ningún modo de dibujo específico.

Leer imagen en el espacio de trabajo y mostrar imagen

Lea la imagen en el espacio de trabajo.

im = imread('concordorthophoto.png'); 

Recopile datos sobre la imagen, como su tamaño, y almacene los datos en una estructura que puede pasar a las funciones de devolución de llamada.

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

Muestre la imagen en un eje.

hIm = imshow(im); 

Especifique una función de devolución de llamada para la devolución de llamada en la imagen.ButtonDownFcn Pase la estructura a la función de devolución de llamada.myData Esta función de devolución de llamada crea los objetos de línea y comienza a dibujar los ROI.

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

Crear función de devolución de llamada para empezar a dibujar ROIs

Cree la función utilizada con la devolución de llamada para crear ROI de línea.ButtonDownFcn Esta función:

1. Crea una instancia de un objeto de ROI de línea.

2. Configura a los oyentes para que reaccionen a los clics y al movimiento del ROI.

3. Agrega un menú contextual personalizado a los ROI que incluye una opción 'Eliminar todo'.

4. Comienza a dibujar el ROI, utilizando el punto en el que se hace clic en la imagen como punto de partida.

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 

Crear función de devolución de llamada para actualizar la etiqueta y el color del ROI

Cree la función a la que se llama siempre que se mueva el ROI de línea, es decir, cuando se produzca el evento.'MovingROI' Esta función actualiza la etiqueta de ROI con la longitud de la línea y cambia el color de la línea en función de su longitud.

Esta función se llama repetidamente cuando se mueve el ROI. Si desea actualizar el ROI solo cuando el movimiento haya terminado, escuche el evento en su lugar.'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 

Crear función de devolución de llamada para actualizar las unidades de medida

Cree la función a la que se llama cada vez que haga doble clic en la etiqueta de ROI. Esta función abre un cuadro de diálogo emergente en el que puede introducir información sobre la distancia del mundo real y las unidades.

Esta función escucha el evento, utilizando datos de eventos para comprobar el tipo de clic y la parte del ROI en la que se hizo clic.'ROIClicked'

El cuadro de diálogo emergente le pide que introduzca la distancia y las unidades conocidas para esta medición. Con esta información, puede calibrar todas las mediciones de ROI a unidades del mundo real.

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 

Crear función de devolución de llamada para eliminar todos los ROI

Cree la función para eliminar todos los ROI. Ha agregado un elemento de menú contextual personalizado a cada ROI de línea en la función de devolución de llamada.startDrawing Esta es la devolución de llamada asociada a ese menú contextual personalizado. Esta devolución de llamada utiliza la función para buscar el tipo de ROI y elimina los ROI encontrados.findobj

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

Consulte también

| | |

Temas relacionados