函数 "im2uint8"(在 MATLAB 中)和 "bytescale"(在 Python 中)之间的区别
Difference between the functions "im2uint8" (in MATLAB) and "bytescale" (in Python)
我想将 DICOM 图像从 int16 转换为 uint8。我在 Python 中使用 Z_axis = bytescale(img)
完成了它,但这给出了与在 MATLAB 中使用 im2uint8
不同的结果。在 MATLAB 中,使用 im2uint8
转换为 uint8 后的 DICOM 图像的最小值和最大值分别为 (124, 136)。但是使用 bytescale
转换后 Python 中的这些值是 (0, 255).
Python代码:
for person in range(0, len(dirs1)):
if not os.path.exists(os.path.join(directory, dirs1[person])):
Pathnew = os.path.join(directory, dirs1[person])
os.makedirs(Pathnew)
for root, dirs, files in os.walk(os.path.join(path, dirs1[person])):
dcmfiles = [_ for _ in files if _.endswith('.dcm')]
for dcmfile in dcmfiles:
dcm_image = pydicom.read_file(os.path.join(root, dcmfile))
img = dcm_image.pixel_array
Z_axis = bytescale(img)
minVal = Z_axis.min()
maxVal = Z_axis.max()
Matlab代码:
for j = 1 : length(Files2)
img = dicomread([galleryPath Files2(j).name]);
Z_axis = im2uint8(img);
minVal = min(min(Z_axis));
maxVal = max(max(Z_axis));
图像显示时看起来相等,但数值不同。那么,bytescale
和 im2uint8
函数是否相等?如果不是,我想要 Python 中的 im2uint8
这样的结果。我应该选择什么样的功能(尤其是DICOM图像)?
例如,在 MATLAB 中读取 DICOM 文件后:
img = dicomread([galleryPath Files2(j).name]);
img = [ -1024, -1024, 16;
-1024, 8, 11;
17, 5, 8];
但是在Python中,读取后的相同图像是:
dcm_image = pydicom.read_file(os.path.join(root, dcmfile))
img = dcm_image.pixel_array
img = array([[ -1024, -1024, 27],
[ -1024, 27, 26],
[ 24, 26, 23]])
我不知道为什么它们在 MATLAB 和 Python 中不同。在 MATLAB 中应用 im2uint8
后,输出为:
Z_axis = im2uint8(img)
Z_axis =
3×3 uint8 matrix
124 124 128
124 128 128
128 128 128
并且在 Python 中应用 bytescale
之后,输出是:
bytescale(img)
Z_axis =
array([[0, 0, 83],
[0, 83, 83],
[83, 83, 83]], dtype=uint8)
首先,关于读取数据的问题,我建议在 MATLAB 中使用 dcmread
in Python, as that gave me the same exact data as dicomread
。
其次,在 MATLAB 中,当 im2uint8
converts int16
values it will scale them assuming minimum and maximum values for the data equal to -32768 and 32767, respectively (i.e. the minimum and maximum values representable by an int16
). For bytescale
表现相同时,我相信您需要相应地设置 cmin
和 cmax
参数(否则它们将默认为 data.min()
和 data.max()
)。这应该在 Python:
中复制 im2uint8
的结果
Z_axis = bytescale(img.astype(float), cmin=-32768, cmax=32767)
注意:必须首先将数据转换为浮点数,以解决 bytescale
中无法正确处理整数运算的明显错误(由 Cris Luengo 提供)。
是的,不一样
bytescale
将矩阵转换为 uint8 通过最高和最低(最高 255 和最低 0)归一化所有值
img = array([[ 91.06794177, 3.39058326, 84.4221549 ],
[ 73.88003259, 80.91433048, 4.88878881],
[ 51.53875334, 34.45808177, 27.5873488 ]])
bytescale(img)
array([[255, 0, 236],
[205, 225, 4],
[140, 90, 70]], dtype=uint8)
在 Matlab 中 im2uint8
将双图像转换为 uint8 很有用。双图像的范围为 0 到 1。
要在 Matlab 拳头中做同样的事情,您需要在值 0-1(双)范围内转换图像,对数据进行归一化,然后应用 im2uint8。
I = [ 91.06794177, 3.39058326, 84.4221549;
73.88003259, 80.91433048, 4.88878881;
51.53875334, 34.45808177, 27.5873488];
Inorm = (I - min(I(:))) ./ ( max(I(:)) - min(I(:)) );
I2 = im2uint8(Inorm);
然后你得到相同的图像:
I2 =
3×3 uint8 matrix
255 0 236
205 225 4
140 90 70
我想将 DICOM 图像从 int16 转换为 uint8。我在 Python 中使用 Z_axis = bytescale(img)
完成了它,但这给出了与在 MATLAB 中使用 im2uint8
不同的结果。在 MATLAB 中,使用 im2uint8
转换为 uint8 后的 DICOM 图像的最小值和最大值分别为 (124, 136)。但是使用 bytescale
转换后 Python 中的这些值是 (0, 255).
Python代码:
for person in range(0, len(dirs1)):
if not os.path.exists(os.path.join(directory, dirs1[person])):
Pathnew = os.path.join(directory, dirs1[person])
os.makedirs(Pathnew)
for root, dirs, files in os.walk(os.path.join(path, dirs1[person])):
dcmfiles = [_ for _ in files if _.endswith('.dcm')]
for dcmfile in dcmfiles:
dcm_image = pydicom.read_file(os.path.join(root, dcmfile))
img = dcm_image.pixel_array
Z_axis = bytescale(img)
minVal = Z_axis.min()
maxVal = Z_axis.max()
Matlab代码:
for j = 1 : length(Files2)
img = dicomread([galleryPath Files2(j).name]);
Z_axis = im2uint8(img);
minVal = min(min(Z_axis));
maxVal = max(max(Z_axis));
图像显示时看起来相等,但数值不同。那么,bytescale
和 im2uint8
函数是否相等?如果不是,我想要 Python 中的 im2uint8
这样的结果。我应该选择什么样的功能(尤其是DICOM图像)?
例如,在 MATLAB 中读取 DICOM 文件后:
img = dicomread([galleryPath Files2(j).name]);
img = [ -1024, -1024, 16;
-1024, 8, 11;
17, 5, 8];
但是在Python中,读取后的相同图像是:
dcm_image = pydicom.read_file(os.path.join(root, dcmfile))
img = dcm_image.pixel_array
img = array([[ -1024, -1024, 27],
[ -1024, 27, 26],
[ 24, 26, 23]])
我不知道为什么它们在 MATLAB 和 Python 中不同。在 MATLAB 中应用 im2uint8
后,输出为:
Z_axis = im2uint8(img)
Z_axis =
3×3 uint8 matrix
124 124 128
124 128 128
128 128 128
并且在 Python 中应用 bytescale
之后,输出是:
bytescale(img)
Z_axis =
array([[0, 0, 83],
[0, 83, 83],
[83, 83, 83]], dtype=uint8)
首先,关于读取数据的问题,我建议在 MATLAB 中使用 dcmread
in Python, as that gave me the same exact data as dicomread
。
其次,在 MATLAB 中,当 im2uint8
converts int16
values it will scale them assuming minimum and maximum values for the data equal to -32768 and 32767, respectively (i.e. the minimum and maximum values representable by an int16
). For bytescale
表现相同时,我相信您需要相应地设置 cmin
和 cmax
参数(否则它们将默认为 data.min()
和 data.max()
)。这应该在 Python:
im2uint8
的结果
Z_axis = bytescale(img.astype(float), cmin=-32768, cmax=32767)
注意:必须首先将数据转换为浮点数,以解决 bytescale
中无法正确处理整数运算的明显错误(由 Cris Luengo 提供)。
是的,不一样
bytescale
将矩阵转换为 uint8 通过最高和最低(最高 255 和最低 0)归一化所有值
img = array([[ 91.06794177, 3.39058326, 84.4221549 ],
[ 73.88003259, 80.91433048, 4.88878881],
[ 51.53875334, 34.45808177, 27.5873488 ]])
bytescale(img)
array([[255, 0, 236],
[205, 225, 4],
[140, 90, 70]], dtype=uint8)
在 Matlab 中 im2uint8
将双图像转换为 uint8 很有用。双图像的范围为 0 到 1。
要在 Matlab 拳头中做同样的事情,您需要在值 0-1(双)范围内转换图像,对数据进行归一化,然后应用 im2uint8。
I = [ 91.06794177, 3.39058326, 84.4221549;
73.88003259, 80.91433048, 4.88878881;
51.53875334, 34.45808177, 27.5873488];
Inorm = (I - min(I(:))) ./ ( max(I(:)) - min(I(:)) );
I2 = im2uint8(Inorm);
然后你得到相同的图像:
I2 =
3×3 uint8 matrix
255 0 236
205 225 4
140 90 70