Code covered by the BSD License  

Highlights from
CameraGUI

image thumbnail

CameraGUI

by

 

access all connected cameras, take snapshots, record streams, access and process frames in realtime

RealtimeProcess(camobj, capturetime, frameinterval, processinggroup, callbacksbuffer, checkinterval)
%this function depends on unixtime.m


function [abstimestamps] = RealtimeProcess(camobj, capturetime, frameinterval, processinggroup, callbacksbuffer, checkinterval)

if nargin<2
   error('You have to choose a camera and capture time!')
end
if nargin<3
    frameinterval = 1;
end
if nargin<4
    processinggroup = 1;
end
if nargin<5
    callbacksbuffer = 5;
end
if nargin<6
    checkinterval = 50; % milliseconds
end

capturetime = abs(capturetime);
frameinterval = abs(frameinterval);
processinggroup = abs(processinggroup);

% set global for circular data, framenr and timestamps arrays
% we preallocate an array for image data that we will use for a circular
% datadump; circlesize = number of callbacks that fit into data array
global circularsize;
circularsize = callbacksbuffer;
global circulardata;
global circularframenr;
global circulartimestamps;
circulardata = [];
circularframenr = [];
circulartimestamps = [];
% set globals for capturing timestamps in callback function
global framecounter; % counting frames that are stored in curtimestamps
% % not used anymore:
%global curframenr; % the camera may skip frames; so, i rather store all the frame numbers that the camera actually gives me
%global curtimestamps; % timestamps that the camera returns


framecounter = 0;

% signals next free frame position in circulardata to next callback
global nextfree;
nextfree = 1;

% signals next released highest frame number to worker
global releasedfr;
releasedfr = 0;

framerate = measureFrameRate (camobj,20);
% e.g. if we want to compress 30 seconds into 3 seconds, so
% only acquire every tenth frame: set(vid,'FrameGrabInterval',10);
% acquiring always starts with 1st frame per trigger, then skip (framegrabinterval - 1) frames, then
% next frame, and so on
set (camobj,'FrameGrabInterval',frameinterval);
framerate = framerate / frameinterval;

%available logging modes
loggingModes = set(camobj, 'LoggingMode');
disp ('available logging modes:')
disp (loggingModes)
disp ('---------------------------------------')

% Configure the logging mode to memory.
set(camobj, 'LoggingMode', 'memory');

% Verify the configuration.
currentLoggingMode = get(camobj, 'LoggingMode');
disp ('current logging mode:')
disp (currentLoggingMode)
disp ('---------------------------------------')


%set capturing length
numframes = round(capturetime * framerate);
if numframes == 0
    numframes = 1; 
end

% set frames per callback (fpf)
global fpf;
camobj.UserData = 1; %this is going to be our counter for FrameSave (per function callback, NOT per frame)
fpf = round(processinggroup); %how many frames per callback function (FrameSave)
if fpf == 0
    fpf = 1; 
end
%one more minor correction:
%we want capturing length to be a multiple of fpf
numframes = fpf * ceil(numframes/fpf);

%preallocate memory for timestamps storing
%curtimestamps = zeros(numframes*2,6);
%curframenr = zeros(1,numframes*2);

set(camobj,'FramesAcquiredFcn',{@FrameSave});
set(camobj,'FramesAcquiredFcnCount',fpf);
set(camobj,'FramesPerTrigger',numframes);
% no need for 'set(camobj,'Timeout',1);'

%set up abort button
mygui = openfig('quickguismall.fig','new'); hmygui = guihandles(mygui);
set(hmygui.togglebutton1,'String','Abort Capturing');
set(hmygui.togglebutton1,'ForegroundColor',[1 0 0]);
set(hmygui.figure1,'Name','Stop Capturing');

%start capturing
start(camobj);
starttime = [];
endtime = unixtime(clock()) + 3600; % a very high number, will be corrected below
disp(['capturetime (according to determined framerate): ',num2str(capturetime), ' seconds']);
abortcapture = false;
prevreleasedfr = 0;
totallostframes = 0;
try
hf = figure;
while unixtime(clock()) <= endtime && ~abortcapture
    if releasedfr > prevreleasedfr
        newframeind = find(circularframenr > prevreleasedfr & circularframenr <= releasedfr)';
        newframeind(:,2) = circularframenr(newframeind);
        sortnewframeind = sortrows(newframeind,2);
        numframes = size(sortnewframeind,1);
        if numframes < releasedfr - prevreleasedfr
            disp(['We just lost ',num2str(releasedfr-prevreleasedfr-numframes),' frames']);
            totallostframes = totallostframes + releasedfr-prevreleasedfr-numframes;
        end
        for ii = 1:numframes
            frameindex = sortnewframeind(ii,1);
            curframenr = sortnewframeind(ii,2);
            disp(['Processing frame ',num2str(curframenr)]);
            %curtimestamp = circulartimestamps(frameindex,:);
            %disp(num2str(curtimestamp));
            %curframedata = circulardata(:,:,:,thisfree:upperind) = data;
            curframedata = circulardata(:,:,:,frameindex); % datatype of circulardata is probably uint8
            
            % #############################################################
            % HERE DO YOUR IMAGE PROCESSING
            
            
            figure(hf);ih = image(curframedata);
            % #############################################################
        end
        prevreleasedfr = releasedfr;
    end

    if isempty(starttime)
        if releasedfr > 0
            starttime = unixtime(clock());
            endtime = starttime + capturetime + 2; % give it some extra time
        end
    end
    
    %{
    timecounter = unixtime(clock()) - starttime;
    disp(['seconds passed: ', num2str(floor(timecounter)), ' of ',num2str(capturetime)]);
    disp(['frames already acquired: ',num2str(camobj.FramesAcquired)]);
    disp('-------------------------------------------------------------')
    %}
    pause(checkinterval/1000);
    if get(hmygui.togglebutton1,'Value')==1
       abortcapture = true; 
    end
end
if abortcapture
    stop(camobj);
end
wait(camobj,Inf);
catch
    stop(camobj);
    msgbox('ERROR');
end
close (mygui);

set(camobj,'FramesAcquiredFcn',{},'FramesAcquiredFcnCount',0)

% Determine the number of frames acquired.
frsAcquired = camobj.FramesAcquired;
frsAcquired = framecounter; %we rather give the number of actually saved frames
%disp (strcat('total frames acquired: ',num2str(frsAcquired)))
disp (['number lost frames during image processing: ',num2str(totallostframes)]);

%{
%first we delete empty fields
curframenr(curframenr==0) = [];
curtimestamps(curtimestamps(:,1)==0,:) = [];
%now generate abstimestamps matrix
abstimestamps = [curframenr',unixtime(curtimestamps)];
save (destfiletimestamps, 'abstimestamps');
%}
abstimestamps = [];


function FrameSave(camobj,event)
global framecounter; % counts all frames; probably not really usefull
%global curtimestamps; % collect all timestamps in an array
%global curframenr; % collect real frame numbers in an array
global circulardata;
global circulartimestamps;
global circularframenr;

% only important for initializing array:
%-------------------
global circularsize;
global fpf;
%-------------------

% signals next free frame position in circulardata to next callback
global nextfree;

% signals next released highest frame number to worker
global releasedfr;

circularframes = fpf * circularsize;
[data,time,abstime] = getdata(camobj,camobj.FramesAcquiredFcnCount);
curlen = (length(time));
thisfree = nextfree;
if (thisfree + curlen - 1) > circularframes
    thisfree = 1;
end
nextfree = thisfree + curlen; % this may be too large, but then it will be corrected as thisfree during the next callback
framecounter = framecounter + curlen;

if isempty(circulardata)
    %height
    imgH = size(data,1);
    %width
    imgW = size(data,2);
    %colors
    imgB = size(data,3);
    % % frames
    %imgF = size(data,4);
    %datatype
    dt = class(data);
    circulardata = cast(zeros(imgH,imgW,imgB,circularframes),dt);
    circulartimestamps = zeros(circularframes,6);
    circularframenr = zeros(1,circularframes);
end

upperind = thisfree+curlen-1;
circulardata(:,:,:,thisfree:upperind) = data;
circulartimestamps(thisfree:upperind,:) = cell2mat({abstime(:).AbsTime}');
circularframenr(thisfree:upperind) = cell2mat({abstime(:).FrameNumber});
releasedfr = circularframenr(upperind);

%curtimestamps(curfrcounter+1:curfrcounter+curlen,:)=cell2mat({abstime(:).AbsTime}');
%curframenr(curfrcounter+1:curfrcounter+curlen)=cell2mat({abstime(:).FrameNumber});
camobj.UserData = camobj.UserData + 1; %we count, but dont use this counter in this script...

Contact us