Ujjayanta Bhaumik
Ujjayanta Bhaumik

Reputation: 83

How does one calculate the integral image from original?

I tried separating the individual channels of the image and then calculate using the recursive function. At the end, I joined the three channels:

function [ii] = computeIntegralImage(image)
%function to compute integral from original image
iip=zeros(size(image,1)+1,size(image,2)+1);
jjp=zeros(size(image,1)+1,size(image,2)+1);
kkp=zeros(size(image,1)+1,size(image,2)+1);

for i=2:size(iip,1)
    for j=2:size(iip,2)
        iip(i,j)=image(i-1,j-1,1)+iip(i,j-1)+iip(i-1,j)-iip(i-1,j-1); 
    end
end

for i=2:size(jjp,1)
    for j=2:size(jjp,2)
        jjp(i,j)=image(i-1,j-1,2)+jjp(i,j-1)+jjp(i-1,j)-jjp(i-1,j-1); 
    end
end

for i=2:size(kkp,1)
    for j=2:size(kkp,2)
        kkp(i,j)=image(i-1,j-1,3)+kkp(i,j-1)+kkp(i-1,j)-kkp(i-1,j-1); 
    end
end

ii= cat(3,iip,jjp,kkp);

The matlab output for function integralImage is completely white:

Matlab Output

My output is a colorful image:

My Output

Upvotes: 0

Views: 322

Answers (1)

Cris Luengo
Cris Luengo

Reputation: 60645

The integral image can be easily computed by first integrating over one axis, then integrating the result over the other axis. This 1D integral is computed with cumsum:

out = cumsum(image,1);
out = cumsum(out,2);

Note that if image is of an integer type, this is likely going to lead to overflow. You should convert such an array to double first.

Finally, to display the result you need to use

imshow(out,[])

otherwise you don’t see the full range of the data, and anything above 1 becomes white, as you saw with MATLAB’s result.


Regarding your code:

The problem is overflow. Convert the value taken from input to double first. In MATLAB, uint8(150)+150 == uint8(255). This leads to alternating rows and columns like you see: one step you subtract some large value from the partial sums, leading to a small value, the next step you subtract a small value leading to a large value, etc.

At first I was confused by your first row and column in the output, which remain at 0. But then I noticed that the output is one larger than the input, and you use this first column to avoid special cases. Consider cropping the first row and column from your output.

Regarding loop order: It is faster when the inner loop is over the first dimension, as then the data is accessed in storage order and therefore uses the cache better. This should not affect the result, just the timing.

Upvotes: 1

Related Questions