Art
Art

Reputation: 1335

Calculating pair correlation for image

I have a binary image, lets say 512x512px. I want to calculate pair correlation g(x). So far I'm doing it in as primitive as inefective way, line by line:

function Cr = pairCorr(image)

domains = imread(image); % read image
domains(domains>0) = 1;  % make sure its binary by setting 1 to values > 0
size = length(domains(:, 1)); % image size

for i=1:size
    line = domains(:, i); % take one line...
    for j=1:size % and for each distance...
        s = line(1:end-size+j);
        Cr(i, j) = mean(s); %...calculate Cr as mean  
    end
end

Cr = mean(Cr); % average all lines

Any idea how to do it a bit faster? Thanks!

Upvotes: 1

Views: 1548

Answers (1)

Dan
Dan

Reputation: 45752

Your code (from the loops on) seems to be to be the same as

Cr = mean(bsxfun(@rdivide, cumsum(domains), (1:n)'));

where my n is your size. Don't use size as a variable name in matlab as it's a very useful function. For example you went length(domains(:,1)) but you could have gone size(domains, 2)

What is my code doing:

cumsum(domains) finds a cumulative sum down each column. So that's like doing your for j=1:size s = line(1:end-size+j); Cr(i, j) = mean(s); end in one shot for the whole matrix. But with sum instead of mean. So to convert a vector of cumulative sums to means we must divide each element by the column number. So we want to divide by the vector 1:n. bsxfun allows us to perform an operation on each slice of a dimension of a matrix. So in the 2D case on each column it allows to divide (that's the @rdivide) by another constant column, i.e. (1:n)'.

Here is a test showing equivalence:

n = 512;
A = rand(n);
A(A > 0.5) = 1;
A(A <= 0.5) = 0

tic
Cr1 = mean(bsxfun(@rdivide, cumsum(A)', (1:n)));
toc

tic
for i=1:n
    line = A(:, i); 
    for j=1:n 
        s = line(1:end-n+j);
        Cr2(i, j) = mean(s);
    end
end
Cr2 = mean(Cr2)
toc  

mean(mean(Cr1 == Cr2))

Results:

Elapsed time is 0.016396 seconds.
Elapsed time is 75.2006 seconds.

So although this is only for 1 run it gives you a speed up of like 4500 which is pretty good I think

Upvotes: 1

Related Questions