Lossy conversion from float64 to uint8

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.


There is no reason to use imageio library to save your image, since you already use skimage.color module from skimage library. You can keep using skimage to save the image with skimage.save.

Moreover, the warning itself ("Lossy conversion from float64 to uint8. Range [0, 1]. Convert image to uint8 prior to saving to suppress this warning.") comes from skimage library.

This warning appears because dtype of the image is changed during saving from original 'float64' to 'uint8'.

print(color.convert_colorspace(in_hsv_h, 'HSV', 'RGB').dtype) float64

But saving an image changes dtype to 'uint8':

from skimage import io io.imread('testing-sorted-hue.png').dtype dtype('uint8')

To suppress the warning you need to change dtype of the image before saving. Skimage provides utility function img_as_ubyte to do this:

in_hsv_h = color.convert_colorspace(in_hsv_h, 'HSV', 'RGB') print('dtype before:', in_hsv_h.dtype) dtype before: float64

from skimage.util import img_as_ubyte in_hsv_h=img_as_ubyte(in_hsv_h) print('dtype after: ', in_hsv_h.dtype) dtype after: uint8

Skimage library warns against using astype to change dtype of an image.

Tags:

Python

Rgb

Hsv