Code covered by the BSD License  

Highlights from
CameraGUI

image thumbnail

CameraGUI

by

Georg D (view profile)

 

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