How can I best log images from a DCAM camera at a specified frame rate while previewing the acquired images, or improve the performance of preview()?

9 views (last 30 days)
Hi,
I've been trying to write a program using the Image Acquisition toolbox that will do two things:
1. Log video from a camera to disk at a specified frame rate
2. Show a live preview of this video as it is being acquired
Unfortunately, my hardware (AlliedVision Pike F-145b) does not appear to have a configurable frame rate property. To address this, I wrote a timer function with a callback that executes a manual trigger on the camera. While this works perfectly without a live preview, calling the usual preview(vid) causes several frames to be dropped at frame rates that should be in reach of my camera. Here is that code:
% Prevents apparently bugged memory restrictions in OSX
imaqmex('feature','-limitPhysicalMemoryUsage',false);
framerate = 24;
frameInterval = 1/framerate;
% Create video input object.
vid = videoinput('dcam', 1, 'F7_Y8_1388x1038_mode0');
% Configure image brightness, ROI, and color space
src = getselectedsource(vid);
src.Shutter=(300);
vid.ROIPosition=[0, 0, 900, 900];
vid.ReturnedColorspace = 'grayscale';
% Configure triggers
triggerconfig(vid, 'manual');
vid.FramesPerTrigger = 1;
vid.TriggerRepeat = inf;
set(vid,'TimerPeriod',frameInterval);
vid.TimerFcn = {@tmp_trigger,0.05};
% Configure video logging
vid.LoggingMode = 'disk';
logfile = VideoWriter([sprintf('%s/VideoLog', '~/Desktop/frames'),'.avi'], 'Grayscale AVI');
logfile.FrameRate = framerate;
vid.DiskLogger = logfile;
vid.logging;
open(logfile)
frame = getsnapshot(vid); % get snapshot to warm up camera
imwrite(frame,[sprintf('%s/snapshot%06d', '~/Desktop/frames', 0),'.jpg'], 'jpg'); % save this image for an ROI preview
n_milliseconds = 30000;
preview(vid); % start live preview (performance penalty)
frame = getsnapshot(vid);
pause(2); % wait to allow warm=up
start(vid); % begin acquisition
trigger(vid) % trigger immediately without waiting for the first timer event
pause(n_milliseconds/1000); %acquire video for n_seconds
stop(vid); % stop acquisition
wait(vid, inf, 'logging'); % wait for the video log to fully populate with camera data
close(logfile); % stop writing to the logfile
flushdata(vid); % clear the memory of the camera
eventLog = vid.EventLog; % get event timing info
delete(vid)
clear vid
% Prepare and write the timing info for image acquisition to a file
for i = 1:length({eventLog.Data})
FlatStruct(i).Type = {eventLog(i).Type};
FlatStruct(i).Time = {datestr(eventLog(i).Data.AbsTime, 'mmmm dd, yyyy HH:MM:SS.FFF')};
FlatStruct(i).Frame = [eventLog(i).Data.FrameNumber];
end
struct2table(FlatStruct) % view the trigger data to assess performance
%writetable(struct2table(FlatStruct), [sprintf('%s/EventLog', '~/Desktop/frames'),'.csv']);
% A nested function that issues a camera trigger at the specified interval
function tmp_trigger(vid,events,maxDelay)
wait(vid,maxDelay,'logging')
trigger(vid)
end
At frame rates greater than 66% of the max frame rate of the camera (frame rates that should be achievable due to the low ROI), ~1.5% of the frames will drop.
I also tried putting image-by-image display instead of preview(vid) in the callback function like so:
hvpc = vision.VideoPlayer;
function tmp_trigger(vid,events,maxDelay,vplayer)
wait(vid,maxDelay,'logging')
trigger(vid)
img = getdata(vid, 1);
vplayer.step(img)
end
This also caused dropped frames.
I would happily accept dropped frames in the preview, it's more important for me to log all the frames.
Can anyone provide some tips on improving the performance of the live preview? I looked at the documentation for preview() hoping to find a configuration that would allow me to sacrifice some performance in favor of doing logging more faithfully, but there isn't much there.
Thanks!

Answers (0)

Community Treasure Hunt

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

Start Hunting!