Problems with stopping a loop using a GUI and Getting data to apear in GUI

2 visualizzazioni (ultimi 30 giorni)
Hi, I have been having a lot of trouble trying to create a GUI for the following code. This code is used to calculated the hight, width and area of a flame. The images come from a webcamera and the main body of the code needs to be in a loop in order to constantly update the values of the height etc.
when you run the code bellow it pops up with a simple GUI with just a stop & start button, When you press start the webcam turns on and the hight, width and area start updating in the comand window. the press the stop button nothing happen? I think the problem is caused by there being a loop within a loop? But im not sure.
Also i would like to display the flameHeight, flameWidth and area on the GUI instead of the command window. I have tried to do it using:
flameArea = str2num(get(handles.counter_text,'String'));
set(handles.counter_text,'String',num2str(flameArea));
But it did not work, so i comented it out :( If anyone has any idea how i could solve these problems please let me know. Thank You!
function varargout = interruptFunction(varargin)
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @interruptFunction_OpeningFcn, ...
'gui_OutputFcn', @interruptFunction_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback', []);
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT
% --- Executes just before interruptFunction is made visible.
function interruptFunction_OpeningFcn(hObject, eventdata, handles, varargin)
% Choose default command line output for interruptFunction
handles.output = hObject;
% Update handles structure
guidata(hObject, handles);
% UIWAIT makes interruptFunction wait for user response (see UIRESUME)
% uiwait(handles.figure1);
% --- Outputs from this function are returned to the command line.
function varargout = interruptFunction_OutputFcn(hObject, eventdata, handles)
% varargout cell array for returning output args (see VARARGOUT);
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Get default command line output from handles structure
varargout{1} = handles.output;
--- Executes on button press in start_pushbutton.
function start_pushbutton_Callback(hObject, eventdata, handles)
%initialize the flag variable
set(handles.start_pushbutton,'UserData',1);
%while the flag variable is one, the loop continues
while (get(handles.start_pushbutton,'UserData') ==1)
%%%%%% flameArea = str2num(get(handles.counter_text,'String'));
%%%%%% set(handles.counter_text,'String',num2str(flameArea));
%"flushes the event queue" and updates the figure window
%since Matlab is a single thread process, this command is requierd
drawnow
imaqhwinfo ('winvideo', 1);
video = videoinput('winvideo',1,'RGB24_640x480');
preview(video);
origimage=getsnapshot(video);
imshow(origimage);
for count = 1:1000
tic
origimage=getsnapshot(video);
pause(0.05)
imshow(origimage);
imgGray = rgb2gray(origimage); %Converts Image to Gray Scale
imshow(imgGray);
noiseThreshold = 0.5; %Changes senstivity
heightThreshold = 5;
widthThreshold = 5;
imgB = im2bw(imgGray,noiseThreshold); %converts to binary
imshow(imgB);
imgHeight = size(imgB,1);
imgWidth = size(imgB,2);
% Height
for iRow = 1:1:imgHeight
if sum(imgB(iRow,:))>heightThreshold
flameH1 = iRow;
break;
end
end
for iRow = imgHeight:-1:1
if sum(imgB(iRow,:))>heightThreshold
flameH2 = iRow;
break;
end
end
flameHeight = flameH2 - flameH1
% Width
for iColumn = 1:1:imgWidth
if sum(imgB(:,iColumn))>widthThreshold
flameW1 = iColumn;
break;
end
end
for iColumn = imgWidth:-1:1
if sum(imgB(:,iColumn))>widthThreshold
flameW2 = iColumn;
break;
end
end
flameWidth = flameW2 - flameW1
% flameArea = flameWidth * flameHeight
flameArea = sum(sum(imgB))
end
end
--- Executes on button press in stop_pushbutton.
function stop_pushbutton_Callback(hObject, eventdata, handles)
%toggle the flag variable so that the other process will stop
set(handles.start_pushbutton,'UserData',0);
guidata(hObject, handles);

Risposta accettata

Peter Manley-Cooke
Peter Manley-Cooke il 4 Apr 2011
Hi Jim, It does actually work.
The problem is the for loop. I don't have the image & video toolkit so I commented all that part out, but with nothing inside the loop except the pause, it still takes 50 seconds for the loop to stop. With processing included it will take longer.
The reason is that the stop button can have no effect until the for loop has done its 1000 iterations, each with a 0.05 pause. 1000 x 0.05 = 50 seconds.
Just replace the for loop with the while loop,
while (get(handles.start_pushbutton,'UserData') ==1) && count < 1001
it will still loop until the stop button is pressed and you will get a quicker response to the button.
To update the flamearea continuously put the line
set(handles.counter_text,'String',num2str(flameArea));
inside this while loop, perhaps after the flame area is calculated.
Any Good?

Più risposte (1)

Peter Manley-Cooke
Peter Manley-Cooke il 30 Mar 2011
First the flame area display: You only need
set(handles.counter_text,'String',num2str(flameArea));
assuming that there is a text edit window in the gui called counter_text. You will need to initialise 'flameArea' before the while loop, set it to zero?
Why the for loop? You could do the same with a while loop with an extra condition the same as the previous while loop as in
count = 1;
while (get(handles.start_pushbutton,'UserData') ==1) && count < 1001
...
count=count+1
end
This would drop out of the loop when the condition is not met.
Is the start button defined as interruptable in the property editor? It should be.
Finally, I am not sure, but flushing the event queue may flush the stop button press, out of existance every time round the loop. Have you tried changing this for pause(0.01), which gives time for everything to catch up.
I hope this gives you some ideas, if not of much use in itself.
  1 Commento
jim
jim il 30 Mar 2011
Hi, Thanks for the help!
The reason im using a for loop is because it is in some example code that i have. (Shown bellow). Also I want the loop to be continuously loop until the stop button is pressed.
The example i have, is a gui with a simple stop & start button that stops/starts a number in a box counting up. Which works correctly.
But When i try to modify this code and put my 'flame code' instead of the original number counter code, the start button works but the stop button no longer works.
%Example Code
function varargout = interruptFunction(varargin)
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @interruptFunction_OpeningFcn, ...
'gui_OutputFcn', @interruptFunction_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback', []);
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT
% --- Executes just before interruptFunction is made visible.
function interruptFunction_OpeningFcn(hObject, eventdata, handles, varargin)
% Choose default command line output for interruptFunction
handles.output = hObject;
% Update handles structure
guidata(hObject, handles);
% UIWAIT makes interruptFunction wait for user response (see UIRESUME)
% uiwait(handles.figure1);
% --- Outputs from this function are returned to the command line.
function varargout = interruptFunction_OutputFcn(hObject, eventdata, handles)
% varargout cell array for returning output args (see VARARGOUT);
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Get default command line output from handles structure
varargout{1} = handles.output;
%%
% --- Executes on button press in start_pushbutton.
function start_pushbutton_Callback(hObject, eventdata, handles)
%initialize the flag variable
set(handles.start_pushbutton,'UserData',1);
%while the flag variable is one, the loop continues
while (get(handles.start_pushbutton,'UserData') ==1)
%increments the counter
temp = str2num(get(handles.counter_text,'String'));
temp = temp + 1;
set(handles.counter_text,'String',num2str(temp));
%"flushes the event queue" and updates the figure window
%since Matlab is a single thread process, this command is requierd
drawnow
end
%%
% --- Executes on button press in stop_pushbutton.
function stop_pushbutton_Callback(hObject, eventdata, handles)
%toggle the flag variable so that the other process will stop
set(handles.start_pushbutton,'UserData',0);
guidata(hObject, handles);

Accedi per commentare.

Community Treasure Hunt

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

Start Hunting!

Translated by