从float64到uint8的有损转换

时间:2019-11-16 18:25:06

标签: python rgb hsv

来自 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.

还是没有经验的人,有什么快速的方法可以解决这个问题?

2 个答案:

答案 0 :(得分:3)

警告是不言自明的:color.convert_colorspace(in_hsv_h, 'HSV', 'RGB')的类型为float64,而imsave则将元素转换为uint8

PNG图像的像素每个分量存储为一个字节(红色表示一个字节,绿色表示一个字节,蓝色表示一个字节)。
每个分量都是一个[0,255]范围内的整数值(类型uint8)。

color.convert_colorspace的输出为float64,每个颜色分量都位于float64类型的[0,1]范围内(存储在内存中为64位,并且比{{ 1}})。

uint8范围[0,1]到float64范围[0,255]的转换类似于:uint8
舍入操作会丢失一些数据(例如:在float64_val * 255 = 132.658的情况下,结果舍入为133)。

  

在保存之前将图像转换为uint8以禁止显示此警告

告诉您在保存之前将图像元素转换为uint8_val = round(float64_val*255)

解决方案很简单。
乘以255,然后加上uint8

.astype(np.uint8)

为了使代码正常工作,在构建imsave('testing-sorted-hue.png', (color.convert_colorspace(in_hsv_h, 'HSV', 'RGB')*255).astype(np.uint8)) 时还应该添加.astype(np.uint8)

newImage

完整代码:

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

备注:
makeartwithpython中的示例使用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)) 而不是from imageio import imsave,并且该站点中的示例正常运行。

注意:
我没有很多Python编程经验,请谨慎选择答案。

答案 1 :(得分:0)

没有理由使用imageio库来保存图像,因为您已经使用了skimage.color库中的skimage模块。您可以继续使用skimageskimage.save保存图像。

此外,警告本身(“从float64到uint8的有损转换。范围[0,1]。在保存之前将图像转换为uint8以禁止显示此警告。”)来自skimage库。

出现此警告是因为在保存过程中图像的dtype从原始的“ float64”更改为“ uint8”。

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

但是保存图像会将dtype更改为'uint8':

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

要取消显示警告,您需要在保存之前更改图像的dtype。 Skimage提供实用程序功能img_as_ubyte来做到这一点:

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库警告不要使用astype更改图像的dtype。