Matlab: real-time ROI display selected using IMRECT

I have a two-axis GUI. The first axes have a low resolution image.

What I would like to do is select the area on the first axes using IMRECT, and then display this area as a high resolution image on the second axes, while constantly updating as I move the IMRECT rectangle.

The only way I was able to do this is with a β€œloop cycle” with 0.1 pause in it, which only starts for a minute or two when I select and change the ROI using IMRECT, which is very cumbersome.

My thought was to use a function that runs whenever the mouse moves within the first axes, with the ploting and getPosition commands in this function. However, I'm not sure how to write such a function (triggering mouse movement inside the axes).

Any help would be greatly appreciated!

+6
source share
2 answers

Generally, you should assign a callback to your imrect . For instance:

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

The callback must receive additional parameters, such as the image and other axes, using anonymous functions.


I wrote a small piece of code that does what you want. You should add border checks as I was not worried. It updates CData instead of launching imshow when moving the rectangle, so it is pretty smooth.

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 
+4
source

Similar functionality as @Andrey's answer with three differences:

  • Setting axis limits instead of 'CData' (what could be faster?)
  • The zoom factor is variable and depends on the size of the rectangle, due to the 'fit' 'IniitalMagnification' .
  • Added by ConstraintFcn

:

 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 

which could be called:

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

Source: https://habr.com/ru/post/925326/


All Articles