Vectorize calculating a co-variance matrix for every RGB pixel in an image

4 views (last 30 days)
Hi, I am looking to calculate a variance-covariance matrix for every pixels RGB value in an image for each cluster, k. I then sum the variance-covariance matrices over all pixels and normalize it resulting in k variance-covariance matrices.
I currently have this in a for loop which is very slow, so I was wondering would anyone have any idea as to how to vectorize the 'for count4=1:n...' loop?
image=reshape(image,height*width,3);
%posterior is an n*k matrix where n is the number of pixels and k %is the number of classes holding the probability of pixel n %belonging to cluster k
for count3=1:k
%calculate new weights
newWeights(count3)=1/m*n*sum(posterior(:,count3),1);
%calculate new mu
postRepMat=repmat(posterior(:,count3),1,3);
newMu(count3,:)=sum(postRepMat.*image)/sum(posterior(:,count3));
%calculate new sigma
%NB Formula is from matlab cov.m file
%indivdual sigma needed as calculate a covariance matrix for each
%RGB observation
individualSigma=zeros(3,3,n);
%subtract new mu from image
xc = bsxfun(@minus,image,newMu(count3,:));
%create cov matrix,
%create individual covariance matrix for each observation
for count4=1:n
individualSigma(:,:,count4)=(xc(count4,:)'*xc(count4,:))*posterior(count4,count3);
end
newSigma(:,:,count3)=sum(individualSigma,3)/sum(posterior(:,count3));
end
regards, John

Answers (2)

Andrei Bobrov
Andrei Bobrov on 17 Jun 2011
C = arrayfun(@(i1)xc(i1,:)'*xc(i1,:)*posterior(i1,count3),1:n,'un',0);
individualSigma = cat(3,C{:});
However, one line
individualSigma = reshape(cell2mat(arrayfun(@(i1)xc(i1,:)'*xc(i1,:)*...
posterior(i1,count3),1:n,'un',0)),3,3,[]);
  2 Comments
John
John on 20 Jun 2011
Hi Andrei, thanks for this response. Unfortunately it is more computationally expensive than the original approach using for loops. For an RGB image with 420360 pixels (n), a for loop takes 21 seconds whilst the methods using arrayfun take 40 and 43 seconds respectively.
regards,
John
Andrei Bobrov
Andrei Bobrov on 20 Jun 2011
Of course with large arrays loop 'for ... end' functions more effective then 'arrayfun' and 'cellfun', ie I showed how not to do...

Sign in to comment.


Sean de Wolski
Sean de Wolski on 20 Jun 2011
Reshape your matrix so that it lies along the 3rd dimension both as a column-slice and a row-slice, then multiply directly using mtimesx.

Community Treasure Hunt

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

Start Hunting!