The function imwrite
saves the data in an 8 bit format. When the function converts your 32 bit data to 8 bit, it scales the data to use the full bit depth of 8 bits, so for example the maximum of your data is scaled up to 255. See scipy imsave saves wrong values for another example.
To avoid this, convert your data to numpy.uint8
before saving it. In the following example, a
has data type 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)
The astype
method is used to convert the array to numpy.uint8
before giving it to the imsave
function.
In [100]: imsave("a.tif", a.astype(np.uint8)) # Convert to 8 bit before saving
Read it back with 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)
Note that when the data is read with scipy.misc.imread
, the result has data type numpy.uint8
.
Another recommended option, especially if you are trying to preserve data that requires 16 bits or 32 bits, is to use tifffile
.
In this example, a
has data type numpy.uint32
, with some values that are larger than can fit in an unsigned 8 bit number.
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)