Pedro Pereira
Pedro Pereira

Reputation: 47

Select a ROI (circle and square) in matlab in order to aply a filter

I am working on matlab and I want to do an interactive selection like you do when you use the function roipoly, but I want to select or a circle or a square. I already search for funcion to select a region of interest (ROI) like you select when you use roipoly but using a circle or a square but I can't find anything.

Any tips?

I already tried using the ginput.

[X, Y]= ginput(2)

xmin=min(X)
xmax=max(X)
ymin=min(Y)
ymax=max(Y)

In this code I define the corner of the square (the user defines the two points with the ginput). But when I check the points of the image, they are wrong. I think is because of the size of the figure that is not the same on the plot.

The best way to select the ROI that I want is to using a function similar with the roipoly, but for a circle and for a square, instead of a polygon. And with this type of function I have only can select points inside of the picture with the "ginput" I have to type a error message if the user select any point outside of the figure (the problem is that they don't match, the point that I can select is greater then the size of the image).

Upvotes: 4

Views: 10445

Answers (2)

Alon
Alon

Reputation: 11

I managed to implement an interactive area selection (in my case a circle) using the following technique:

  1. Get the first point using the built-in ginput(1):

    [X1, Y1] = ginput(1);
    xp = [X1 Y1];
    
  2. Generate a handle for the circle:

    h = plot(X1, Y1, 'r');
    
  3. Set a custom MouseMove event handler to select the second point:

    set(gcf, 'WindowButtonMotionFcn', {@mousemove, h, xp});
    
  4. Wait for the user to click while the handler works its magic:

    k = waitforbuttonpress;
    
  5. Finally disable the handler:

    set(gcf, 'WindowButtonMotionFcn', '');
    

The event handler goes as follows:

function mousemove(object, eventdata, h, xp)
cp = get(gca, 'CurrentPoint');
r = norm([cp(1,1) - bp(1) cp(1,2) - bp(2)]);
theta = 0:.1:2*pi;
xc = r*cos(theta)+bp(1);
yc = r*sin(theta)+bp(2);
set(h, 'XData', xc);
set(h, 'YData', yc);
end

Et voila. This works nicely, and r is visible to the calling function so you can make use of it.

Upvotes: 1

Pete
Pete

Reputation: 2344

There are really two questions here:

1) What is wrong with your GINPUT code and 2) How to write roiCircle or roiSquare

In answer to (1), nothing is wrong; that code behaves as it should:

imgData = randn(100);
imagesc(imgData );
[X, Y]= ginput(2)

xmin=min(X);
xmax=max(X);
ymin=min(Y);
ymax=max(Y);

squareX = [xmin xmin xmax xmax xmin];
squareY = [ymin ymax ymax ymin ymin];
hold on; 
plot(squareX,squareY); %plot the correct square
hold off;

You can use IMCROP to get the data:

width = xmax - xmin;
height = ymax - ymin;
imgSelect = imcrop(imgData,[xmin,ymin,width,height]);
figure; imagesc(imgSelect);

As far as (2) (writing roiCircle or roiSquare), so that they update nicely like roiPoly does, those will require a significant (though not insurmountable) amount of MATLAB GUI programming. It's tractable, but not trivial.

Upvotes: 2

Related Questions