 # Clipping pixel values

Hello everyone!

I have a grey scale image that I want to brighten. I do so by incrementing the pixel values by 50.
The problem is, if the value is higher than 255 it gets reset to 0 and then is incremented. Is there a way to clip the maximum value somehow ? As in, if it gets to 255 then it stays at 255.

So far I came up with this solution but it is rather laborious (line 8):

``````from skimage import data, io, exposure
import matplotlib.pyplot as plt
import numpy as np

im = data.camera()
hist, hist_centers = exposure.histogram(im)

im_new = im + np.minimum(np.ones_like(im) * 255 - im, np.ones_like(im) * 50)
hist_new, hist_centers_new = exposure.histogram(im_new)

fig, axs = plt.subplots(2, 2)

axs[0, 0].imshow(im, cmap=plt.cm.gray)
axs[0, 0].set_title('Original Image')

axs[0, 1].plot(hist_centers, hist)
axs[0, 1].set_title('Original Histogram')

axs[1, 0].imshow(im_new, cmap=plt.cm.gray)
axs[1, 0].set_title('New Image')

axs[1, 1].plot(hist_centers_new, hist_new, 'tab:red')
axs[1, 1].set_title('New Histogram')

plt.show()
``````

if you are starting with a `uint8` type and you don’t want to deal with type conversions, then you could clip the values prior to addition, for instance:

``````im = data.camera()
``````

alternatively, you could convert to `float`, then clip the values after addition and return to `uint8`

``````im = data.camera().astype('float')
im[im > 255] = 255
im = im.astype('uint8')
``````

as a sidenote, if you just want to display the image brighter, you don’t need to change the array values directly, you can also just use the `vmin, vmax` arguments to `imshow()`

There is also the handy `np.clip()`.
But as pointed out by talley already you would have to change the `dtype` to prevent wrap-around in `uint8`. You can then revert back to `uint8` after clipping.

1 Like

You can also get NumPy to upcast to a more useful integer dtype:

``````In : x = np.array([0, 128, 255], dtype=np.uint8) + np.array()

In : x
Out: array([  8, 136, 263])

In : x.dtype
Out: dtype('int64')

In : np.clip(x, 0, 255).astype(np.uint8)
Out: array([  8, 136, 255], dtype=uint8)
``````

If you are concerned about memory consumption, you can have one fewer copy:

``````In : x = np.array([0, 128, 255], dtype=np.uint8)

In : np.clip(x + np.array(), 0, 255, out=x)
Out: array([  8, 136, 255], dtype=uint8)

In : x
Out: array([  8, 136, 255], dtype=uint8)

``````
1 Like