I am doing image processing and I want to calculate the variance of a histogram of pixel intensities.

The first method I have tried: The images store the pixels values using double precision numbers, however to make a histogram, they need to be scaled so that the can be grouped in to bins. For example into bins of 0 to 255.

And I get a histogram looking like this hist

I can then calculate variance in the usual way

$\mu = \frac{1}{n} \sum_x xf(x)$

$ \sigma^2 = \frac{1}{n} \sum_x {(x- \mu)^2 f(x)}$

But I have suspicions that this is not very usefull for comparing variances between different images. For example, when I get an image with a wider spread of pixel intensities, the histogram is scaled over a wider range. This means that pixels that would otherwise be grouped into a different bin, get placed in the same bin.

As you can see here squashed

It seems to defeat the purpose of a histogram to place most of the pixles into one or two bins.

Is this a job for kernel density estimation?

I need some way of comparing apples to apples.


Histograms are an estimate of the true probability distribution of intensity values. So you would like to compare probability distributions against each other.

There are plenty of ways to compare distributions, depending upon your application, that is, what your goal is and how calculating a distance fits in. OpenCV supports a couple of them.

For more possibilities you may check this paper (Comprehensive Survey on Distance/Similarity Measures between Probability Density Functions, Sung-Hyuk Cha).


I don't see how the second histogram has a wider spread, if anything it's less. Pixels go from 0-255, and if your pixels are saved as double precision, then you scaling them to fit into 0-255 won't change their distribution (much), unless you scale them wrong. If they end up in the same bin, then that's because they are almost the same. So the 2nd image really has from the look of it less pixels in the first place (smaller image size?), and more of these are condensed in the range from ~110-120.

You are using grey-scale images, right? Otherwise it'd be more than one channel (ie RGB color image has 3 channels (+Alpha if you're strict, but not important in this case)). And then you'd need to map it differently anyway.

If you want to compare using variance, try this:

Convert image to grey-scale.

Calculate its histogram.

Normalize histogram such that the sum of all Bin's values add up to 1. (ie divide each bin count by total amount of pixels).

Calc Mean = Sum(i=1 to N=#OfBins) i*hist(i)

Calc Variance = Sum(i=1 to N=#OfBins) (i-Mean)^2 * hist(i)

And then compare variances between two images (using same amount of bins and parameters).

However, you might want a better measure of similarity between two images.

As a start you could calculate Euclidean, Intersection and Chi-squared distance using the normalized histograms and get fancier afterwards.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.