Re-run section of code when rectangle selection is resized
Afficher commentaires plus anciens
I have thermal camera footage that consists of a few hundred frames saved as individual .mat files that contain temperature arrays. I want to run the code below. First, I visualize a particular frame using imagesc. I use drawrectangle to crop the image to a designated ROI of temperatures, then use that position to crop the rest of my frames. I do some math to the "cropped" array values, then display one of the altered frames as another color-scaled image. At this point, I want to be able to click back to my first figure window, make small adjustments to the size of the original ROI, and have the script run through again with the new region to produce an updated final image. I have to be able to see this final, representative image in order to know how much to adjust the ROI. Right now, I'm just running the script over and over again until I'm happy with the crop region. Any ideas?
N = %total number of frames
h = load(['frame100.mat']);
figure
imagesc(h.Frame) % "Frame" is 480x640 double array within the struct "h"
colormap jet
hold on
roi = drawrectangle('Color','w');
z = [1 N-1];
crop = [roi.Position(1) roi.Position(2) z(1) roi.Position(3) roi.Position(4) z(2)];
for i = 0:N
load(['frame' num2str(i) '.mat']);
frames(:,:,i+1) = Frame;
end
croppedFrames = imcrop3(frames,crop);
%
% Do some math to the array values
%
% Display representative altered region of same original frame
representativeFrame = alteredFrames(:,:,100);
figure
imagesc(representativeFrame)
colormap jet
%
% Here is the point at which I want to resize the ROI and have everything up to this point update based on the new array values.
%
%
% More script I want to run after ROI is finalized
Réponse acceptée
Plus de réponses (1)
Yash
le 1 Sep 2023
Hi @Maddie Kern
To achieve the functionality you described, where you can interactively adjust the ROI and have the script update accordingly, you can use a combination of waitfor and callbacks in MATLAB. Here's how you can modify your code to implement this behavior:
N = %total number of frames
h = load(['frame100.mat']);
figure
imagesc(h.Frame) % "Frame" is 480x640 double array within the struct "h"
colormap jet
hold on
roi = drawrectangle('Color','w');
z = [1 N-1];
crop = [roi.Position(1) roi.Position(2) z(1) roi.Position(3) roi.Position(4) z(2)];
% Initialize variable to keep track of ROI change
roiChanged = false;
% Set up a button callback function
function updateROIButtonCallback(~, ~)
% Update the crop parameters based on the new ROI position
crop = [roi.Position(1) roi.Position(2) z(1) roi.Position(3) roi.Position(4) z(2)];
% Signal that ROI has changed
roiChanged = true;
% Close the figure
close(gcf);
end
% Add a button to update ROI with the callback to updateROIButtonCallback
updateButton = uicontrol('Style', 'pushbutton', 'String', 'Update ROI', ...
'Position', [10 10 100 30], 'Callback', @updateROIButtonCallback);
% Wait for the user to interact with the ROI and click the update button
waitfor(updateButton, 'UserData');
if roiChanged
% Loop over frames and perform necessary operations
frames = zeros([size(h.Frame), N]);
for i = 0:N
load(['frame' num2str(i) '.mat']);
frames(:,:,i+1) = Frame;
end
croppedFrames = imcrop3(frames,crop);
% Perform the rest of your calculations
% Display the altered frame
representativeFrame = alteredFrames(:,:,100);
figure
imagesc(representativeFrame)
colormap jet
end
% More script you want to run after ROI is finalized
In this code, a button named "Update ROI" is added to the figure window that allows you to manually trigger the update of the ROI and subsequent processing. The waitfor function waits for a UI event, in this case, clicking the button, before continuing with the script. The UserData property is set to signal that the button has been clicked. This way, you can adjust the ROI in the first figure window, click the "Update ROI" button, and then the script will proceed with the updated ROI and display the final result.
I hope this helps.
3 commentaires
Maddie Kern
le 1 Sep 2023
Hi @Maddie Kern
It seems like there might be an issue with the scope of the roi variable within the callback function. To resolve this issue, you can use the gcf (get current figure) and findobj functions to access the ROI within the callback function. Here's how you can modify the updateROIButtonCallback
function updateROIButtonCallback(~, ~)
% Get the current figure
fig = gcf;
% Find the ROI within the current figure
roi = findobj(fig, 'Type', 'images.roi.rectangle');
% Check if ROI exists
if ~isempty(roi)
% Update the crop parameters based on the new ROI position
crop = [roi.Position(1) roi.Position(2) z(1) roi.Position(3) roi.Position(4) z(2)];
% Signal that ROI has changed
roiChanged = true;
% Close the figure
close(fig);
else
% Handle the case when ROI is not found
disp('ROI not found');
end
end
Well, this is one fo the many ways to handle the scope of the roi variable. You can also try other approaches such as
- using global keyword to make the roi variable globally available.
- by passing the roi as an arguement to the updateROIButtonCallback.
It would also be helpful if you could share your data files, that would help me in delivering better code quality.
I hope this helps.
Maddie Kern
le 4 Sep 2023
Catégories
En savoir plus sur ROI-Based Processing dans Centre d'aide et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!