奇怪的问题是我有一个标签的3D数组(比如1-36),名为labelled_stack。这些只是数组中的值等于给定标签的区域。带有5个标签的快速2D示例如下:
labelled_stack = (0 0 0 0 0 0 0 0 0 0)
(0 1 1 0 0 0 2 2 2 0)
(0 1 0 0 3 0 0 2 2 0)
(0 0 0 3 3 0 0 0 0 0)
(0 4 0 0 3 0 0 0 5 0)
(0 4 0 0 0 0 5 5 5 0)
(0 0 0 0 0 0 0 0 0 0)
但想象一下它的阵容......
我尝试使用cv2.imwrite和scipy.misc.imsave来保存堆栈,但是当我这样做然后打开它们时,它们的值已经改变,因此值= 5,现在等于255,并且值相等到1,等于51等。这是不可接受的。我需要值保持原样..以1为单位增加整数值。我知道cv2和scipy.misc都写为8位图像,但这并不意味着我得到了这个错误。
我甚至已经将图像重新读回到python中,以检查这是否正在发生。它是。
我的labelled_stack类型为np.uint32
编辑以包含保存命令:for j in np.arange(0,l,1):
misc.imsave(save_path+Folder+'/Labelled/slice_{:04d}of{:}.tif'.format(j+1,l),labelled_stack[:,:,j])
...或
cv2.imwrite(save_path+Folder+'/Labelled/slice_{:04d}of{:}.tif'.format(j+1,l),labelled_stack[:,:,j])
答案 0 :(得分:3)
您可以阅读documentation:
imwrite函数将图像保存到指定的文件中。基于文件扩展名选择图像格式(请参阅imread()以获取扩展名列表)。 仅PNG,JPEG 2000和TIFF的8位(或16位无符号(CV_16U))单通道或3通道(带'BGR'通道顺序)图像可以使用此功能保存。
你说“labelled_stack
的类型为np.uint32
”(32位无符号整数)。那就是问题所在。你需要自己处理类型转换。
答案 1 :(得分:3)
函数imwrite
以8位格式保存数据。当函数将32位数据转换为8位时,它会将数据缩放为使用8位的完整位深度,因此例如,您的数据的最大值可扩展到255.有关其他示例,请参阅scipy imsave saves wrong values。
要避免这种情况,请在保存之前将数据转换为numpy.uint8
。在以下示例中,a
的数据类型为numpy.uint32
。
In [98]: from scipy.misc import imsave, imread
In [99]: a
Out[99]:
array([[0, 3, 2, 2, 4, 0, 3, 0],
[2, 0, 0, 3, 3, 1, 3, 0],
[2, 4, 4, 0, 2, 3, 1, 3],
[0, 1, 3, 1, 0, 0, 0, 4],
[2, 1, 1, 2, 1, 1, 3, 1],
[0, 4, 0, 1, 0, 0, 2, 3],
[3, 1, 3, 3, 3, 2, 3, 4],
[0, 4, 1, 4, 2, 2, 0, 2]], dtype=uint32)
astype
方法用于在将数组提供给numpy.uint8
函数之前将其转换为imsave
。
In [100]: imsave("a.tif", a.astype(np.uint8)) # Convert to 8 bit before saving
使用scipy.misc.imread
读回来:
In [101]: b = imread("a.tif")
In [102]: b
Out[102]:
array([[0, 3, 2, 2, 4, 0, 3, 0],
[2, 0, 0, 3, 3, 1, 3, 0],
[2, 4, 4, 0, 2, 3, 1, 3],
[0, 1, 3, 1, 0, 0, 0, 4],
[2, 1, 1, 2, 1, 1, 3, 1],
[0, 4, 0, 1, 0, 0, 2, 3],
[3, 1, 3, 3, 3, 2, 3, 4],
[0, 4, 1, 4, 2, 2, 0, 2]], dtype=uint8)
请注意,使用scipy.misc.imread
读取数据时,结果的数据类型为numpy.uint8
。
另一个推荐的选项,特别是当您尝试保留需要16位或32位的数据时,使用tifffile
。
在此示例中,a
的数据类型为numpy.uint32
,其中一些值大于无符号的8位数。
In [152]: from tifffile import imsave, imread
In [153]: a
Out[153]:
array([[ 0, 5, 10, 15, 20, 25, 30, 35, 40, 45],
[ 50, 55, 60, 65, 70, 75, 80, 85, 90, 95],
[100, 105, 110, 115, 120, 125, 130, 135, 140, 145],
[150, 155, 160, 165, 170, 175, 180, 185, 190, 195],
[200, 205, 210, 215, 220, 225, 230, 235, 240, 245],
[250, 255, 260, 265, 270, 275, 280, 285, 290, 295],
[300, 305, 310, 315, 320, 325, 330, 335, 340, 345],
[350, 355, 360, 365, 370, 375, 380, 385, 390, 395],
[400, 405, 410, 415, 420, 425, 430, 435, 440, 445],
[450, 455, 460, 465, 470, 475, 480, 485, 490, 495]], dtype=uint32)
In [154]: imsave("a.tif", a)
In [155]: b = imread("a.tif")
In [156]: b
Out[156]:
array([[ 0, 5, 10, 15, 20, 25, 30, 35, 40, 45],
[ 50, 55, 60, 65, 70, 75, 80, 85, 90, 95],
[100, 105, 110, 115, 120, 125, 130, 135, 140, 145],
[150, 155, 160, 165, 170, 175, 180, 185, 190, 195],
[200, 205, 210, 215, 220, 225, 230, 235, 240, 245],
[250, 255, 260, 265, 270, 275, 280, 285, 290, 295],
[300, 305, 310, 315, 320, 325, 330, 335, 340, 345],
[350, 355, 360, 365, 370, 375, 380, 385, 390, 395],
[400, 405, 410, 415, 420, 425, 430, 435, 440, 445],
[450, 455, 460, 465, 470, 475, 480, 485, 490, 495]], dtype=uint32)