Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lossy conversion from float64 to uint8

Tags:

python

rgb

hsv

Code from https://www.makeartwithpython.com/blog/visualizing-sort-algorithms-in-python/

from imageio import imsave

import numpy as np

newImage = np.random.randint(0, 255, (300, 300, 3))

in_hsv_h = color.convert_colorspace(newImage, 'RGB', 'HSV')
in_hsv_s = in_hsv_h.copy()
in_hsv_v = in_hsv_h.copy()

for i in range(newImage.shape[0]):
    in_hsv_h[i,:,0] = np.sort(in_hsv_h[i,:,0])
    in_hsv_s[i,:,1] = np.sort(in_hsv_s[i,:,1])
    in_hsv_v[i,:,2] = np.sort(in_hsv_v[i,:,2])

imsave('testing-sorted-hue.png', color.convert_colorspace(in_hsv_h, 'HSV', 'RGB'))
imsave('testing-sorted-saturation.png', color.convert_colorspace(in_hsv_s, 'HSV', 'RGB'))

Lossy conversion from float64 to uint8. Range [0, 1]. Convert image to uint8 prior to saving to suppress this warning.

Still very inexperienced, any quick way to solve this issue?

like image 297
unreadable Avatar asked Nov 16 '19 18:11

unreadable


1 Answers

The warning is self explanatory: color.convert_colorspace(in_hsv_h, 'HSV', 'RGB') is of type float64, and imsave, convert elements to uint8.

The pixels of PNG image, are stored as one byte per component (one byte for red, one for green and one for blue).
Each component is an integer value in range [0, 255] (type uint8).

The output of color.convert_colorspace is of float64, each color component is in range [0, 1] of type float64 (stored as 64 bits in memory, and much more accurate than uint8).

The conversion from float64 range [0, 1] to uint8 range [0, 255] is performed like: uint8_val = round(float64_val*255).
The rounding operation loose some data (for example: in case float64_val*255 = 132.658, the result is rounded to 133).

Convert image to uint8 prior to saving to suppress this warning

Tells you to convert the image elements to uint8 prior to saving.

Solution is simple.
Multiply by 255, and add .astype(np.uint8).

imsave('testing-sorted-hue.png', (color.convert_colorspace(in_hsv_h, 'HSV', 'RGB')*255).astype(np.uint8))

In order for your code to work, you should also add .astype(np.uint8) when building newImage:

newImage = np.random.randint(0, 255, (300, 300, 3)).astype(np.uint8)

Complete code:

from imageio import imsave
from skimage import color

import numpy as np

newImage = np.random.randint(0, 255, (300, 300, 3)).astype(np.uint8)


in_hsv_h = color.convert_colorspace(newImage, 'RGB', 'HSV')
in_hsv_s = in_hsv_h.copy()
in_hsv_v = in_hsv_h.copy()

for i in range(newImage.shape[0]):
    in_hsv_h[i,:,0] = np.sort(in_hsv_h[i,:,0])
    in_hsv_s[i,:,1] = np.sort(in_hsv_s[i,:,1])
    in_hsv_v[i,:,2] = np.sort(in_hsv_v[i,:,2])

imsave('testing-sorted-hue.png', (color.convert_colorspace(in_hsv_h, 'HSV', 'RGB')*255).astype(np.uint8))
imsave('testing-sorted-saturation.png', (color.convert_colorspace(in_hsv_s, 'HSV', 'RGB')*255).astype(np.uint8))

Remark:
The example in makeartwithpython uses from imageio import imsave instead of from scipy.misc import imsave, and the example in the site is working correctly.

Note:
I don't have a lot of Python programming experience, please take my answer with some caution.

like image 194
Rotem Avatar answered Oct 20 '22 19:10

Rotem