Vectorizing nested for loops

Hi,
I am having a few issuing trying to vectorise multiple nested for loops. This application is video and i am looping through each pixel in each line of each frame of all the frames.
for l=1:nFrames
currentVFrame = read(liveVid, l); % Read in next frame
alphaVFrame = zeros(vidHeight, vidWidth, 3, 'uint8'); % create and then reset to 0
for k = 1:3
for i=1:vidHeight
for j=1:vidWidth
if(currentVFrame(i,j,k) == 254) % 254 = green screen
alphaVFrame(i,j,k) = 000; % Set to transparent instead
else
alphaVFrame(i,j,k) = currentVFrame(i,j, k); % Keep original file info
end
end
end
end
%imshow(alphaVFrame); % Show a preview of trhe current frame
mov(l).cdata = im2uint8(alphaVFrame); % Write the frame to our mov structure (int)
writeVideo(OutputVideo, alphaVFrame); % write the frame to the video file (ext)
end
I have tried to vectorise it following the example written on this post:
[i,j] = ndgrid(1:vidHeight*vidWidth);
r = reshape(a(i)+a(j), [nFrames, 3, VidHeight, VidWidth]);
But I get an error:
Maximum variable size allowed by the program is exceeded.
Error in ndgrid (line 63)
varargout{1} = x(:,ones(size(y)));
Can anyone point me in the right direction? I'm using Matlab R2013a.

 Accepted Answer

The post you linked does not apply to what you're doing. The simplest thing is to use matrix operations on your frames instead of your three inner loops:
for frame = 1:nframes %why use a meaningless letter instead of a meaningful name?
currentVFrame = read(liveVid, frame);
alphaVFrame = currentVFrame; %copy frame to output
alphaVFrame(alphaVFrame == 254) = 0; %and replace green screen with transparent?
%imshow(alphaVFrame); % Show a preview of trhe current frame
mov(frame).cdata = im2uint8(alphaVFrame); % Write the frame to our mov structure (int)
writeVideo(OutputVideo, alphaVFrame); % write the frame to the video file (ext)
end
I'm puzzled by your comment though %254 = green screen, this is only true on the green channel, ( k==2) but you're doing your test on all three colour channels.

5 Comments

That's great thanks for your quick response Guillaume.
In response to your question, you are right. I do not need to check all three channels when I am only looking at the green content, so in my code above you could just check the green channel, as you rightly said, when k==2.
nFrames is short for Number of Frames, apologies if that was confusing.
The code you've posted and my replacement will also set red or blue to 0 when they are 254. If you just want to set pixels to 0 when just green is 254, then:
%to set all three channels to 0:
alphaVFrame(repmat(alphaVFrame(:, :, 2) == 254, [1 1 3])) = 0;
%to just set green to 0:
green = alphaVFrame(:, :, 2);
green(green == 254) = 0;
alphaVFrame(:, :, 2) = green;
My comment about the variable name was about the l which does not mean anything. frame is a much better name. nframes is fine as a variable name.
Let me just rephrase what you've said to ensure I understand.
To set all the colours (RGB) to 0 when green (and only green) is equal to 254 I would use:
%to set all three channels to 0:
alphaVFrame(repmat(alphaVFrame(:, :, 2) == 254, [1 1 3])) = 0;
To set only the colour that is equal to 254 to 0 (i.e. if blue is equal to 254 then set to 0, but leave green and red alone) I would use:
alphaVFrame(alphaVFrame == 254) = 0;
And finally, to check only green, and set only green to 0 when it's equal to 254 I would use your final snippet of code:
%to just set green to 0:
green = alphaVFrame(:, :, 2);
green(green == 254) = 0;
alphaVFrame(:, :, 2) = green;
Yes, exactly.
Fantastic, thank you for your help Guillaume.

Sign in to comment.

More Answers (0)

Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

Asked:

on 10 Mar 2015

Commented:

on 10 Mar 2015

Community Treasure Hunt

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

Start Hunting!