Flip real time video and stop it with user input - matlab

I created a GUI using Matlab and inserted a live video in this GUI with 2 bush buttons, one for starting video and the other for capturing an image.
The problem is when I press start video, the video displays the picture flipped, it means when you wave right hand, it is displayed in the left side.
how can I solved this problem?
I wrote this code:
i=0;
while(i<=1000)
dataa=getsnapshot(vid);
data1 = dataa(:,:,1);
data1 = fliplr(data1);
data2 = dataa(:,:,2);
data2 = fliplr(data2);
data3 = dataa(:,:,3);
data3 = fliplr(data3);
data=cat(3,data1,data2,data3);
flushdata(vid);
imshow(data);
end
and it works, but now I want to stop the while statement when the user pushes a button. How can I do that?
Thank you.

You can use the fliplr() function to flip your frames when you capture them to flip them. As long as I know, this code is quite fast as it doesnt flip the positions but changes the matrix element memory directions.
For stoping the while loop I suggest the next thing (maybe a more experienced matlab "player" would do it something else)
Wherever you have the code do:
while (i<=1000)&&~buttonpushed
% your code
pause(0.01) % If you dont pause the loop the GUI cannot refresh
end
In the startup part of the code
global buttonpushed;
buttonpushed=false;
And In the callback of the button:
function pushbutton1_Callback(hObject, eventdata, handles)
if get(hObject,'Value')
buttonpushed=true;
else
buttonpushed=false;
end
end

Related

datacursormode: spurious MouseMotion event processing when UpdateFcn takes time to return

