Why is image.astype(uint8) different from np.clip(image.astype(uint32), 0, 255) in Python?
if you have any negative values in the image, then casting to uint32 is or uint8 will create different results.
I am a bit confused about a behavior of my code.
I have an image tensor with values in range [0, 255] to which I have added some Gaussian noise so that the resulting tensor has values in larger and now continuous range, e.g. ca. [-253.234, 581.613].
This tensor should then be visualized via plt.imshow(...).
For this and other purposes, I would like to cast the tensor to a uint type. However, I encountered some weird differences between the following approaches and I would like to identify the right approach:

plt.imshow(image.astype(np.uint32))
plt.imshow(image.astype(np.uint8))
plt.imshow(np.clip(image.astype(np.uint32), 0, 255))

Approach (1) leads to the expected "Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers)." warning. And I assume that this image is then clipped like np.clip to values in the range [0, 255].
Approaches (2) and (3) lead to values in range [0, 255] so no exception is thrown but their mean values differ.
Approaches (1) and (3) lead to the same visualization, while (2) leads to a different image (e.g. slightly darker and more noisy).
I am currently clueless about why this happens. Is converting to uint32 and then clipping different from converting to uint8 in the first place?