App designer - issue with app freezing after performing the first task

15 vues (au cours des 30 derniers jours)
Teshan Rezel
Teshan Rezel le 24 Mar 2021
Modifié(e) : Adam Danz le 29 Mar 2021
Hi folks,
I have an app that's meant to display an image from a folder with plots on them in the shape of a crosshair.
Currently, it is freezing after loading the image folder and displaying the first image, and I'm uncertain as to why.
Could you please point me in the direction of where my code is incorrect?
checkMatrix is a matrix of 9 checkbox values.
The issue appears to be in the "DisplayCrosshairs" section. The very first line causes the programme to sieze up and become completely un-interactable.
Thanks
methods (Access = private)
function ROI(app, index1, index2)
hold on
plot(index1, index2, app.innerMarkerStyle, 'MarkerSize', app.CrosshairThickness.Value, 'Color', app.crossHairColour);
plot(index1, index2, app.outerMarkerStyle, 'MarkerSize', app.CrosshairThickness.Value, 'Color', app.crossHairColour);
end
function DisplayCrosshairs(app)
[rows, columns] = size(app.Image, [1, 2]);
quarterHeight = rows*0.25;
halfHeight = rows*0.5;
threeQuarterHeight = rows*0.75;
quarterWidth = columns*0.25;
halfWidth = columns*0.5;
threeQuarterWidth = columns*0.75;
checkMatrix = [app.TopLeft.Value app.TopMiddle.Value app.TopRight.Value app.CentreLeft.Value app.CentreMiddle.Value app.CentreRight.Value app.BottomLeft.Value app.BottomMiddle.Value app.BottomRight.Value];
app.numSamplesPerImage = sum(checkMatrix, 1:9);
if checkMatrix(1) == 1
ROI(app, quarterHeight, quarterWidth);
elseif checkMatrix(2) == 1
ROI(app, quarterHeight, halfWidth);
elseif checkMatrix(3) == 1
ROI(app, quarterHeight, threeQuarterWidth);
elseif checkMatrix(4) == 1
ROI(app, halfHeight, quarterWidth);
elseif checkMatrix(5) == 1
ROI(app, halfHeight, halfWidth);
elseif checkMatrix(6) == 1
ROI(app, halfHeight, threeQuarterWidth);
elseif checkMatrix(7) == 1
ROI(app, threeQuarterHeight, quarterWidth);
elseif checkMatrix(8) == 1
ROI(app, threeQuarterHeight, halfWidth);
elseif checkMatrix(9) == 1
ROI(app, threeQuarterHeight, threeQuarterWidth);
else
msgbox('Please select a quadrant for the crosshair to be displayed in');
end
end
function DisplayImage(app)
app.currentImage = fullfile(app.imageFolder(app.imageNumber).folder, app.imageFolder(app.imageNumber).name);
app.Image.Position = [0 0 app.UIFigure.Position(3:4)];
app.img = imread(app.currentImage);
app.uiImage = uiimage(app.UIFigure, 'imagesource', app.currentImage, "Position", app.Image.Position);
DisplayCrosshairs(app);
end
function LoadFolder(app)
app.imageFolder = dir(fullfile(app.filePath, '*.jpg'));
app.fileNumber = numel(app.imageFolder);
end
function CheckEndOfList(app)
if app.imageNumber < app.fileNumber
app.imageNumber = app.imageNumber +1;
else
msgbox('You have reached the last image');
end
end
end
function startupFcn(app)
pause(1);
app.UIFigure.WindowState = 'maximized';
app.Counts = [zeros(8, 1)];
app.Percentages = [zeros(8, 1)];
app.CokeTable.Data = [app.Counts, app.Percentages];
app.CokeTable.Position = [73 -1 168 265];
app.tallyOrder = [1];
app.innerMarkerStyle = '+';
app.outerMarkerStyle = 'o';
app.crossHairColour = 'w';
app.ImageNumber.Value = app.imageNumber;
app.TotalNumber.Value = app.fileNumber;
end
function AddImageFolderMenuSelected(app, event)
app.filePath = uigetdir(pwd);
addpath(app.filePath);
LoadFolder(app);
DisplayImage(app);
CheckEndOfList(app);
app.ImageNumber.Value = app.imageNumber;
app.TotalNumber.Value = app.fileNumber;
end
  5 commentaires
Teshan Rezel
Teshan Rezel le 25 Mar 2021
Hi @Adam Danz, I get the following error in the command window when running the app:
Array indices must be positive integers or
logical values.
Error in ManualPointCount/DisplayImage (line
168)
app.currentImage =
fullfile(app.imageFolder(app.imageNumber).folder,
app.imageFolder(app.imageNumber).name);
Error in
ManualPointCount/AddImageFolderMenuSelected
(line 279)
DisplayImage(app);
Error using matlab.ui.internal.controller.WebMenuController/fireActionEvent (line 67)
Error while evaluating Menu Callback.
172 app.uiImage = uiimage(app.UIFigure, 'imagesource', app.currentImage, "Position", app.Image.Position);
K>>
Adam Danz
Adam Danz le 25 Mar 2021
Replied below in Jan's answer.

Connectez-vous pour commenter.

Réponse acceptée

Adam Danz
Adam Danz le 26 Mar 2021
>At this point, a figure called "Figure 2" pops up
That's because you're not using axis handles to specify the parent in these lines below
function ROI(app, index1, index2)
hold on
plot(index1, index2, app.innerMarkerStyle, 'MarkerSize', app.CrosshairThickness.Value, 'Color', app.crossHairColour);
plot(index1, index2, app.outerMarkerStyle, 'MarkerSize', app.CrosshairThickness.Value, 'Color', app.crossHairColour);
end
Instead, replace app.UIAxes below with your axis handle.
function ROI(app, index1, index2)
hold(app.UIAxes,'on')
plot(app.UIAxes, index1, index2, app.innerMarkerStyle, 'MarkerSize', app.CrosshairThickness.Value, 'Color', app.crossHairColour);
plot(app.UIAxes, index1, index2, app.outerMarkerStyle, 'MarkerSize', app.CrosshairThickness.Value, 'Color', app.crossHairColour);
end
> and the main app freezes
No, it doesn't freeze. Execution stops because of an error!
  4 commentaires
Teshan Rezel
Teshan Rezel le 29 Mar 2021
thanks @Adam Danz, this is pretty much exactly the solution I needed! The only issue now is that the "plot" function doesn't appear centred on the image, and is far too small to be seen. Can you please advise me on how to rectify this?
function ROI(app, index1, index2)
hold (app.Image, "on")
plot(app.Image, index1, index2, app.innerMarkerStyle, 'MarkerSize', app.CrosshairThickness.Value, 'Color', app.crossHairColour);
plot(app.Image, index1, index2, app.outerMarkerStyle, 'MarkerSize', app.CrosshairThickness.Value, 'Color', app.crossHairColour);
end
function DisplayCrosshairs(app)
I = imshow(app.currentImage, "Parent", app.Image);
app.Image.XLim = [0 I.XData(2)];
app.Image.YLim = [0 I.YData(2)];
app.Width = app.Image.XLim;
app.Height = app.Image.YLim;
quarterHeight = app.Height(1)+range(app.Height)*0.25;
halfHeight = app.Height(1)+range(app.Height)*0.5;
threeQuarterHeight = app.Height(1)+range(app.Height)*0.75;
quarterWidth = app.Width(1)+range(app.Width)*0.25;
halfWidth = app.Width(1)+range(app.Width)*0.5;
threeQuarterWidth = app.Width(1)+range(app.Width)*0.75;
checkMatrix = [app.TopLeft.Value app.TopMiddle.Value app.TopRight.Value app.CentreLeft.Value app.CentreMiddle.Value app.CentreRight.Value app.BottomLeft.Value app.BottomMiddle.Value app.BottomRight.Value];
app.numSamplesPerImage = sum(checkMatrix, 1:9);
if checkMatrix(1) == 1
ROI(app, quarterHeight, quarterWidth);
elseif checkMatrix(2) == 1
ROI(app, quarterHeight, halfWidth);
elseif checkMatrix(3) == 1
ROI(app, quarterHeight, threeQuarterWidth);
elseif checkMatrix(4) == 1
ROI(app, halfHeight, quarterWidth);
elseif checkMatrix(5) == 1
ROI(app, halfHeight, halfWidth);
elseif checkMatrix(6) == 1
ROI(app, halfHeight, threeQuarterWidth);
elseif checkMatrix(7) == 1
ROI(app, threeQuarterHeight, quarterWidth);
elseif checkMatrix(8) == 1
ROI(app, threeQuarterHeight, halfWidth);
elseif checkMatrix(9) == 1
ROI(app, threeQuarterHeight, threeQuarterWidth);
else
msgbox('Please select a quadrant for the crosshair to be displayed in');
end
end
Adam Danz
Adam Danz le 29 Mar 2021
Modifié(e) : Adam Danz le 29 Mar 2021
Are you referring to the ROI(app, index1, index2) function?
What have you tried to do to fix it?
You can get the size of the image using
size(I)
where I is your image data. You can get the center of the image using
size(I)/2
If there is space in the margins between the image and the axes use
axis(app.UIAxes, 'tight')

Connectez-vous pour commenter.

Plus de réponses (1)

Jan
Jan le 24 Mar 2021
Appending folders to Matlab's PATH can lead to unexpected side effects, if the folders contain Matlab files. So avoid addpath but use absolute path names using app.filePath and fullfile() - as you do already. So remove this line:
addpath(app.filePath);
But this is most likely not the source of the problem.
Adam's suggestion to use the debugger to step through the code line by line is the way to locate the line, which causes the troubles.
  6 commentaires
Adam Danz
Adam Danz le 25 Mar 2021
Modifié(e) : Adam Danz le 26 Mar 2021
@Teshan Rezel, I'll reply to you here rather than having two parallel conversations.
This is the first line of DisplayImage(app), not the DisplayCrosshairs function as you indicated earlier. It's a minor mistake not to worry about but it did result in time troubleshooting the wrong parts of the code.
More importantly, now we know that the app isn't freezing. It's not just stopping due to an error and an error message should have appeared in the command window and in app designer code view if the app was opened in app desginer. That's an important lesson - check the command window for error messages if a program stops unexpectedly.
I agree with Jan, app.imageNumber is neither a positive integer or logical value as the error message indicates. Maybe it's a valid number wrapped in a cell such as {1} or perhaps it's empty or NaN.
Teshan Rezel
Teshan Rezel le 26 Mar 2021
Hi @Adam Danz and @Jan, I think it seems to fail when it gets to the "if" statement within the DisplayCrosshairs function. At this point, a figure called "Figure 2" pops up with a small crosshair at its centre, and the main app freezes. I'm not sure how to pass make "plot" draw the crosshair on the app.Image property though

Connectez-vous pour commenter.

Catégories

En savoir plus sur Graphics Object Programming dans Help Center et File Exchange

Produits


Version

R2020b

Community Treasure Hunt

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

Start Hunting!

Translated by