Isn't there a graphics TA? Your question ist pretty much language-independent.

Cheers!

Stefan

Solved

Posted on 2004-11-11

Experts

I am doing some image processing. i want to know how to calculate contrast

I am doing some image processing. i want to know how to calculate contrast

14 Comments

Isn't there a graphics TA? Your question ist pretty much language-independent.

Cheers!

Stefan

You could find the brightest pixel, the dimmest, and compute the contrast as the relative ratio of the two.

But then what if the picture is very low contrast, except for one black and one white pixel?

A better way would be to compute the standard deviation of the pixels. A bit time consuming but probably much more accurate.

vector<int> grayscale(width*height);

// fill image here

int x, y;

double xcontrast=0;

double ycontrast=0;

int xcount=0;

int ycount=0;

for (y=0; y<height; y++) {

for (x=0; x<width-1; x++) {

double xdiff = grayscale[y*width+x] - grayscale[y*width+x+1];

xcontrast += xdiff*xdiff;

xcount++;

}

}

for (y=0; y<height-1; y++) {

for (x=0; x<width; x++) {

double ydiff = grayscale[y*width+x] - grayscale[(y+1)*width+x];

ycontrast += ydiff*ydiff;

ycount++;

}

}

return hypot(sqrt(xcontrast/xcoun

It's more like the average rate of change. An image of alternating horizontal lines of 50% and 51% white (what most people would consider VERY LOW contrast) is going to give a much higher reading than an image that goes from 0 to 100% white from top to bottom. Not quite most people's definition of contrast.

Then what way should be better for calculating contrast

Actually, i want to split a bitmap into a number of n*n pixels region

and calculate the contrast of each region to find the max contrast region

Then the span between those two points is a pretty good indication of the contrast.

Gray = 0.3*Red + 0.59*Green + 0.11*Blue

then find the max and min gray value

However, I don't understand what mean "throw away say 5 to 10% from each end"

// This calculates the contrast of the image:

// Locality is not considered.

// This meets all objections by grg99...

vector<int> grayscale(width*height);

// fill image here

int n = width*height;

int i;

double sum=0;

for (i=0; i<n; i++) sum += grayscale[i];

double avg = sum / n;

double contrast;

for (i=0; i<n; i++) {

double diff = grayscale[i] - avg;

contrast += diff*diff;

}

return sqrt(contrast/n);

If you want to tweak these algorithms to make one you recommend to smallee over mine then feel free to do so, but these basic methods answer the question.

Give me some time to digest the answer

i will accept the answer as soon as possible

Build a histogram, a count of how many pixels have each level of gray. Maybe use 100 bins.

You'll end up with something like:

0%:*** ( three black pixels )

1%:***** ( five very dark gray pixels )

... and so on, up to:

50%:**********************

... and so on, up to:

99%:******* (maybe 7 almost-white pixels )

100%: *** ( a few totally white pixels )

--------------------------

Now let's say there are 1000 total pixels.

I'd throw away the bottom 5%, as they're probably black noise pixels, same with top 5%.

So you start at 0% and keep counting pixels up the percentages until you've seen 5% of the pixels.

Take that percentage as "most dark".

Start at 100% too and count down 5% of the pixels, that will toss out a lot of white noise.

Call that the "most white" percentage.

The difference between those two will be one measure of contrast.

I think i should increase the pts from your great help (grg99 and foodlebardle )

But give me some time for testing

I'd throw away the bottom 5%, as they're probably black noise pixels, same with top 5%.

So you start at 0% and keep counting pixels up the percentages until you've seen 5% of the pixels.

Take that percentage as "most dark".

Start at 100% too and count down 5% of the pixels, that will toss out a lot of white noise.

Call that the "most white" percentage.

The difference between those two will be one measure of contrast.

<<

what if there are only black and white pixels? or for that matter one white pixel on black background. pixels should never be classified as noise but should be corrected if their value is within avg(neighbors) +/- noiselevel. then we can use (max-min) as contrast.

so the algo would be like this:

determine noise level:

process the image through a highpass filter.

take the median of absolute values as noise level

remove noise

if difference between pixel and avg of neighbors is within noise level, apply correction

use (max-min) as contrast

apply correction:

correction = |pixel value - avg|*(noise level - |pixel value - avg|)

corrected value = pixel value + correction * sign(pixel value - avg)

By clicking you are agreeing to Experts Exchange's Terms of Use.

Join the community of 500,000 technology professionals and ask your questions.

Connect with top rated Experts

**10** Experts available now in Live!