Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are some methods to analyze image brightness using Python?

I'd like some advice on performing a simple image analysis in python. I need to calculate a value for the "brightness" of an image. I know PIL is the goto library for doing something like this. There is a built-in histogram function.

What I need is a "perceived brightness" values I can decide if further adjustments to the image are necessary. So what are something of the basic techniques that will work in this situation? Should I just work with the RGB values, or will histogram give me something close enough?

One possible solution might be to combine the two, and generate average R,G,and B values using the histogram, then apply the "perceived brightness" formula.

like image 788
cmcginty Avatar asked Aug 16 '10 05:08

cmcginty


People also ask

How do you calculate the mean brightness of an image?

It's generally the same for "brightness" of an image, "loudness" of a sound signal, etc. Some ideas of what you can use as a generic "brightness" is: Average value of all the pixels (i.e. sum up all the brightnesses of all the pixels, then divide by total amount of pixels, i.e. width * height).

How do you find the contrast of an image in Python?

Here is one measure of contrast: Michelson contrast and how to compute it in Python/OpenCV/Numpy. Low contrast is near zero and high contrast is near one. Use the Y (intensity) channel from YUV or YCbCr or alternately the L channel from LAB or even just convert the image to grayscale and use that.

How do I adjust the brightness of an image in OpenCV?

Increasing the Brightness using OpenCV is very easy. To increase the brightness, add some additional values with each channel, and the brightness will be increased. For example, BRG images have three channels blue (B), green (G) and red(R). That means the current value of a pixel will be (B.


2 Answers

Using the techniques mentioned in the question, I came up with a few different versions.

Each method returns a value close, but not exactly the same as the others. Also, all methods run about the same speed except for the last one, which is much slower depending on the image size.

  1. Convert image to greyscale, return average pixel brightness.

    def brightness( im_file ):    im = Image.open(im_file).convert('L')    stat = ImageStat.Stat(im)    return stat.mean[0] 
  2. Convert image to greyscale, return RMS pixel brightness.

    def brightness( im_file ):    im = Image.open(im_file).convert('L')    stat = ImageStat.Stat(im)    return stat.rms[0] 
  3. Average pixels, then transform to "perceived brightness".

    def brightness( im_file ):    im = Image.open(im_file)    stat = ImageStat.Stat(im)    r,g,b = stat.mean    return math.sqrt(0.241*(r**2) + 0.691*(g**2) + 0.068*(b**2)) 
  4. RMS of pixels, then transform to "perceived brightness".

    def brightness( im_file ):    im = Image.open(im_file)    stat = ImageStat.Stat(im)    r,g,b = stat.rms    return math.sqrt(0.241*(r**2) + 0.691*(g**2) + 0.068*(b**2)) 
  5. Calculate "perceived brightness" of pixels, then return average.

    def brightness( im_file ):    im = Image.open(im_file)    stat = ImageStat.Stat(im)    gs = (math.sqrt(0.241*(r**2) + 0.691*(g**2) + 0.068*(b**2))           for r,g,b in im.getdata())    return sum(gs)/stat.count[0] 

Update Test Results I ran a simulation against 200 images. I found that methods #2, #4 gave almost identical results. Also methods #3, #5 were also nearly identical. Method #1 closely followed #3, #5 (with a few exceptions).

like image 116
cmcginty Avatar answered Oct 04 '22 15:10

cmcginty


Given that you're just looking for an average across the whole image, and not per-pixel brightness values, averaging PIL's histogram and applying the brightness function to the output seems like the best approach for that library.

If using ImageMagick (with the PythonMagick bindings), I would suggest using the identify command with the "verbose" option set. This will provide you with a mean value for each channel, saving you the need to sum and average a histogram — you can just multiply each channel directly.

like image 31
Andrew Avatar answered Oct 04 '22 15:10

Andrew