Python: Normalize image exposure

Histogram equalisation works surprisingly well for this kind of thing. It's usually better for photographic images, but it's helpful even on line art, as long as there are some non-black/white pixels.

It works well for colour images too: split the bands up, equalize each one separately, and recombine.

I tried on your sample image:

after hist equal

Using libvips:

$ vips hist_equal sample.jpg x.jpg

Or from Python with pyvips:

x = pyvips.Image.new_from_file("sample.jpg")
x = x.hist_equal()

It's very hard to say if it will work for you without seeing a larger sample of your images, but you may find an "auto-gamma" useful. There is one built into ImageMagick and the description - so that you can calculate it yourself - is:

Automagically adjust gamma level of image.

This calculates the mean values of an image, then applies a calculated -gamma adjustment so that the mean color in the image will get a value of 50%.

This means that any solid 'gray' image becomes 50% gray.

This works well for real-life images with little or no extreme dark and light areas, but tend to fail for images with large amounts of bright sky or dark shadows. It also does not work well for diagrams or cartoon like images.

You can try it out yourself on the command line very simply before you go and spend a lot of time coding something that may not work:

convert Tribunal.jpg -auto-gamma result.png

enter image description here

You can do -auto-level as per your own code beforehand, and a thousand other things too:

convert Tribunal.jpg -auto-level -auto-gamma result.png