%% Perform Webcam Image Acquisition in Parallel with Postprocessing
% This example shows how to perform frame acquisition from a webcam in parallel with data postprocessing.
% In the example, you use a parallel worker to perform image acquisition and then stream the data back to the client for postprocessing by using a DataQueue object.
% To perform postprocessing using workers instead of your MATLAB client, see Perform Image Acquisition and Parallel Image Processing.
%% Set Up Parallel Environment
% Start a parallel pool with one worker on the local cluster.

parpool('local',1);

%
% To send information back from the worker to the MATLAB client, create a DataQueue object.

D = parallel.pool.DataQueue;

% Create a figure object, and set 'Visible' to 'on' so that it opens outside of the live script. To display images every time they arrive from the DataQueue object, use afterEach.

fig = figure('Visible','on');
afterEach(D,@processDisp);

%
%% Fetch Data and Perform Postprocessing in Parallel
% Define the frequency of acquisition, that is, how many frames per second you want to pull out from the camera.

freq = 5;

% Select a value that takes into account how long postprocessing takes. Otherwise the video stream can significantly lag over time.
% To start data acquisition on the parallel worker, call parfeval and pass the acquisition function, the DataQueue object, and the acquisition rate as arguments.

f = parfeval(@getFrameFromCamera,0,D,freq);

% Acquire frames for a period of 30 seconds. This example applies a blurring filter as the postprocessing step and shows the original and processed frames side by side.

pause(30);

% To stop the video feed, cancel the acquisition.

cancel(f);

% For a more detailed example showing postprocessing on workers, see Perform Image Acquisition and Parallel Image Processing.
%
%% Define Helper Functions
% The getFrameFromCamera function connects to the webcam, then acquires image frames and sends them to the DataQueue object in an infinite loop.

function getFrameFromCamera(D,freq)
    cam = webcam;
    while true
        img = snapshot(cam);
       
        send(D,img);
        pause(1/freq);
    end
end

% The processDisp function postprocesses frames and displays the original and processed frames each time data arrives to the DataQueue object.

function processDisp(img)
    imgBlur = imgaussfilt(img,3);
    imshow([img, imgBlur],'Parent',gca)
end

% Copyright 2019 The MathWorks, Inc.