How to apply certain action on struct fields?

2 visualizzazioni (ultimi 30 giorni)
Hello, I have a variable, "vidTMP", it's a structure.
It's movie frames. Each frame is 1080x1920x3 uint 8. Field name is cdata.
I'd like to perform "rgb2gray" on all of the frames in one code command. Is it possible?
Maybe "structfun"? I've tried, but seem to have some syntax error...
At the moment I'm using the following for-loop. Is there any more elegant alternative?
firstFrame = vidTMP.cdata;
vidTMP2 = zeros(size(firstFrame,1),size(firstFrame,2),length(vidTMP));
for i = 1 : length(vidTMP)
vidTMP2(:,:,i) = vidTMP(i).cdata(:,:,1);
end

Risposta accettata

Stephen23
Stephen23 il 30 Ago 2016
Modificato: Stephen23 il 30 Ago 2016
The structfun documentation clearly states that the input structure must be a scalar structure. Your structure has size 1x660, so it is definitely not a scalar structure.
However there are other simple ways to apply an operation to each element of your non-scalar structure. Lets start by defining some sample data:
% fake data in a non-scalar structure:
S(1).cdata = randi([0,255],10,20,3,'uint8');
S(2).cdata = randi([0,255],10,20,3,'uint8');
S(3).cdata = randi([0,255],10,20,3,'uint8');
S(4).cdata = randi([0,255],10,20,3,'uint8');
tmp = cellfun(@rgb2gray,{S.cdata},'Uni',0);
out = cat(3,tmp{:});
Or you could use arrayfun to perform some operation on each element of the structure (remember that each element is itself a scalar structure):
tmp = arrayfun(@(s)rgb2gray(s.cdata),S,'UniformOutput',false);
out = cat(3,tmp{:});
Note that if you don't have rgb2gray, then use this:
vec = reshape([0.2989,0.5870,0.1140],1,1,[]);
rgb2gs = @(rgb)sum(bsxfun(@times,vec,double(rgb)),3);
Also note these might be considered to be elegant solutions, but a loop is likely to be faster.

Più risposte (0)

Categorie

Scopri di più su Structures in Help Center e File Exchange

Tag

Community Treasure Hunt

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

Start Hunting!

Translated by