0

I would like to implement a tool to adjust the brightness of a RGB image, which is simply a (N, M, 3)-shaped numpy array of dtype uint8.

The algorithm is really simple, I'm just adding an integer in range [-255, 255] to all pixels of my images.

Unfortunately, I also need to truncate the resulting pixel value to stay in range [0, 255], and numpy makes the array overflow when I'm adding the value.

Is there a way to add the brightness and take care of truncating the result without creating an intermediary array or using an ugly loop?

I'm working with large images, so I need to be efficient.

kmario23
  • 57,311
  • 13
  • 161
  • 150
PiRK
  • 893
  • 3
  • 9
  • 24
  • np.clip([-1, 1, 255, 256], 0, 255) …. array([ 0, 1, 255, 255]) but check the help and make sure you specify the output dtype properly – NaN May 07 '19 at 15:58
  • @nan that requires creating an intermediary array of larger dtype. If my data is 1GB of uint8, it will use up to 2GB more memory of uint16. – PiRK May 08 '19 at 11:05

1 Answers1

1

A bit late but I've used a convenient non-linear function (arctan) instead of clipping the overflow values:

from PIL import Image
import numpy as np

factor = 3
c = 512 / np.pi  # a constant to be used along with arctan

adjusted_image = np.arctan(data/c * factor) * c
Image.fromarray(adjusted_image.astype(np.int8), 'RGB')

The non-linear function can be fine-tuned, indeed; take this as an example for testing.

isCzech
  • 313
  • 1
  • 1
  • 7