关于skimage中transform的旋转和numpy旋转的对比问题

记录下skimage中的旋转问题:

对于numpy旋转90度的问题,可直接调用以下函数即可完成,数据类型跟随变换之前的数据类型:

img_couterclock_90 = np.rot90(img, 1)

对于使用skimage,采用以下代码会造成数据类型的转换,尽管数据的取整值不会发生改变:

img_couterclock_90_skimage = transform.rotate(img, 90, preserve_range=True)

然而,需要确保保存图像时的数据类型为输入图像的数据类型,而直接采用astype的方式是错误的。原因在于此时的img_couterclock_90_skimage中的数据类型是float64的(适用于skimage中的图像处理),直接转换会造成数据截断发生错误。这一点可以通过对比两个数组看出来,截图如下:

img_couterclock_90[..., -1][np.where(img_couterclock_90_skimage[..., -1] != img_couterclock_90[..., -1])]
img_couterclock_90_skimage[..., -1][np.where(img_couterclock_90_skimage[..., -1] != img_couterclock_90[..., -1])]

而这些不同的数在view as array中是看不出来的,如下,分别为numpy旋转结果和skimage旋转结果:

如果直接对skimage旋转结果(float64)进行astype数据类型转换,将会造成数据截断,导致数据发生变化(部分1值消失,变为0),如下:

解决这个问题可以通过取整来解决,代码为:

np.rint(img_couterclock_90_skimage[..., -1]).astype(np.uint8)

 

可见,两者完全一致。

综上,可通过两种方法实现图像的旋转,numpy方法最优,skimage则需要在数据类型变换前进行取整操作,如下:

img_couterclock_90 = np.rot90(img, 1)
np.rint(img_couterclock_90_skimage[..., -1]).astype(np.uint8)

这样才能确保两者结果相同,不会改变图像数据类型。

 

posted @ 2022-05-16 21:56  Anm半夏  阅读(107)  评论(0编辑  收藏  举报