Perform Image Acquisition, Post Processing and plotting in parallel using SPMD

19 次查看(过去 30 天)
I want to perform the following tasks:
Worker 1 acquires a set of images. In this example, I replaced the image acquisition with the random generation of a uint8 matrix. After that, the acquired image is sent to Worker 2, which performs some post-processing. In this example, I used imgaussfilt with a pause to simulate some workload.
My goal is to have a code where Worker 1 can acquire images without any interruptions, and the latest captured frame is plotted in one figure while the latest post-processed figure is displayed in another figure. These figures should be updated continuously as long as the Frame Acquisition loop is running.
Initially, I thought the best solution would be to offload "plotting the latest figure" to Worker 3 and "plotting the latest post-processed picture" to Worker 4. However, I encountered an issue where I couldn't get any figures when I used "figure" and "imshow" within the spmd-block.
My latest workaround involves sending the images to the parallel.pool.DataQueue. The problem I'm facing is that plotting the images seems to block each other, causing the latest image and the latest post-processed image to be displayed sequentially. As a result, the refresh rate of the figure displaying the latest acquired image is constrained by the refresh rate of the post-processing.
Is it also correct to initiate the Image Acquisition Loop outside of the spmd-block, or is it better to call it within the worker (case 1)?
I am entirely new to parallel computing and grateful for any help!
This is my code:
FramesToLoop = 40;
if isempty(gcp('nocreate'))
parpool('Processes', 4); % You can adjust the number of workers as needed
end
D = parallel.pool.DataQueue;
D1 = parallel.pool.DataQueue;
afterEach(D,@(data) updatePlot(data));
afterEach(D1,@(data) updatePlot2(data));
for p = 1:FramesToLoop
spmd
switch spmdIndex
case 1
[img, AcquFPS] = GetFrameFromCamera();
send(D,img);
spmdSend(img,2,1);
case 2
B1 = spmdReceive('any',1);
[imgBlur] = postProcess(B1);
send(D1,imgBlur);
end
end
end
figure(5)
imshow([img{1},imgBlur{2}]) % only to view the latest captured and post-processed image
function [img, AcquFPS] = GetFrameFromCamera()
tic
img = uint8(randi([0,254],fliplr([1000,500])));
AcquFPS = 1/toc;
end
function [imgBlur] = postProcess(img)
imgBlur = imgaussfilt(img,3);
pause(0.2) % simulate workload
end
function updatePlot(img)
figure(1)
imshow(img)
drawnow
end
function updatePlot2(img)
figure(2)
imshow(img)
drawnow
end

采纳的回答

Varun
Varun 2023-10-25
Hi Cristian,
It looks like you want to plot latest captured image from worker 1 and latest post-processed image from worker 2 simultaneously without blocking with each other. Also, these figures should be updated continuously if the frame acquisition loop is running.
The initial approach, in which you discussed i.e. plotting the latest figure to Worker 3 and plotting the latest post-processed picture to Worker 4. However, you couldn't get any figures when you used "figure" and "imshow" within the spmd-block. This is because it is not recommended to use "figure" and "imshow" inside a worker pool when working with parallel computing in MATLAB.
In a parallel computing context, such as a worker pool, there is no guarantee that the worker has access to a display or that the figures will be visible. Instead, when working with parallel computing, it is more common to perform computations and data processing tasks on the workers, and then collect and visualize the results on the main MATLAB session.
So, to plot images inside the main pool using the functions "updatePool" and "updatePool2", make sure to declare "figure(1)" and "figure(2)" globally before the for loop as well, as shown below otherwise you can face issues with plotting images:
...
...
afterEach(D, @(data) updatePlot(data));
afterEach(D1, @(data) updatePlot2(data));
% Create figures outside the loop
figure(1);
figure(2);
for p = 1:FramesToLoop
...
...
By creating the figures globally outside the loop, you ensure that the figures exist before the "imshow()" function is called. This allows the images to be displayed correctly in the figures.
Now coming to your last question, it will not be a good idea to call image acquisition Loop within the worker as it will block post-processing loop in worker 2. First it will plot all the captured images of worker 1 and then it will plot all the post-processed images of worker 2.
Please refer to the following documentation to learn more about Parallel Computing Toolbox of MATLAB:

更多回答(0 个)

类别

Help CenterFile Exchange 中查找有关 Asynchronous Parallel Programming 的更多信息

产品


版本

R2023a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by