MATLAB Answers

Draggable resizable rectangle in the image to obtain live signal to noise ratio

34 views (last 30 days)
I am trying to design a draggable resizable reactangle in the image to display live signal to noise ratio (SNR). I can calculate the SNR for a specific cropped image but I want to let use drag the rectangle to any position of the image and obtain signal to noise ration of that selected rectangular region. However, I did not find any good source code to draw a draggable resizable rectangle that can obtain live position of the rectangle. I found crop_it2 function in Matlab file exchange but it asks user to close the figure first and then it will plot the cropped region. Instead, I want to keep the figure open and let user drag the rectangle with mouse and it will display SNR value of that rectangular region in the image. This is the source code I found here:
function [rect_pos] = Crop_it2(I)
% Crops the Image from a resizable & draggable rectangle
% & displays it (after the figure is closed)
% I is the Image to be cropped, assumed to be in the
% matlab workspace
% I = imread('liftingbody.png');
% [rect_pos] = Crop_it(I);
% RGB = imread('peppers.png');
% [rect_pos] = Crop_it(RGB);
% $author Shripad Kondra, SISSA, Trieste, Italy
% $acknowledgments Diana Bedolla (SISSA), Erion Hasanbelliu (UFL)
% $date 21-Aug-2008
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 1) get the screensize
Screen_size = get(0,'ScreenSize');
min_Screen_size = min(Screen_size(3:4));
% 2) imagine the screen as a aquare with this size
% 3) find the length of diagonal
diag_Screen_size = round(sqrt(2*min_Screen_size.^2));
% 3) Lets say you have to fit a figure which is half the screen size
scale_screen = diag_Screen_size/4;
d=sqrt(r.^2+c.^2); % find the size of the diagonal of the image
scale_fig = (scale_screen/d);
%% Figure resizing
% Don't use IMSHOW as it doesn't strecth the image in same proportion %
% as the figure when the figure is strecthed. %
figure, imshow(I); %colormap gray;
rect_pos_fig = get(gcf,'position');
rect_pos_fig(3) = round(c*scale_fig);
rect_pos_fig(4) = round(r*scale_fig);
% set the figure position so that it is proportional to the image
% set axis to fill the figure.
set(gca,'position',[0 0 1 1]);
%% Creating the rectangle
% create the rectangle
plotedit on
h1=annotation('rectangle',[0 0 0.4 0.4]);
% fancy stuff -> slower if image is gray or is too big
if(size(I,3)>1 && scale_fig>1)
% here is the key for resizable rectangle
% set the delete callback
% recover the value of the position of rectangle from root.
%% Callback subfunction
function myCallback(src,eventdata,I,h1)
rect_pos = get(h1,'position');
rect_pos = (floor(rect_pos.*[c r c r]))+1;
rect_pos(2) = r - (rect_pos(2) + rect_pos(4));
I2=imcrop(I,rect_pos); % uses imageprocessing toolbox
figure, imshow(I2); colormap gray; % remove this line if you don't want
set(gca,'position',[0 0 1 1]);
% save the position of rectangle in root.
% or put imwrite function to save the
% cropped image
% e.g.
% imwrite(I2,'temp','png');
% see imwrite
%% croping function
function I2 = myCrop(I,rect)
% copied from imcrop -> see IMCROP
m = size(I,1);
n = size(I,2);
pixelHeight = rect(4);
pixelWidth = rect(3);
r1 = round(rect(2) + 1 );
c1 = round(rect(1) + 1 );
r2 = round(rect(4) + r1);
c2 = round(rect(3) + c1);
% Check for selected rectangle completely outside the image
if ((r1 > m) || (r2 < 1) || (c1 > n) || (c2 < 1))
b = [];
r1 = max(r1, 1);
r2 = min(r2, m);
c1 = max(c1, 1);
c2 = min(c2, n);
I2 = I(r1:r2, c1:c2, :);


Sign in to comment.

Accepted Answer

Image Analyst
Image Analyst on 15 Dec 2020
Try this:
% Maximize the window.
g = gcf;
g.WindowState = 'maximized'
uiwait(msgbox('After you click OK, and when you see the crosshairs, drag out a rectangle'));
title('Double Click or type Enter when ready', 'FontSize', 20);
% roi = drawrectangle('Color','r')
% position = roi.Position;
roi = imrect();
position = wait(roi)
% Delete the draggable roi
% Create a new rectangle
rectangle('Position', position, 'EdgeColor', 'r', 'LineWidth', 2);
row1 = position(2)
row2 = row1 + position(4) - 1
col1 = position(1)
col2 = col1 + position(3) - 1
caption = sprintf('y Row 1 = %.1f, y Row 2 = %.1f, x Col 1 = %.1f, x Col 2 = %.1f', row1, row2, col1, col2);
title(caption, 'FontSize', 20);


Show 2 older comments
Muhammad Abir
Muhammad Abir on 16 Dec 2020
Yes, I would like to do it live. This is the requirement for my project. I am still struggling with this
Image Analyst
Image Analyst on 16 Dec 2020
You'd have to look into that listener capability. I've not done that before so I'd be fumbling around just like you'll have to. Good luck.
Muhammad Abir
Muhammad Abir on 16 Dec 2020
I think I found the solution. Thanks for you suggestion. Appreciate it.
I = imread('cameraman.tif');
% plot image 1 & draw a rectangular ROI on images
figure, imshow(I);
roi = drawrectangle('LineWidth',2,'Color','white');
% set up listeners for ROI moving events
addlistener(roi,'MovingROI',@(r1,evt) allevents(r1,evt));
% allevents callback function displays the previous position & the current position of the ROI
function allevents(r1,evt)
disp(['ROI moving current position: ' mat2str(evt.CurrentPosition)]);

Sign in to comment.

More Answers (1)

Image Analyst
Image Analyst on 15 Dec 2020
I'd just use drawrectangle() or imrect().


Muhammad Abir
Muhammad Abir on 15 Dec 2020
I tried to use imrect like this but I cannot be the postion of the rectangle. I just need the postion of the rectangle so I can calculate SNR
h = imrect(gca, [10 10 100 100]);
addNewPositionCallback(h,@(p) getPosition(h))

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!