Frame will not update with Live Video Tacking

2 views (last 30 days)
Hello Everyone! I need some help... I'm working on a project that will track the position of a particle using a live video feed and frame capture. To start I created a custom GUI with the help of this tutorial:
I then added to the captureImage_Callback function to perform some image processing techniques and a for loop to capture 10 frames.
The issue that I am having now is that when I press the pushbutton "captureImage" The program does indeed capture 10 frames. However it is capturing the same frame 10 times. Is there a way I can have MATLAB update the frame to be captured so that I have subsequent frames instead of the same frame 10 times?
I apologize with my lack of experience with custom GUI's. I haven't done much work with them. attached is my code.
Thank you in advance!

Accepted Answer

Geoff Hayes
Geoff Hayes on 14 Sep 2014
John - once you start the camera, does the camera axes (in your GUI) update/refresh with new images periodically, or does the image remain fixed? In the myCameraGUI_OpeningFcn function, you have the following two lines
handles.video.FramesPerTrigger = Inf; % Capture frames until we manually stop it
set(handles.video,'FramesPerTrigger',1)
I don't have the Image Acquisition Toolbox so can't run the above, but based on the FramesPerTrigger page, if this property is set to Inf then the object keeps acquiring frames until an error occurs or you issue a stop command. The second line of code replaces this value with one, and so only one frame is acquired for every trigger that is executed. Why did you add this second line?
Another concern may be with the captureImage_Callback. Since the timer has a period of 0.05 seconds, it may be that the for loop
for i=1:10
% do image stuff
end
iterates quicker than the 0.05 seconds before a new image/frame is acquired. You record the elapsed time with tic and toc - what is that elapsed time after the for loop has ended? Note that there is no guarantee that this code would capture ten consecutive frames, and so is most likely just capturing the same one ten times.
You may need to add a pause to the above code to wait for the new frame to be acquired, something like
for i=1:10
% do image stuff
% wait for new image/frame
pause(0.05);
end
Or you may wish to add logic/code to the periodic timer function to check to see if the capture image button has been pressed and if so, check to see if ten consecutive frames have been written to file. If not, then write the latest image/frame to file and increment a counter. If so, then clear the flag indicating that the capture button was pressed.
Doing it this way (updating the timer code) would ensure that you capture ten consecutive frames. In the timer code that builds the callback, you could add a line that would call another function (after the latest image/frame was acquired) and this function would check to see if the capture button was pressed and if ten frames have been written to file.
I think this is a better way than adding the pause command in the for loop. As the timer is responsible for acquiring new frames, then since it "knows" when a new frame is acquired then it can process it further and write the results to file.

More Answers (1)

John
John on 15 Sep 2014
Thanks Geoff!
The following two lines were used as a sort of test area for me. I wanted to see if either of the lines of code would make a difference in the image capture. I would normally just comment one or the other out. It seems that using INF is working and I have removed the second line from the m file:
handles.video.FramesPerTrigger = Inf; % Capture frames until we manually stop it
set(handles.video,'FramesPerTrigger',1) - HAS BEEN DELETED AS OF TODAY.
You were also right about the timing issue. After playing around with some pause values within the for loop I am able to capture consecutive frames. Obviously this technique lowers the frame rate to about 2 frames per second (Calculated within the code using tic/toc). I will have to try to keep the frame rate as high as possible for the application of this code. I will try to modify the Timer Function today as per your suggestion:
Or you may wish to add logic/code to the periodic timer function to check to see if the capture image button has been pressed and if so, check to see if ten consecutive frames have been written to file. If not, then write the latest image/frame to file and increment a counter. If so, then clear the flag indicating that the capture button was pressed.
Doing it this way (updating the timer code) would ensure that you capture ten consecutive frames. In the timer code that builds the callback, you could add a line that would call another function (after the latest image/frame was acquired) and this function would check to see if the capture button was pressed and if ten frames have been written to file.
This will be my first time trying to modify a Timer Function. Can you recommend any resources that I can use to help me through this process? Thanks again for your help!
  1 Comment
Geoff Hayes
Geoff Hayes on 16 Sep 2014
Hi John - you can take a look at the documentation at TimerFcn as this will be the property of the videoinput that you will need to modify in order to capture the ten frames (etc.). Unfortunately, there is very little to read, but the key point is the data type for the TimerFcn which is one of a string, function handle, or cell array.
In your code, you are using a string as
set(handles.video,'TimerPeriod', 0.05, ...
'TimerFcn',['if(~isempty(gco)),'...
'handles=guidata(gcf);'...
'image(getsnapshot(handles.video));'...
'set(handles.cameraAxes,''ytick'',[],''xtick'',[]),'...
'else '...
'delete(imaqfind);'...
'delete(hObject);'...
'end']);
You should be able to change it to a function handle as
set(handles.video,'TimerPeriod', 0.05, ...
'TimerFcn', @myTimerCallback);
Now, define the the callback as
function myTimerCallback()
if(~isempty(gco))
handles=guidata(gcf);
image(getsnapshot(handles.video));
set(handles.cameraAxes,'ytick',[],'xtick',[])
else
delete(imaqfind);
delete(hObject);
end
Try just changing the above (in your code) and re-run to ensure that the same behaviour still exists. Hopefully it will! Then you can make changes to myTimerCallback to check to see if the user has pressed the capture button, and if so, whether to continue writing frames to file. See guidata on how you can pass data from one callback to another (in your case, this may be to pass the "capture" button has been pressed from the capture button callback to the timer callback.

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!