Acquire Images Using Parallel Workers
This example shows how to use the Parallel Computing Toolbox™ together with the Image Acquisiton Toolbox™ to acquire and save images in a separate MATLAB® worker.
Doing so allows you to perform other operations in the main MATLAB worker with minimal impact on the image acquisition. As a result, your image acquisition is more consistent and you can run more CPU-intensive operations in parallel on multicore CPUs.
Set Up Image Acquistion
This example uses the
parfeval function from the Parallel Computing Toolbox to asynchronously execute a specified function. You can run the specified function in the background of your main MATLAB worker without waiting for it to complete. For more information about this function, see
parfeval (Parallel Computing Toolbox).
Create a function called
captureVideo to execute on the parallel MATLAB worker. This function creates a new
videoinput object and sets the
FramesAcquiredFcn property. It then configures the frames to acquire and starts the acquisition. See the
captureVideo function at the end of this example. You can modify
captureVideo to fit your image acquisition needs and setup.
captureVideo function sets the
FramesAcquiredFcn property to a handle to the
saveImages callback function. The
saveImages function saves acquired images to a folder in your current working directory. See the
saveImages function at the end of this example.
Before you start the image acquisition, create a folder called
data, where the parallel worker saves your acquired images.
Start Image Acquisition on Parallel Worker
Create a parallel pool with one worker on your local machine using
Starting parallel pool (parpool) using the 'local' profile ... Connected to the parallel pool (number of workers: 1).
captureVideo function in your parallel worker using
captureVideo does not have any output, specify the number of output arguments as
f = parfeval(@captureVideo,0)
f = FevalFuture with properties: ID: 4 Function: @captureVideo CreateDateTime: 13-Jan-2021 11:58:35 StartDateTime: 13-Jan-2021 11:58:35 Running Duration: 0 days 0h 0m 0s State: running Error: none
The output shows that the status of the
parfeval future is
If you want to block MATLAB until
parfeval completes, you can use the
wait function on the future
f. Using the wait function is useful when subsequent code depends on the completion of
parfeval future to confirm that its status is
FevalFuture with properties: ID: 4 Function: @captureVideo CreateDateTime: 13-Jan-2021 11:58:35 StartDateTime: 13-Jan-2021 11:58:35 Running Duration: 0 days 0h 0m 15s State: finished (unread) Error: none
Your images are acquired and saved to the
data folder in your current working directory.
Shut Down Parallel Pool
When you finish working with the parallel pool, clear the future and shut down the parallel pool.
clear f delete(gcp("nocreate"))
Function to Capture Video
The parallel worker executes the
captureVideo function. This function creates a
videoinput object and sets the appropriate properties. You can modify it to fit your image acquisition needs.
function captureVideo() % Create videoinput object. v = videoinput('winvideo'); % Specify a custom callback to save images. v.FramesAcquiredFcn = @saveImages; % Specify the number of frames to acquire before calling the callback. v.FramesAcquiredFcnCount = 60; % Specify the total number of frames to acquire. v.FramesPerTrigger = 120; % Start recording. start(v); % Wait for the acquision to finish. wait(v); end
Callback Function to Save Images
captureVideo function sets the
saveImages callback as the
FramesAcquiredFcn for the
videoinput object. This function reads the number of frames specified by the
FramesAcquiredFcnCount from the buffer and saves them to the
data folder. You can modify this callback to fit your needs.
function saveImages(src,obj) % Calculate the total frame number for each frame, % in order to save the files in order. currframes = src.FramesAcquired - src.FramesAcquiredFcnCount; % Read images from the videoinput buffer. imgs = getdata(src,src.FramesAvailable); % Save each image to a file in order. for i = 1:src.FramesAcquiredFcnCount imname = "data\img_" + (currframes + i) + ".TIFF"; imwrite(imgs(:,:,:,i),imname); end end