Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Camera frame update can hog MATLAB and massively slow down some stuff #126

Open
raacampbell opened this issue Apr 27, 2023 · 4 comments
Open
Labels
Known obvious issue Issues that users are likely to report as bugs

Comments

@raacampbell
Copy link
Contributor

raacampbell commented Apr 27, 2023

A lot of operations, like opening folders, fitting models, etc, run orders of magnitude slower because somehow they are being bogged down by the camera updating. Only certain things seem badly affected. It shouldn't really be like this but at present a bunch of Zapit operations that seem affected will shut down the camera temporarily whilst they complete before firing it back up again. We should work out why this happens and fix it. I'm sure we can do better than this. Maybe there should be a timer rather than a listener on the new frame property.

For sure something wrong is happening because if you ctrl-c at the CLI you abort the image acquisition and the following error pops up:

Operation terminated by user during imaqdevice/flushdata


In zapit.hardware.camera/flushdata (line 149)
                flushdata(obj.vid)

In zapit.pointer/storeLastFrame (line 26)
    obj.cam.flushdata

In zapit.pointer>@(varargin)obj.storeLastFrame(varargin{:}) (line 126)
                obj.cam.vid.FramesAcquiredFcn = @obj.storeLastFrame;
 
Warning: The FramesAcquiredFcn callback is being disabled.
To enable the callback, set the FramesAcquiredFcn property. 

You might also get:

Operation terminated by user during imaqdevice/peekdata


In zapit.hardware.camera/getLastFrame (line 156)
                lastFrame=squeeze(peekdata(obj.vid,1));

In zapit.pointer/storeLastFrame (line 16)
    tmp = obj.cam.getLastFrame;

In zapit.pointer>@(varargin)obj.storeLastFrame(varargin{:}) (line 126)
                obj.cam.vid.FramesAcquiredFcn = @obj.storeLastFrame;
 
Warning: The FramesAcquiredFcn callback is being disabled.
To enable the callback, set the FramesAcquiredFcn property. 
Warning: An error occurred while drawing the scene: Error in json_scenetree: Could not find node in replaceChild 

Exactly what you see must depend on what it was doing when ctrl-c is hit.

Other times it will start filling the screen with:

Warning: An error occurred while drawing the scene: Error in json_scenetree: Could not find node in replaceChild 

And you have to restart it.

@raacampbell raacampbell added the Known obvious issue Issues that users are likely to report as bugs label Apr 27, 2023
@raacampbell raacampbell changed the title Camera frame update can hog MATLAB and massively slow stuff down Camera frame update can hog MATLAB and massively slow down some stuff Feb 11, 2024
@raacampbell
Copy link
Contributor Author

raacampbell commented May 10, 2024

To test this I start Zapit and look at the resource meter on Windows. It's 80% CPU use. Drops to 15% on hZP.cam.stopVideo. Let's look at the profiler.
Seems like the line that is taking up a lot of CPU usage in my code is lastFrame=squeeze(peekdata(obj.vid,1)); in the method getLastFrame of the camera class. This is called by the callback pointer.storeLastFrame, which runs whenever a frame is available.

Is there a more efficient way? There must be. e.g. imaqtool runs preview and this does not hose the CPU. The idea might be something like this:

% Create a GUI figure window
fig = figure('Name', 'Camera Feed GUI');

% Create axes for displaying camera feed
ax = axes('Parent', fig);

% Create video input object
vid = videoinput('winvideo', 1, 'MJPG_1280x720'); % Adjust parameters as needed

% Configure video input object
vid.FramesPerTrigger = 1; % Grab one frame per trigger
vid.TriggerRepeat = inf; % Continue acquiring frames until stopped
% Adjust other properties such as resolution, frame rate, etc.

% Start preview
preview(vid, ax);

@raacampbell
Copy link
Contributor Author

@raacampbell
Copy link
Contributor Author

raacampbell commented May 17, 2024

I test and find that with the original frame update system involving the listener, it is laggy confirming the sample calib. With the preview approach the lag has gone. It still uses a lot of CPU but maybe a fifth less than the current approach. The initial issue, however, is that when I implement it this way the axes are wiped and for some reason I can not start and stop the feed. So have to figure out those things.

Edit it's just:

>> stoppreview(hZP.cam.vid)
 
>> preview(hZP.cam.vid)

To reverse axes:

OUT.hAx.XDir='reverse'

@raacampbell
Copy link
Contributor Author

The dev_newpreview branch attempted to do the above, but it became very complicated because sample calibration was not honouring the image scale and caused chaos. So instead I switched to restricting the camera to 20 FPS (from 100) and the CPU is about 20 to 30% less after implementing this. 3d9bdaa If we continue to have issues with responsiveness, we can try doing the update in a separate thread or adding a button to disable the camera.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Known obvious issue Issues that users are likely to report as bugs
Projects
None yet
Development

No branches or pull requests

1 participant