I'm using DATACURSORMODE in Matlab 8.1.0.604 (R2013a) on Mac OS 10.11.6 (El Capitan).
In the simple example below, the data cursor only moves when a new location is clicked, not when the mouse is merely moved. This is exactly the behaviour I want. However, in my code I get a different behaviour: after the first click, the cursor moves whenever the mouse just moves, until I subsequently double-click. I did not knowingly ask for this latter behaviour and do not want it.
The key difference seems to be that my UpdateFcn callback code takes time to complete (and let's assume it always will: my callback is intended to perform fairly complex actions, and is already as vectorized and optimized as it can get). This is emulated by the pause statement in the example below, which should hopefully replicate the problem if uncommented (might have to fiddle with the duration, depending on platform/setup).
In datacursormode.m the "UNDOCUMENTED FUNCTIONALITY" comments mention that both MouseMotion and ButtonDown events are thrown by a data cursor mode object. This is clearly not the full story, because by default there's no response to mouse motion alone, but something happens, presumably due to the delay, to make it do so.
So my question is: is this cursor-moving-on-mouse-motion-until-you-doubleclick a known feature/mode, or just unintended "undefined behaviour" as a side effect of the delay? In either case, how can I (programmatically) prevent it from happening, assuming I can't actually speed up the callback code?
function demo
fig = 1;
figure(fig), close, figure(fig) % ensure virgin figure
image
h = datacursormode(fig);
datacursormode(fig, 'on')
set(h, 'UpdateFcn', #callback)
function txt = callback(cbo, event)
% pause(0.1) % uncomment this line (and/or lengthen the delay as necessary) to replicate the problem
txt = evalc('cbo,event,disp(get(event))');
I couldn't actually reproduce your problem on R2012a or R2016a on Windows, but it sounds like on your system MATLAB is failing to catch the ButtonUp event when you click. The reason MouseMotion events are processed is because you should be able to drag the cursor when you have the mouse button held down.
Assuming that it is indeed the slow response of the UpdateFcn that causes this, you may be able to resolve this by triggering the slow part in an asynchronous operation which then triggers another update when it is done. The most universal form of this, I think, is to use a timer with a very short StartDelay. In the example below I've used appdata to share handles between the datacursormode object and the timer, but you could approach this in many different ways in your specific implementation.
function demo
fig = 1;
figure(fig), close, figure(fig) % ensure virgin figure
image
h = datacursormode(fig);
datacursormode(fig, 'on')
set(h, 'UpdateFcn', #cursormodecallback)
setappdata(fig, 'cursormode',h);
setappdata(fig, 'timer',timer('StartDelay',0.001, 'TimerFcn',#timercallback));
setappdata(fig, 'lasttxt','Initial text');
function txt = cursormodecallback(cbo, event)
txt = getappdata(1,'lasttxt'); % Display the most recently generated text in the tooltip
t = getappdata(1,'timer');
if strcmp(get(t,'Running'),'off') % If we have already asked for an updated tooltip and haven't got one yet then don't ask for another one
set(t, 'UserData',{cbo,event}); % Store the data needed by the slow callback to generate the tooltip
start(t); % Ask the timer to generate new text
end
function timercallback(cbo, event)
cursordata = get(cbo,'UserData');
[cbo,event] = cursordata{:};
pause(1)
txt = evalc('cbo,event,disp(get(event))');
if ~isequal(txt,getappdata(1,'lasttxt'))
setappdata(1,'lasttxt',txt); % Store the latest text
updateDataCursors(getappdata(1,'cursormode')); % Update the cursor so the text is displayed
end
Here's an edited version of Will's solution that works nicely. The StartDelay value is critical: <=6ms fails to solve the mouse motion problem. 7ms solves it most of the time, but occasionally lapses. 10ms seems to work fairly reliably (except the very first time in a given new Matlab session, when things are slow to wake up). Typical Matlab implementation flakiness...
function demo
fig = 100;
figure(fig), close, figure(fig) % ensure virgin figure
img = image;
EnableDataCursor(img)
function EnableDataCursor(img)
ax = get(img, 'parent');
fig = get(ax, 'parent');
dcm = datacursormode(fig);
datacursormode(fig, 'on')
set(dcm, 'UpdateFcn', #CursorModeCallback)
setappdata(img, 'CursorModeObject', dcm);
setappdata(img, 'Timer', timer('StartDelay', 0.010, 'TimerFcn', #TimerCallback));
setappdata(img, 'LastText', 'Initial text');
function txt = CursorModeCallback(cbo, event)
img = get(event, 'Target');
t = getappdata(img, 'Timer');
if strcmp(get(t, 'Running'), 'off') % If we have already asked for an updated tooltip and haven't got one yet then don't ask for another one
txt = 'updating...';
set(t, 'UserData', {cbo, event}); % Store the data needed by the slow callback to generate the tooltip
start(t); % Ask the timer to generate new text
else
txt = getappdata(img, 'LastText'); % Display the most recently generated text in the tooltip
end
function TimerCallback(t, varargin)
ud = get(t, 'UserData');
[cbo, event] = deal(ud{:});
img = get(event, 'Target');
pause(1) % numbercrunch, numbercrunch, numbercrunch
txt = num2str(get(event, 'Position'));
if ~isequal(txt, getappdata(img, 'LastText'))
setappdata(img, 'LastText', txt); % Store the latest text
updateDataCursors(getappdata(img, 'CursorModeObject')); % Update the cursor so the text is displayed
end

Simply entering the debugger during execution of MATLAB GUI fixes error that persists during normal execution

I'm using a programmatic GUI in MATLAB which uses multiple figure windows. When I press the button 'Redraw' in Figure A, a new figure appears (Figure B) with some data plotted. I want the focus to immediately switch back to Figure A because there are many hotkeys (WindowKeyPressFcn) that I use in that window to update the plots in Figure B.
There are two problems here:
1) The last line of the callback for the button 'Redraw' does switch focus back to Figure A, BUT only if Figure B exists already. That is, the first time Figure B is created, it remains in focus. If I then use Figure A to update the plots in Figure B, the focus correctly switches back to Figure A. I can't think of why it behaves differently during the first redraw and all subsequent calls.
2) The even bigger issue is that if I set a breakpoint anywhere in the code and then resume execution, the focus switches back to Figure A as I want. So, why does entering the debugger and doing nothing else fix the problem? How can I find the issue if everything works in the debugger?
Thanks in advance!
EDIT: To my great surprise, I was able to reproduce this "Heisenbug" by writing my first ever programmatic GUI. This should be the simplest example of my problem. To see it in action, simply run the code below and click on the push button. For some reason, when Window 2 is created for the first time, the focus does NOT switch back to Window 1 as intended. It works properly for all subsequent button presses. Try closing Window 2 and pushing the button again, the error will keep occurring.
As mentioned in the original post, setting a breakpoint in the code resolves the issue. Set a breakpoint at line 27, then resume execution and Window 1 will be in focus.
What is happening here?
function heisenbug
%% Main problem:
% After clicking the push button, I want the focus to
% always switch back to Window 1 (the one containing the button).
% However, this does not work when Window 2 is first created.
%%
%% Create and then hide the GUI as it is being constructed
f = figure('Visible','off','name','Window 1','units','normalized','Position',[0.1 0.1 0.5 0.5]);
%% Initialize handles structure
handles = guihandles(f);
handles.window2 = [];
guidata(f,handles)
%% Make a button
hbutton = uicontrol('Style','pushbutton','String','Push me','units','normalized',...
'Position',[0.1 0.1 0.8 0.8],...
'Callback',#button_Callback);
%% Make the GUI visible
f.Visible = 'on';
%% Button callback
function button_Callback(source,eventData)
handles = guidata(gcbo);
% If Window 2 already exists, plot a circle, then switch focus back to Window 1.
if ~isempty(handles.window2) && ishandle(handles.window2)
figure(handles.window2);
plot(1,1,'bo')
figure(f);
% Otherwise, create Window 2 and do the same thing.
else
handles.window2 = figure('Name','Window 2','units','normalized','position',[0.4 0.1 0.5 0.5]);
plot(1,1,'bo')
figure(f)
end
guidata(source,handles)
end
end
My post was quickly answered by Adam (thanks!) on the MathWorks site: http://se.mathworks.com/matlabcentral/answers/299607-simply-entering-the-debugger-during-execution-of-matlab-gui-fixes-error-that-persists-during-normal.
I needed to insert a pause(0.05) after Window 2 is created, before trying to switch the focus back with figure(f). Otherwise the focus is stolen back to Window 2 when it finishes plotting.

MATLAB Slider GUI with Background While Loop to Control Feedback Servo Motors

I am attempting to implement a servo motor with feedback control program in MATLAB for multiple servo motors. The objective is to read servo(s) analog output, compare with a user value from slider bar(s), write the new position to the servo, and continue to write or monitor analog output to ensure servo maintains last user value. I am having trouble because I cannot figure out the optimal flow to always keep the GUI open and accepting user values while a while loop runs in the background. Below is the general structure that I would like the code to output:
test_gui %calls GUI figure with slider bar
GUI window with Slider bar pops up
%Callback for when user slides bar
function slider(i)_Callback(hObject, eventdata, handles)
% hObject handle to slider1 (see GCBO)
load('user.mat'); %Load previous user input
sze=size(user,1);
user(sze+1,1)=get(hObject,'Value'); %Add new user input to previous input
save('user.mat','user') %Save variable to be accessed by outer loop
'user' is passed into a continuous while loop that writes servo position
while user ~= 'c' %Continue to run until close window callback
load('user.mat'); %load user input from callback
Write_Servoi(a,user(end,:),add,speed,pinin,myServo) %Writes to servo(s) based on last input, allows servo(s) to maintain position if torqued out of position
end
During this while loop, I would like the user to be able to continuously change the slider and send this slider value into the while loop to be written to the servo. However, I cannot figure out how to update user when in the while loop.
If anyone has any ideas on how to get this to work, please let me know. I would greatly appreciate any help. I am open to changing the structure, as long as the objectives above are satisfied.
Robert
To update the user variable, you'll need to make sure it is properly loaded. Calling load with no output does not always load your variable into the function workspace.
Instead of load('user.mat');, you'll need to load your file as a structure and then retrieve your variable from the structure. To accomplish this, do the following:
s=load('user.mat');
user=s.user;

Conditional pausing in Matlab (not Debugging)

I am new to Matlab so please bear with me.
So I created a two GUID GUI in which one generates a dynamic data and updates the plotting every second so I used pause(1) (which is continuous) and the second one takes the full data of the first GUI and plots it (opens on button press)
Is there a way where if I open the the second GUI the first GUI pauses and if and only if the second GUI is stopped the first GUI resumes its process?
Thanks in advance.
Update
Example:
gui1.m
function guie1()
for ii=1:100
c = magic(ii)
plot(c);
% a button at this point
% Some pause condition
drawnow;
end
so when I click on that button it would open a window (a new figure may be) so unless I close is the loop should be paused.
Here is the example:
run(fullfile(docroot,'techdoc','creating_guis','examples','callback_interrupt'));
Here is the link:
http://www.mathworks.com/help/matlab/creating_guis/callback-sequencing-and-interruption.html
Update:
Here:
http://blogs.mathworks.com/videos/2010/12/03/how-to-loop-until-a-button-is-pushed-in-matlab/
http://www.mathworks.com/matlabcentral/fileexchange/29618-spspj

Detect a keystroke in matlab while viewing a figure?

I'm trying to sort through some image data in matlab and want to prompt the user for input about a series of images. Each time I show an image I want to pause and wait for a keystroke and perform a different action depending on what was pressed.
Current Best Solution:
responses = zeros(length(images),1);
for i = 1:length(images)
im = imread(images{i}.fname);
h = figure(1);
imshow(im);
% instead of just pause, I want to get the keystroke (k) that was pressed
waitforbuttonpress;
k = get(h,'CurrentCharacter');
switch lower(k)
case 'a'
responses(i) = 1;
case 'b'
responses(i) = 2;
end
end
You could use the KeyPressFcn property of the figure environment which should be set to a handle of a callback function that receives an event structure containing the character pressed. See the Matlab documentation for details and example.
Also you can look at the CurrentKey property of the figure environment but it will not give you a way to know when the key is actually pressed.