简体   繁体   English

从 float64 到 uint8 的有损转换

[英]Lossy conversion from float64 to uint8

Code from https://www.makeartwithpython.com/blog/visualizing-sort-algorithms-in-python/代码来自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?还是很没有经验,有什么快速解决这个问题的方法吗?

The warning is self explanatory: color.convert_colorspace(in_hsv_h, 'HSV', 'RGB') is of type float64 , and imsave , convert elements to uint8 .警告是不言自明的: color.convert_colorspace(in_hsv_h, 'HSV', 'RGB')float64类型,而imsave将元素转换为uint8

The pixels of PNG image, are stored as one byte per component (one byte for red, one for green and one for blue). PNG图像的像素存储为每个组件一个字节(红色一个字节,绿色一个字节,蓝色一个字节)。
Each component is an integer value in range [0, 255] (type uint8 ).每个组件都是 [0, 255] 范围内的 integer 值(类型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 ). color.convert_colorspace 的 output 是float64 ,每个颜色分量都在float64类型的范围 [0, 1] 内(在 memory 中存储为 64 位,比uint8准确得多)。

The conversion from float64 range [0, 1] to uint8 range [0, 255] is performed like: uint8_val = round(float64_val*255) .float64范围 [0, 1] 到uint8范围 [0, 255] 的转换执行如下: 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).舍入操作会丢失一些数据(例如:如果 float64_val*255 = 132.658,则结果舍入为 133)。

Convert image to uint8 prior to saving to suppress this warning在保存之前将图像转换为 uint8 以抑制此警告

Tells you to convert the image elements to uint8 prior to saving.告诉您在保存之前将图像元素转换为uint8

Solution is simple.解决方法很简单。
Multiply by 255, and add .astype(np.uint8) .乘以 255,然后添加.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时添加.astype(np.uint8)

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. makeartwithpython中的示例使用from imageio import imsave而不是from scipy.misc import imsave ,并且站点中的示例工作正常。

Note:笔记:
I don't have a lot of Python programming experience, please take my answer with some caution.我没有很多Python编程经验,请谨慎接受我的回答。

There is no reason to use imageio library to save your image, since you already use skimage.color module from skimage library.没有理由使用imageio库来保存图像,因为您已经使用了skimage库中的skimage.color模块。 You can keep using skimage to save the image with skimage.save .您可以继续使用skimage使用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.此外,警告本身(“从 float64 到 uint8 的有损转换。范围 [0, 1]。在保存之前将图像转换为 uint8 以抑制此警告。”)来自skimage库。

This warning appears because dtype of the image is changed during saving from original 'float64' to 'uint8'.出现此警告是因为图像的 dtype 在从原始“float64”保存到“uint8”期间发生了更改。

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

But saving an image changes dtype to 'uint8':但是保存图像会将 dtype 更改为“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.要抑制警告,您需要在保存之前更改图像的 dtype。 Skimage provides utility function img_as_ubyte to do this: Skimage 提供实用程序 function 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 library warns against using astype to change dtype of an image. Skimage 库警告不要使用astype来更改图像的 dtype。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 将图像从 float64 转换为 uint8 使图像看起来更暗 - Convert image from float64 to uint8 makes the image look darker 尝试将 a.npy 文件 (float64) 转换为 uint8 或 uint16 - Trying to convert a .npy file (float64) to uint8 or uint16 将 float64 类型的 np.array 转换为 uint8 缩放值类型 - Convert np.array of type float64 to type uint8 scaling values 至少两个uint64系列,缺少值而没有float64转换 - Minimum of two uint64 series with missing values without float64 conversion 错误:TypeError:传递给参数“输入”的值的 DataType uint8 不在允许值列表中:float16、bfloat16、float32、float64、int32 - Error: TypeError: Value passed to parameter 'input' has DataType uint8 not in list of allowed values: float16, bfloat16, float32, float64, int32 类型错误:传递给参数“输入”的值的数据类型布尔值不在允许值列表中:float32、float64、int32、uint8、int16、int8 - TypeError: Value passed to parameter 'input' has DataType bool not in list of allowed values: float32, float64, int32, uint8, int16, int8 复制内部格式float64 uint64 - Copying internal formats float64 uint64 float64到float32转换会产生意外结果 - float64 to float32 conversion gives unexpected result 在熊猫中将int64非自愿转换为float64 - Involuntary conversion of int64 to float64 in pandas 将 ndarray 从 float64 转换为整数 - Convert ndarray from float64 to integer
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM