[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 709
  • Last Modified:

how to calculate bitmap 's contrast

Experts

I am doing some image processing. i want to know how to calculate contrast
0
smallee
Asked:
smallee
  • 5
  • 4
  • 3
  • +2
3 Solutions
 
stefan73Commented:
Hi smallee,
Isn't there a graphics TA? Your question ist pretty much language-independent.

Cheers!

Stefan
0
 
grg99Commented:
This is a bit of a toughie.

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.

0
 
foodlebardleCommented:
// This calculates the contrast of the image:

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/xcount), sqrt(ycontrast/ycount));


0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
grg99Commented:
Well, that code computes *something*, but it's not what I'd call the "contrast".

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.



0
 
smalleeAuthor Commented:
Hi grg99
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
0
 
grg99Commented:
I'd compute a histogram of the pixel brightnesses, then start at both ends and throw away say 5 to 10% from each end, maybe  a bit more if the picture is noisy.

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

0
 
smalleeAuthor Commented:
Do you mean that Changing the RGB value to gray value

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"

0
 
foodlebardleCommented:

// 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);
0
 
grg99Commented:
Better, but not quite... You're still saying the contrast is proportional to the number of pixels away from the average.  So a black image with a 10x10 pixel white square will have by that algorithm,  1/100th the contrast of the same black background with a 100x100 white square.  IMHO neds a little more work....

0
 
foodlebardleCommented:
OK, whatever.  I think this answers smallee's question.
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.
0
 
smalleeAuthor Commented:
thx grg99 and foodlebardle

Give me some time to digest the answer

i will accept the answer as soon as possible
0
 
grg99Commented:
hard to describe without graphics, but here goes:

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%:***********************************  ( a lot of medium gray pixels )
... 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.


0
 
smalleeAuthor Commented:
Thx again

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

But give me some time for testing
0
 
jhshuklaCommented:
>>
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)
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

  • 5
  • 4
  • 3
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now