I have a code where I read in two images and display it side-by-side. I draw a region of interest within the first image, and the region is automatically shown on the second image. When I move the rectangle to another region within the first image, only that rectangle moves (not the second image's rectangle). How can I fix this so that when I move the first rectangle, the second move moves to the same position as well.
What I have now
% Read images
I = imread('cameraman.tif');
I2 = imread('cameraman.tif');
% plot image 1 & draw a rectangular ROI on images
subplot(1,2,1); imshow(I);
roi = drawrectangle('LineWidth',2,'Color','white');
subplot(1,2,2); imshow(I2);
roi2 = drawrectangle(gca,'Position',roi.Position);
% set up listeners for ROI moving events
addlistener(roi,'MovingROI',@allevents);
addlistener(roi,'ROIMoved',@allevents);
% allevents callback function displays the previous position & the current position of the ROI
function allevents(~,evt)
evname = evt.EventName;
switch(evname)
case{'MovingROI'}
disp(['ROI moving previous position: ' mat2str(evt.PreviousPosition)]);
disp(['ROI moving current position: ' mat2str(evt.CurrentPosition)]);
case{'ROIMoved'}
disp(['ROI moved previous position: ' mat2str(evt.PreviousPosition)]);
disp(['ROI moved current position: ' mat2str(evt.CurrentPosition)]);
end
end

 Akzeptierte Antwort

Ameer Hamza
Ameer Hamza am 11 Nov. 2020
Bearbeitet: Ameer Hamza am 11 Nov. 2020

2 Stimmen

Currently, your event lister function is just priting the values. You need to set the position too. Try following code
% Read images
I = imread('cameraman.tif');
I2 = imread('cameraman.tif');
% plot image 1 & draw a rectangular ROI on images
subplot(1,2,1); imshow(I);
roi = drawrectangle('LineWidth',2,'Color','white');
subplot(1,2,2); imshow(I2);
roi2 = drawrectangle(gca,'Position',roi.Position);
% set up listeners for ROI moving events
addlistener(roi,'MovingROI',@(r1,evt) allevents(r1,evt,roi2));
addlistener(roi,'ROIMoved',@(r1,evt) allevents(r1,evt,roi2));
% allevents callback function displays the previous position & the current position of the ROI
function allevents(roi1,evt,roi2)
evname = evt.EventName;
roi2.Position = roi1.Position;
switch(evname)
case{'MovingROI'}
disp(['ROI moving previous position: ' mat2str(evt.PreviousPosition)]);
disp(['ROI moving current position: ' mat2str(evt.CurrentPosition)]);
case{'ROIMoved'}
disp(['ROI moved previous position: ' mat2str(evt.PreviousPosition)]);
disp(['ROI moved current position: ' mat2str(evt.CurrentPosition)]);
end
end
Or a simpler solution using linkprop()
% Read images
I = imread('cameraman.tif');
I2 = imread('cameraman.tif');
% plot image 1 & draw a rectangular ROI on images
subplot(1,2,1); imshow(I);
roi = drawrectangle('LineWidth',2,'Color','white');
subplot(1,2,2); imshow(I2);
roi2 = drawrectangle(gca,'Position',roi.Position);
linkprop([roi, roi2], 'Position')

15 Kommentare

This is perfect! Thank you! Although both solutions work, I chose the second one because it is simpler!
Ameer Hamza
Ameer Hamza am 11 Nov. 2020
I am glad to be of help! :)
I guess 2nd solution will also be more efficient.
Another modification: what if I want two window for the two images but still link areas across?
Something like this
% Read images
I = imread('cameraman.tif');
I2 = imread('cameraman.tif');
% plot image 1 & draw a rectangular ROI on images
subplot(1,2,1); imshow(I);
roi11 = drawrectangle('LineWidth',2,'Color','white');
roi12 = drawrectangle('LineWidth',2,'Color','white');
subplot(1,2,2); imshow(I2);
roi21 = drawrectangle(gca,'Position',roi11.Position);
roi22 = drawrectangle(gca,'Position',roi12.Position);
hl1 = linkprop([roi11, roi21], 'Position')
hl2 = linkprop([roi12, roi22], 'Position')
As in separate window figures instead of subplot. I tried using the following code, but once I move the rectangle, it does not move in the other two figures.
% Read images
I = imread('cameraman.tif');
I2 = imread('cameraman.tif');
I3 = imread('cameraman.tif');
% plot image 1 & draw a rectangular ROI on images
% subplot(1,3,1); imshow(I);
figure, imshow(I);
roi = drawrectangle('LineWidth',2,'Color','white');
% subplot(1,3,2); imshow(I2);
figure, imshow(I2);
roi2 = drawrectangle(gca,'Position',roi.Position);
% subplot(1,3,3); imshow(I3);
figure, imshow(I3);
roi3 = drawrectangle(gca,'Position',roi.Position);
linkprop([roi, roi2, roi3], 'Position')
Ameer Hamza
Ameer Hamza am 11 Nov. 2020
This code works fine in R2020b. All rectanges move simultaneously. There might be some issue related to R2019b.
Thank you so much!!! Since I am using the MATLAB Online, it is probably not showing up correctly. Thank you for answering my questions!
Ameer Hamza
Ameer Hamza am 12 Nov. 2020
How are you using MATLAB R2019b in MATLAB online? I tried this code in MATLAB online too and it works fine.
I got it to work! Thank you!
Can matlab zoom into my region of interest rather than showing the entire image for all images on one separate window (2 subplots)?
For example, I have this for now. But when I change the position of the rectangle, the subplots do not change.
% read three images
I = imread('cameraman.tif');
I2 = imread('cameraman.tif');
% show first image & draw a rectangular ROI on image
figure, imshow(I);
title('cameraman.tif', 'FontSize', 9);
roi = drawrectangle('LineWidth',2,'Color','white');
% zoom in on those ROIs for each picture
I_roi = I(roi.Position(2):(roi.Position(2)+roi.Position(4)),roi.Position(1):(roi.Position(1)+roi.Position(3)),:); % store roi in matrix
I2_roi = I2(roi.Position(2):(roi.Position(2)+roi.Position(4)),roi.Position(1):(roi.Position(1)+roi.Position(3)),:);
% show the images as a subplot
figure;
subplot(1,2,1); imshow(I_roi);
subplot(1,2,2); imshow(I2_roi);
% link rectangular ROIs across the images
linkprop(roi, 'Position');
You need to use event listeners for this
% read three images
I = imread('cameraman.tif');
I2 = imread('cameraman.tif');
% show first image & draw a rectangular ROI on image
figure, imshow(I);
title('cameraman.tif', 'FontSize', 9);
roi = drawrectangle('LineWidth',2,'Color','white');
% zoom in on those ROIs for each picture
I_roi = imcrop(I, roi.Position); % store roi in matrix
I2_roi = imcrop(I, roi.Position);
% show the images as a subplot
figure;
ax1 = subplot(1,2,1); imshow(I_roi);
ax2 = subplot(1,2,2); imshow(I2_roi);
% set up listeners for ROI moving events
addlistener(roi,'MovingROI',@(r1,evt) allevents(r1,evt,I,ax1,ax2));
addlistener(roi,'ROIMoved',@(r1,evt) allevents(r1,evt,I,ax1,ax2));
% allevents callback function displays the previous position & the current position of the ROI
function allevents(roi,evt,I,ax1,ax2)
rect = roi.Position;
im_ = imcrop(I, rect);
imshow(im_, 'Parent', ax1)
imshow(im_, 'Parent', ax2)
end
I'm really sorry for asking so many questions! I'm still learning MATLAB. I'm trying to use this code to look at specific areas of Whole Slide Images. When I move the ROI rectangle, the first image (zoomed in version) replaces the second subplot and the third subplot. Is there a way to fix this?
For example the three regions are
When I move the region, it becomes this
% select three tif files that corresponds to the same case
[file1,path1] = uigetfile('*.tif');
[file2,path2] = uigetfile('*.tif');
[file3,path3] = uigetfile('*.tif');
if isequal(file1,0) || isequal(file2,0) || isequal(file3,0)
disp('User selected Cancel');
else
% read three images
I = imread(fullfile(path1,file1));
I2 = imread(fullfile(path2,file2));
I3 = imread(fullfile(path3,file3));
% show first image & draw a rectangular ROI on image
figure, imshow(I);
% title('cameraman.tif', 'FontSize', 9);
roi = drawrectangle('LineWidth',2,'Color','white');
% zoom in on those ROIs for each picture
I_roi = imcrop(I, roi.Position); % store roi in matrix
I2_roi = imcrop(I2, roi.Position);
I3_roi = imcrop(I3, roi.Position);
% show the images as a subplot
figure;
ax1 = subplot(1,3,1); imshow(I_roi);
ax2 = subplot(1,3,2); imshow(I2_roi);
ax3 = subplot(1,3,3); imshow(I3_roi);
% set up listeners for ROI moving events
addlistener(roi,'MovingROI',@(r1,evt) allevents(r1,evt,I,ax1,ax2,ax3));
addlistener(roi,'ROIMoved',@(r1,evt) allevents(r1,evt,I,ax1,ax2,ax3));
end
% allevents callback function displays the previous position & the current position of the ROI
function allevents(roi,~,I,ax1,ax2,ax3)
rect = roi.Position;
im_ = imcrop(I, rect);
imshow(im_, 'Parent', ax1)
imshow(im_, 'Parent', ax2)
imshow(im_, 'Parent', ax3)
end
You need to pass all three images to the event function
function allevents(roi,~,I,I2,I3,ax1,ax2,ax3)
rect = roi.Position;
imshow(imcrop(I, rect), 'Parent', ax1)
imshow(imcrop(I2, rect), 'Parent', ax2)
imshow(imcrop(I3, rect), 'Parent', ax3)
end
and change event listener line to
% set up listeners for ROI moving events
addlistener(roi,'MovingROI',@(r1,evt) allevents(r1,evt,I,I2,I3,ax1,ax2,ax3));
addlistener(roi,'ROIMoved',@(r1,evt) allevents(r1,evt,I,I2,I3,ax1,ax2,ax3));
Thank you! That works!
I added titles to each subplot. However, when I move the ROIs to another area, the title disappears.
Is there a way to keep the title on top of the image at all times?
% select three tif files that corresponds to the same case
[file1,path1] = uigetfile('*.tif');
[file2,path2] = uigetfile('*.tif');
[file3,path3] = uigetfile('*.tif');
if isequal(file1,0) || isequal(file2,0) || isequal(file3,0)
disp('User selected Cancel');
else
% read three images
I = imread(fullfile(path1,file1));
I2 = imread(fullfile(path2,file2));
I3 = imread(fullfile(path3,file3));
% show first image & draw a rectangular ROI on image
figure, imshow(I); title(file1,'Interpreter','none');
roi = drawrectangle('LineWidth',1,'Color','white');
% zoom in on those ROIs for each picture
I_roi = imcrop(I, roi.Position); % store roi in matrix
I2_roi = imcrop(I2, roi.Position);
I3_roi = imcrop(I3, roi.Position);
% show the images as a subplot
fig = figure;
pos_fig = [0 0 1920 1080];
set(fig, 'Position', pos_fig)
ax1 = subplot(1,3,1); imshow(I_roi); th1 = title(file1, 'FontSize', 7, 'Interpreter','none');
ax2 = subplot(1,3,2); imshow(I2_roi); th2 = title(file2, 'FontSize', 7, 'Interpreter','none');
ax3 = subplot(1,3,3); imshow(I3_roi); th3 = title(file3, 'FontSize', 7, 'Interpreter','none');
% set up listeners for ROI moving events
addlistener(roi,'MovingROI',@(r1,evt) allevents(r1,evt,I,I2,I3,ax1,ax2,ax3));
addlistener(roi,'ROIMoved',@(r1,evt) allevents(r1,evt,I,I2,I3,ax1,ax2,ax3));
end
% allevents callback function displays the previous position & the current position of the ROI
function allevents(roi,~,I,I2,I3,ax1,ax2,ax3)
rect = roi.Position;
imshow(imcrop(I, rect), 'Parent', ax1)
imshow(imcrop(I2, rect), 'Parent', ax2)
imshow(imcrop(I3, rect), 'Parent', ax3)
end
Try this definition of event callback function
function allevents(roi,~,I,I2,I3,ax1,ax2,ax3)
rect = roi.Position;
ax1.Children.CData = imcrop(I, rect); axis(ax1, 'auto');
ax2.Children.CData = imcrop(I2, rect); axis(ax2, 'auto');
ax3.Children.CData = imcrop(I3, rect); axis(ax3, 'auto');
end
Thank you so much! It works!

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (1)

Auwal
Auwal am 16 Okt. 2023

0 Stimmen

Thanks everyone that contributed.
please may i know if it is possible to get the pixel values in the defined roi and calculate the mean value.
Thanks in advace

2 Kommentare

Yes
croppedImage = imcrop(originalImage, roi.Position); % Get values in the rectangle.
meanValue = mean2(croppedImage)
Auwal
Auwal am 16 Okt. 2023
Thanks so much Image Analyst. It works fine.
However, I am not sure why is not working with circular roi "drawcircle"
Many thanks

Melden Sie sich an, um zu kommentieren.

Produkte

Version

R2019b

Community Treasure Hunt

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

Start Hunting!

Translated by