Python问题解决一:uint16的resize处理

问题描述

使用skimage来实现矩阵的resize时,发现变换前后的矩阵值发生较大变化。变换前平均值和标准差为2549.34±619.91,变换后则为0.0388±0.0093。

from skimage import transform,data
dst=transform.resize(img, (imgSize/4, imgSize/4))

问题定位

skimage的官方文档Transform模块中resize函数如下

skimage.transform.resize(image, output_shape, order=1, mode='reflect', cval=0, clip=True, preserve_range=False, anti_aliasing=True, anti_aliasing_sigma=None)

原因在于默认打开截断并关闭范围保持所引起。打开截断将输入数据(如此时则为uint16)转化为浮点数float64。与matlab不同,skimage的浮点数float64的数值表示范围为[0,1]或[-1,1]。这样处理的意义在于对于绝大多数scikit-image函数,浮点数能够满足平滑、卷积、滤过等操作中保持较高精度。 具体可参考skimage数据类型介绍。

解决方案一

通过设置截断clip和保持范围presever_range来实现,代码

dst = transform.resize(ori,[imgSize/4,imgSize/4],mode="constant", clip=False,preserve_range=True)

计算平均值来查看精度损失,缩放前平均值和标准差为2549.34±619.91,缩放后平均值和标准差为2548.53±613.25。

解决方案二

使用在缩放后使用类型转换,这样会有精度损失。缩放后平均值和标准差为2547.34±560。与方案一相比,标准差差异较为明显。

from skimage.util import img_as_float,img_as_uint
dst = img_as_uint(dst)

解决方案三

这个问题在githhub上也有讨论,解决方案是在使用transform进行数值处理时,首先uint16转换为float64并且归一化到[0,1]。这样在插值过程中保持高精度,然后变换后的返回值保持相同格式(类型float64,数值范围[0,1])。

你可能感兴趣的:(Python)