2012-09-13 17 views
6

Tengo una GUI con dos ejes. Los primeros ejes tienen una imagen de baja resolución.Matlab: trazado en tiempo real del ROI seleccionado con IMRECT

Lo que me gustaría hacer es seleccionar un área en los primeros ejes usando IMRECT y luego mostrar esa área como una imagen de alta resolución en los segundos ejes, mientras actualizo continuamente mientras muevo el rectángulo IMPACT.

La única forma en que he podido hacer esto es con un "bucle forzado" con una pausa de 0.1 que solo se ejecuta durante uno o dos minutos mientras selecciono y cambio el retorno de la inversión con IMPACT, muy engorroso.

Mi idea era usar una función que se ejecutara cada vez que el mouse se movía dentro de los primeros ejes, con los comandos ploting y getPosition en esa función. Sin embargo, no estoy seguro de cómo escribir esa función (desencadenando el movimiento del mouse dentro de un eje).

¡Cualquier ayuda sería muy apreciada!

+1

También puedes ver: http://stackoverflow.com/questions/10998739/scaleable-dragable-box-on-plots-that-can-select-data/10998803 # 10998803 –

Respuesta

4

En general, debe asignar una devolución de llamada a su imrect. Por ejemplo:

x = imrect(); 
x.addNewPositionCallback(@(x)(disp('The rect has changed'))) 

La devolución de llamada debe recibir parámetros adicionales, tales como la imagen y el segundo ejes mediante la utilización de funciones anónimas.


Escribí un pequeño fragmento de código que hace lo que quiere. Debería agregar controles de límites, ya que no me molesté. Actualiza CData en lugar de ejecutar imshow cuando mueve el rectángulo, por lo que es bastante suave.

GUI

function Zoomer 
    figure(); 

    highResImage = imread('peppers.png'); 
    lowResImage = imresize(highResImage,0.5); 

    a1 = subplot(2,1,1); 
    a2 = subplot(2,1,2); 

    imshow(lowResImage,'Parent',a1); 
    initialPosition = [10 10 100 100]; 
    lowResRect = imrect(a1,initialPosition); 

    lowResRect.addNewPositionCallback(@(pos)Callback(pos,a2,highResImage)); 

    Callback(initialPosition , a2, highResImage); 
end 

function Callback(position,axesHandle, highResImage) 
    position = position * 2; 
    x1 = position(1); 
    y1 = position(2); 
    x2 = position(1) + position(3); 
    y2 = position(2) + position(4); 

    highResThumbnail = highResImage(round(y1:y2),round(x1:x2),:); 

    if isempty(get(axesHandle,'Children')) 
     imshow(highResThumbnail,'Parent',axesHandle); 
    else 
     imHandle = get(axesHandle,'Children'); 
     oldSize = size(get(imHandle,'CData')); 
     if ~isequal(oldSize, size(highResThumbnail)) 
      imshow(highResThumbnail,'Parent',axesHandle); 
     else 
      set(imHandle,'CData', highResThumbnail); 
     end  
    end 
end 
+0

Gracias, Andrey. Lo conseguí para que funcione a la perfección. Estaba luchando por un tiempo anteriormente, eso era exactamente lo que estaba buscando. Una línea de código anterior que tenía para restringir el rectángulo imrect dentro del tamaño de la imagen ya no funciona. ¿Tiene una solución rápida para restringir la selección directa dentro de los ejes? ¡Muchas gracias! – user1668909

+0

@ user1668909, consulte http://stackoverflow.com/questions/10998739/scaleable-dragable-box-on-plots-that-can-select-data/10998803#10998803. Especialmente la función 'makeConstraint' –

1

funcionalidad simillar como @ respuesta de Andrei, con tres diferencias:

  • ajuste de axis límites en lugar de 'CData'
  • El factor ampliación (que puede ser más rápido?) es variable y depende del tamaño del rectángulo, debido a 'fit''IniitalMagnification'.
  • Agregado ConstraintFcn

sería:

function imZ = Zoom(im, s) 

f = figure; 
a1 = subplot(1,2,1); 
imshow(im,'InitialMagnification', 'fit'); 
a2 = subplot(1,2,2); 
imshow(im,'InitialMagnification', 'fit'); 

Ipos = [0 0 s]; 
rect = imrect(a1,Ipos); 
rect.setPositionConstraintFcn(@(p) Const(p,size(im))); 
rect.addNewPositionCallback(@(p) CB(p,a2)); 
CB(Ipos,a2); 

if nargout > 0 
    uiwait(f); 
    imZ = im(pm(2):pm(2)+pm(4),pm(1):pm(1)+pm(3),:); 
end 

    function p = Const(p,imS) 
     p(1:2) = max(1,p(1:2)); 
     p(1:2) = min(imS([2 1])-p(3:4),p(1:2)); 
    end 

    function CB(p,a) 
     pm = round(p); 
     axes(a);  
     axis([pm(1),pm(1)+pm(3),pm(2),pm(2)+pm(4)]); 
    end 
end 

que podría denominarse como:

Zoom(imread('peppers.png'),[100 100]); 
+0

Creo que esta es la mejor respuesta aquí. –

Cuestiones relacionadas