Use Parfor on a greenscreen picture

조회 수: 1 (최근 30일)
Adnan Faek
Adnan Faek 2021년 4월 29일
댓글: Edric Ellis 2021년 5월 4일
I have this piece of code, which compares the pixels of a picture with a greenscreen background. If a pixel with a higher green value than the value of the threshold is found, the pixel has to be replaced with a pixel of another picture
function [outPic] = thresholdFilter(green_pic,background, threshold)
[m,n,p] = size(green_pic);
outPic = green_pic;
tic
for i = 1:m
for k = 1:n
if green_pic(i,k,2) >= threshold;
outPic(i,k,1) = background(i,k,1);
outPic(i,k,2) = background(i,k,2);
outPic(i,k,3) = background(i,k,3);
end
end
end
toc
end
Now, i'm trying to reduce the execution time by using parfor. However, when i display the picture, the background is still unedited and it only shows the greenscreen picture.
function [outPic] = thresholdFilter2_0(green_pic,background, threshold)
[m,n,p] = size(green_pic);
outPic = green_pic;
tic
parfor i = 1:m
pic = green_pic;
for k = 1:n
if green_pic(i,k,2) >= threshold;
pic(i,k,1) = background(i,k,1);
pic(i,k,2) = background(i,k,2);
pic(i,k,3) = background(i,k,3);
end
end
outPic = pic(i,:,:);
end
toc
end
How can i get the same results as the first example by using Parfor ?
  댓글 수: 1
Daniel Pollard
Daniel Pollard 2021년 4월 29일
Is there any reason you can't reshape the array into a 1D array, do your thresholding process, then reshape it back to its original shape? That way you could vectorise the code, removing the need for loops at all, and be much cleaner and more efficient.
Also read up on logical indexing. You can get rid of that if statement pretty easily.

댓글을 달려면 로그인하십시오.

채택된 답변

Edric Ellis
Edric Ellis 2021년 4월 30일
The comment on your question by @Daniel Pollard is probably the most productive way forward. But to answer your parfor query specifically - the problem here is that inside the parfor loop, outPic is being treated as a "loop temporary variable". To make a value available after the parfor loop, it has to be either a sliced or a reduction output.
Your original for loop is very close to working as a parfor loop. The only tweak necessary is to make a single assignment into outPic to satisfy the constraints for a sliced output variable.
% Dummy data:
green_pic = rand(10,10,3);
background = rand(10,10,3);
threshold = 0.5;
% Very slightly modified code:
[m,n,p] = size(green_pic);
outPic = green_pic;
parfor i = 1:m
for k = 1:n
if green_pic(i,k,2) >= threshold;
% Make a single assignment into outPic so that
% it can be "sliced"
outPic(i,k,:) = background(i,k,:);
end
end
end
disp('Success!');
Success!
Of course, the vectorised way to do this is as follows:
% Dummy inputs
green_pic = rand(10,10,3);
background = rand(10,10,3);
threshold = 0.5;
[m,n,p] = size(green_pic);
% Starting point for outPic
outPic = green_pic;
% Find all locations where threshold is exceeded. exceedsThreshold will be
% m-by-n logical array.
exceedsThreshold = green_pic(:,:,2) > threshold;
% We want to copy all planes of "background" into "outPic", so we need
% to duplicate "exceedsThreshold" into the third dimension
exceedsThreshold = repmat(exceedsThreshold, 1, 1, p);
% Copy appropriate pieces of background
outPic(exceedsThreshold) = background(exceedsThreshold);
  댓글 수: 2
Adnan Faek
Adnan Faek 2021년 5월 1일
Thank you very much!
However i was expecting a gain in comparison with the function that doesn't use parfor. Instead it takes longer to perform now(0.028239 seconds vs. 2.335178 seconds). I'll try to find a solution to this.
Edric Ellis
Edric Ellis 2021년 5월 4일
I'm not really surprised that parfor is slower than for in this case. There are overheads to running in parfor - specifically you have to transfer the data to different processes to operate on it, and then transfer it back. In this case, the work you're doing is much less time-consuming than the transfer. I suspect you will have more luck trying to use the vectorised approach.

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

Community Treasure Hunt

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

Start Hunting!

Translated by