Main Content

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