11

I want to convert a float32 image into uint8 image in Python using the openCV library. I used the following code, but I do not know whether it is correct or not.

Here I is the float32 image.

J = I*255
J = J.astype(np.uint8)

I really appreciate if can you help me.

Greenonline
  • 1,330
  • 8
  • 23
  • 31
Hamidreza
  • 131
  • 1
  • 1
  • 7
  • Since no one explicitly said it, so long as your values are between 0 and 1 in your float image, then yes, your code is correct. – alkasm Nov 10 '18 at 05:30

2 Answers2

25

If you want to convert an image from single precision floating point (i.e. float32) to uint8, numpy and opencv in python offers two convenient approaches.

If you know that your image have a range between 0 and 255 or between 0 and 1 then you can simply make the convertion the way you already do:

I *= 255 # or any coefficient
I = I.astype(np.uint8)

If you don't know the range I suggest you to apply a min max normalization i.e. : (value - min) / (max - min)

With opencv you simply call the following instruction :

I = cv2.normalize(I, None, 255, 0, cv2.NORM_MINMAX, cv2.CV_8U)

The returned variable I type will have the type np.uint8 (as specify by the last argument) and a range between 0 and 255.

Using numpy you can also write something similar:

def normalize8(I):
  mn = I.min()
  mx = I.max()

  mx -= mn

  I = ((I - mn)/mx) * 255
  return I.astype(np.uint8)
Dženan
  • 3,329
  • 3
  • 31
  • 44
John_Sharp1318
  • 939
  • 8
  • 19
  • 2
    Note that astype truncates decimals. If you need more accuracy, I recommend changing the last lines to `I = ((I - mn)/mx) * 255.0` and `return np.round(I).astype(np.uint8)` – VoteCoffee Feb 17 '21 at 15:06
  • 1
    It depends what you want to do. For some application it is convinient not to round. The choice to round is up to the person as well as the application. – John_Sharp1318 Feb 17 '21 at 15:31
  • I agree. That's why I put it as a comment and didn't edit your answer. – VoteCoffee Feb 17 '21 at 16:44
-4

It is actually very simple: img_uint8 = img_float32.astype(np.uint8)

Burak
  • 2,251
  • 1
  • 16
  • 33
zhao yufei
  • 335
  • 3
  • 6
  • 1
    downvoted because for an image in range [0,1] this results in an image of 0's which is obviously not an adequate solution. – Yuri Feldman Nov 01 '21 at 18:38