2012-09-13 7 views
6

Ho una GUI con due assi. I primi assi hanno un'immagine a bassa risoluzione.Matlab: tracciatura in tempo reale della ROI selezionata con IMRECT

Quello che mi piacerebbe fare è selezionare un'area sui primi assi usando IMRECT e quindi visualizzare quell'area come immagine ad alta risoluzione sul secondo asse, aggiornando continuamente mentre sposto il rettangolo IMRECT in giro.

L'unico modo in cui sono stato in grado di farlo è con un "ciclo for" con una pausa di 0,1 che funziona solo per un minuto o due mentre seleziono e cambio la ROI con IMRECT, molto ingombrante.

Il mio pensiero era di usare una funzione che veniva eseguita ogni volta che il mouse si muoveva all'interno dei primi assi, con i comandi ploting e getPosition in quella funzione. Tuttavia, non sono sicuro di come scrivere una tale funzione (attivazione del movimento del mouse all'interno di un asse).

Qualsiasi aiuto sarebbe molto apprezzato!

+1

Verificate anche: http://stackoverflow.com/questions/10998739/scalabile-trascinabile-box-on-plot-che-può-selezionare-dati/10998803 # 10998803 –

risposta

4

In generale, è necessario assegnare una richiamata al numero imrect. Ad esempio:

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

Il callback deve ottenere parametri aggiuntivi, come l'immagine e il secondo asse, utilizzando funzioni anonime.


Ho scritto un piccolo snippet di codice che fa ciò che vuoi. Dovresti aggiungere controlli al contorno, dal momento che non mi sono preoccupato. Aggiorna CData invece di eseguire imshow quando si sposta il rettangolo, quindi è abbastanza uniforme.

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

Grazie, Andrey. L'ho fatto funzionare perfettamente. Era in difficoltà da un po 'di tempo, era esattamente quello che stavo cercando. Una riga di codice precedente che avevo per vincolare il rettangolo imrect all'interno della dimensione dell'immagine non funziona più ora. Avete una soluzione rapida per vincolare la selezione imrect all'interno degli assi? Grazie mille! – user1668909

+0

@ user1668909, consulta http://stackoverflow.com/questions/10998739/scaleable-dragable-box-on-plots-that-can-select-data/10998803#10998803. Soprattutto la funzione 'makeConstraint' –

1

funzionalità Simillar come @ risposta di Andrey, con tre differenze:

  • impostazione axis limiti invece di 'CData'
  • Il fattore di ingrandimento (che può essere più veloce?) è variabile e dipende dalla dimensione del rettangolo, a causa del 'fit''IniitalMagnification'.
  • Aggiunto ConstraintFcn

sarebbe:

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 

che potrebbe essere chiamato come:

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

Penso che questa sia la migliore risposta qui. –