Main Content

Submuestrear o simplificar un ROI a mano alzada

En este ejemplo se muestra cómo submuestrear o reducir el número de puntos de un objeto de ROI.Freehand

Introducción

La función crea una región de interés (ROI) de aspecto suave, a mano alzada.drawfreehand Sin embargo, el borde del ROI está hecho realmente de puntos discretos distribuidos a lo largo del límite. Dos factores contribuyen a la fluidez de un ROI a mano alzada: 1) la densidad de puntos y 2) la propiedad del objeto ROI a mano alzada.Smoothing

Al dibujar de forma interactiva, el movimiento del ratón determina la densidad de los puntos. Para los IIN complejos grandes, el número de puntos utilizados puede ser bastante grande.

La propiedad controla el aspecto del límite.Smoothing De forma predeterminada, el objeto utiliza un kernel de suavizado gaussiano con un valor sigma de 1 y un tamaño de filtro de 5.Freehand Cambiar este valor solo cambia el aspecto del límite, no cambia la propiedad subyacente del objeto.Position

Densidad predeterminada de puntos

La reducción de la densidad de puntos puede ayudar a reducir el espacio necesario para almacenar los datos de ROI y también puede acelerar cualquier cálculo que dependa del número de estos puntos. Una forma de reducir la densidad de puntos es submuestrear los puntos, por ejemplo, seleccionar cada otro punto.

Cree un ROI a mano alzada de ejemplo convirtiendo una máscara en un ROI. El ROI es muy denso ya que cada píxel de límite corresponderá a un punto del ROI.

im = imread('football.jpg'); bw = im(:,:,1)>200; bw = bwareafilt(bw, 1); bloc = bwboundaries(bw,'noholes'); roipos = fliplr(bloc{1}); imshow(im); hfh = drawfreehand('Position', roipos); 

Para visualizar la densidad de los puntos, convierta cada punto del ROI en un waypoint.

hfh.Waypoints(:) = true;  title('Original density'); snapnow  % Zoom in. xlim([80 200]); ylim([70 160]); snapnow 

Submuestreo de los puntos de posición

Submuestrear los puntos que componen la propiedad del ROI a mano alzada.Position Dado que el ROI a mano alzada es muy denso. El submuestreo puede reducir sustancialmente el tamaño sin perder fidelidad. Consulte la posición inicial, completa y detallada.

fpos = hfh.Position; 

Submuestra, eligiendo cada otro punto.

cpos = fpos(1:2:end,:); 

Actualice la propiedad Position del ROI.

hfh.Position = cpos; 

Para ver la densidad, convierta todos los puntos en waypoints.

hfh.Waypoints(:) = true; title('Simple Subsample'); snapnow 

Submuestreo - Uso de la tasa de cambio

Un mejor enfoque para submuestrear los puntos sería comenzar selectivamente a eliminar puntos que tienen bajo.Curvatura Tiene más sentido eliminar un punto que está a lo largo de una parte relativamente recta del ROI en lugar de uno cerca de una curva. Un enfoque sencillo para definir un valor de curvatura es medir la velocidad del cambio en las ubicaciones de posición.

Mida la tasa de cambio. El vecino del primer punto es el último punto.

dfpos = diff([fpos(end,:); fpos]); 

Defina una medida ad hoc de curvatura basada en un filtro simple de paso bajo.

cm = sum(abs(conv2(dfpos, ones(3,2),'same')),2); 

Ordenar por curvatura.

[~, cmInds] = sort(cm); 

Designe 3/4 de los puntos con valores de curvatura más bajos para eliminar del ROI.

numPointsToCull = round(0.25*size(fpos,1)); 

Quita esas posiciones.

cpos = fpos; cpos(cmInds(1:numPointsToCull),:) = []; 

Actualice el ROI, activando todos los Waypoints para ver el impacto.

hfh.Position = cpos; hfh.Waypoints(:) = true; title('Curvature Based Subsample (factor of 4)'); snapnow 

Submuestreo - Uso del método en objetos de ROI a mano alzadareduce

Un enfoque aún mejor para submuestrear los puntos sería utilizar el método en el objeto de ROI.reduce El método funciona directamente en la propiedad del objeto ROI.reducePosition Puede afectar al número de puntos eliminados especificando un valor de tolerancia entre [0 1.0] como argumento de entrada opcional. El valor predeterminado de tolerancia es 0.01.

Restablezca la propiedad y llame al objeto ROI.Positionreduce

hfh.Position = fpos; reduce(hfh);  % View the updated ROI, turning all the points into waypoints to see the % impact. hfh.Waypoints(:) = true; title('Subsampling using reduce method'); snapnow 

Submuestreo interactivo

Otra forma de submuestrear es usar eventos para facilitar este proceso. En primer lugar, cree un agente de escucha para cambiar interactivamente el número de puntos que utiliza el ROI a mano alzada. Utilice la propiedad del objeto Freehand para almacenar en caché los datos de resolución completa, junto con el valor actual de tolerancia.UserDataPosition A continuación, agregue un menú contextual personalizado al objeto DE ROI creando un nuevo y parentiéndolo en el objeto Freehand.uimenuUIContextMenu Esta opción de menú le permite el ROI, que elimina la memoria caché temporal.Finalizar

Restaure el ROI original y almacene en caché la posición original junto con su medida de curvatura en UserData.

hfh.Waypoints(:) = true; hfh.UserData.fpos = fpos; hfh.UserData.tol = 0; 

Responda al desplazamiento del ratón.

h = gcf; h.WindowScrollWheelFcn = @(h, evt) changeSampleDensity(hfh, evt); 

Agregue un menú contextual para finalizar el ROI y realizar cualquier limpieza necesaria.

uimenu(hfh.UIContextMenu, 'Text','Finalize',...     'MenuSelectedFcn', @(varargin)finalize(hfh));  title('Scroll to change density interactively'); 

Animación del submuestreo interactivo

Función de devolución de llamada - Cambiar la densidad de la muestra basada en el desplazamiento del ratón

Esta función se llama en la acción de desplazamiento. Desplazarse hacia arriba aumenta la densidad y el desplazamiento hacia abajo la disminuye. Esto le permite seleccionar interactivamente el número de puntos que desea conservar.

function changeSampleDensity(hfh, evt) % Restore Position property of ROI. hfh.Position = hfh.UserData.fpos; % Change tolerance by a fixed amount based on the direction of the scroll. % This code changes the tolerance by 0.01 for every scroll increment. tol = hfh.UserData.tol + 0.01 * (evt.VerticalScrollCount); % Restrict the range of tolerance values to be from 0 to 0.15, which is the % useful range. tol = max(min(tol, 0.15), 0); % Call |reduce| with the specified tolerance. reduce(hfh,tol); hfh.UserData.tol = tol; % Update the ROI and turn all the points into waypoints to show the % density. hfh.Waypoints(:) = true; end 

Función de devolución de llamada - Finalizar el ROI a mano alzada

Elimine y cree un nuevo ROI a mano alzada con los puntos submuestreados para ahorrar espacio.

function finalize(hfh) h = ancestor(hfh, 'figure'); % Reset the mouse scroll wheel callback. h.WindowScrollWheelFcn = []; % Save finalized set of points. pos = hfh.Position; % Delete and create a new Freehand ROI with the new |Position| value. delete(hfh); drawfreehand(gca, 'Position', pos); end 

Consulte también

| | |

Temas relacionados