Main Content

Crear herramienta de edición de ROI a mano alzada

En este ejemplo se muestra cómo crear una herramienta sencilla para editar la forma de un ROI a mano alzada utilizando otro objeto de ROI. De forma predeterminada, los objetos de ROI a mano alzada, , ya incluyen asequibilidades, llamados waypoints, para editar interactivamente su forma.images.roi.Freehand Al hacer clic y arrastrar cualquiera de estos waypoints en el borde del ROI, puede ajustar el borde del ROI. También puede agregar waypoints de forma interactiva a cualquier parte del límite.

Otra forma de editar la forma de los ROI a mano alzada, que ofrecen muchos programas populares de manipulación de imágenes, es una herramienta de 'borrador' o 'cepillo'. En este ejemplo se implementa una de estas herramientas, utilizando otro objeto de ROI para editar el ROI a mano alzada.

Crear un ROI a mano alzada

Cree un ROI a mano alzada que siga la forma de una máscara de segmentación. Para obtener más información sobre este proceso, consulte .Utilice LOS ROI a mano alzada para refinar las máscaras de segmentación

Lea los datos de RMN en el área de trabajo.

im = dicomread('knee1.dcm'); 

Segmente la imagen de RMN y seleccione las dos regiones más grandes de la imagen de máscara.

segmentedLabels = imsegkmeans(im,3); boneMask = segmentedLabels==2; boneMask = bwareafilt(boneMask, 1); 

Obtenga las coordenadas de los límites de las dos regiones segmentadas.

blocations = bwboundaries(boneMask,'noholes'); 

Muestre la imagen.

figure hImage = imshow(im, []); 

Convierta las ubicaciones devueltas por orden x,y.bwboundaries

pos = blocations{1}; pos = fliplr(pos); 

Cree un ROI a mano alzada dentro de la máscara segmentada.

hf = drawfreehand('Position', pos); 

Crear la herramienta de edición de ROI a mano alzada

Cree un ROI de círculo que se utilizará como herramienta de edición de ROI de borrador o pincel. (Puede utilizar cualquiera de las clases haciendo un pequeño cambio, que se menciona a continuación).images.roi.*

he = images.roi.Circle(...     'Center', [50 50],...     'Radius', 10,...     'Parent', gca,...     'Color','r'); 

Asocie dos detectores de eventos con el ROI de Circle. Uno escucha el movimiento de ROI y el otro escucha cuando el movimiento se detiene. La función de devolución de llamada móvil ROI , el ejemplo se asegura de que su posición se ajuste a las ubicaciones de píxeles y también para cambiar el color (rojo/verde) para indicar si la operación de edición se eliminará o agregará al ROI a mano alzada de destino. Una vez que el ROI del editor deje de moverse, crearemos las máscaras binarias correspondientes para el ROI del editor y el ROI a mano alzada objetivo y haremos la edición requerida. Por último, transformaremos la máscara actualizada en un objeto de ROI a mano alzada. Conectar un oyente para reaccionar cada vez que se mueve este ROI editor

addlistener(he,'MovingROI', @(varargin)editorROIMoving(he, hf)); addlistener(he,'ROIMoved', @(varargin)editFreehand(hf, he)); 

Edite interactivamente el ROI a mano alzada

Esta animación muestra la operación de edición de agregar y quitar.

Esta es la función de devolución de llamada móvil roide. Esta función garantiza que el ROI del editor se ajuste a la cuadrícula de píxeles y cambia el color del ROI del editor para indicar si se añadirá al ROI a mano alzada o a eliminar una región del ROI a mano alzada. Si el centro del ROI del editor está fuera del ROI a mano alzada objetivo, elimina la operación, de lo contrario se 'añadirá'.

function editorROIMoving(he, hf) % Snap editor ROI to grid he.Position = round(he.Position);  % Check if the circle ROI's center is inside or outside the freehand ROI. center = he.Center; isAdd = hf.inROI(center(1), center(2)); if isAdd     % Green if inside (since we will add to the freehand).     he.Color = 'g'; else     % Red otherwise.     he.Color = 'r'; end end 

Esta es la devolución de llamada de ROI de edición a mano alzada que agrega o elimina la región del ROI del editor que interseca el ROI a mano alzada objetivo.

function editFreehand(hf, he)  % Create a mask for the target freehand. tmask = hf.createMask(); [m, n,~] = size(tmask); % Include the boundary pixel locations boundaryInd = sub2ind([m,n], hf.Position(:,2), hf.Position(:,1)); tmask(boundaryInd) = true;  % Create a mask from the editor ROI emask = he.createMask(); boundaryInd = sub2ind([m,n], he.Position(:,2), he.Position(:,1)); emask(boundaryInd) = true;  % Check if center of the editor ROI is inside the target freehand. If you % use a different editor ROI, ensure to update center computation. center = he.Center; % isAdd = hf.inROI(center(1), center(2)); if isAdd     % Add the editor mask to the freehand mask     newMask = tmask|emask; else     % Delete out the part of the freehand which intersects the editor     newMask = tmask&~emask; end  % Update the freehand ROI perimPos = bwboundaries(newMask, 'noholes'); hf.Position = [perimPos{1}(:,2), perimPos{1}(:,1)];  end 

Consulte también

| | | | | | | | |

Temas relacionados