What is a vectorized way to calculate variance of an image patch

3 views (last 30 days)
I have a 560*560*3 image file, I want to divide the image into many small 8*8 patches, then calculate variance of each patch. What is a vectorized way to calculate variance of each image patch ?
  2 Comments
Walter Roberson
Walter Roberson on 30 May 2015
How do you want to calculate variance of color? If you have an 8 x 8 x 3 subsection, S, representing color, do you want var(S(:)), which treats all the pixel components equally? Or do you want variance of the grayscale equivalent, and thus variance of brightness? Or do you want to convert to HSL and do variance of Hue? Or.... ?
Victor Yi
Victor Yi on 31 May 2015
I want to calculate the variance of each R, G, and B of the 8*8*3 image patch, 3 variance values for one patch.

Sign in to comment.

Accepted Answer

Roger Stafford
Roger Stafford on 31 May 2015
Edited: Roger Stafford on 31 May 2015
You do need to answer Walter's question. Here are two possibilities:
1) From your I = 560 x 560 x 3 array, each 8 x 8 x 3 block will produce a 1 x 1 x 3 array of variances giving a 70 x 70 x 3 result. That is, each of the three colors has its separate page of 70 x 70 variances in a 3D result.
p = 8; q = 8; % Each block is p x q
m = 70; n = 70; c = 3; % There are m x n x c blocks
r = 0:(p*q*m*n*c-1);
s = 1+r+p*(m-1)*floor(r/p)-p*(m*q-1)*floor(r/(p*q))...
+p*m*(q-1)*floor(r/(p*m*q));%The required permutation
V = reshape(var(reshape(I(s),p*q,[])),m,n,c); % Variances
2) Your I array is 560 x 560 of grey-level values. Each 8 x 8 block will produce a single variance giving a 2D 70 x 70 result.
p = 8; q = 8; % Each block is p x q
m = 70; n = 70; % There are m x n blocks
r = 0:(p*q*m*n-1);
s = 1+r+p*(m-1)*floor(r/p)-p*(m*q-1)*floor(r/(p*q))...
+p*m*(q-1)*floor(r/(p*m*q));%The required permutation
V = reshape(var(reshape(I(s),p*q,[])),m,n); % Variances
  2 Comments
Victor Yi
Victor Yi on 31 May 2015
Thank you ! the first sample code solved the problem, but I still didn't figure out the meaning of the sample code. can you explain what is the meaning of the variable "s" and how did you use it to calculate variance.
Walter Roberson
Walter Roberson on 31 May 2015
var() of a lot of values that are not consecutive can be handled by moving the values so that they are consecutive and then taking the variance. Roger builds "s" as a list of the indices of elements that need to go together. It is a clever approach but not readable at all in the form written.

Sign in to comment.

More Answers (2)

Image Analyst
Image Analyst on 31 May 2015
You can use blockproc() (in the Image Processing Toolbox) to calculate the variance of each small tile of an image in a line or two of code since the function is meant for this purpose. Run my attached demos for an example.

Matt J
Matt J on 31 May 2015
Another approach to consider is stdfilt(), which will compute standard deviation in a sliding window fashion rather than a tiled fashion. This is more computation than you need. However, if stdfilt is sufficiently code-optimized, it might be worth it.
  3 Comments
Image Analyst
Image Analyst on 1 Jun 2015
And, if you want to do your own custom function with whatever crazy thing you can imagine, then you can use nlfilter(). It's like conv2(), imfilter(), stdfilt(), entropyfilt(), etc. except that you get to define your own custom code to apply at each filter window location.

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!