Acquire Images Using Parallel Workers
This example shows how to use the Parallel Computing Toolbox™ together with the Image Acquisition 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 Acquisition
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.
The 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.
mkdir("data\")
Start Image Acquisition on Parallel Worker
Create a parallel pool with one worker on your local machine using parpool
.
parpool('local',1);
Starting parallel pool (parpool) using the 'local' profile ... Connected to the parallel pool (number of workers: 1).
Run the captureVideo
function in your parallel worker using parfeval
. Since captureVideo
does not have any output, specify the number of output arguments as 0
.
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 running
.
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
.
wait(f);
Display the parfeval
future to confirm that its status is finished
.
disp(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 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"))
Helper Functions
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 acquisition to finish. wait(v); end
Callback Function to Save Images
The 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