问题描述
我正在使用DICOM图像,尽管在使用imshow
和matplotlib得出的轴extent
使用extent
时,我能够以正确的宽高比绘制它们,但是我遇到了问题手动设置SliceInd = 18
时,绘图的纵横比。目的:将轴从像素数更改为体素的物理坐标(以毫米为单位)。
图像是SimpleITK“图像”-在这种情况下,每个3D图像都由一堆2D图像组成。为简单起见,下面仅绘制每个图像的单个切片(PixArr3D = sitk.GetArrayFromImage(Image)
)。对于不熟悉SimpleITK的用户,命令:
Image
从sitk图像(FixIm
)中创建一个numpy数组。
为说明问题,以下代码用于2x3(2行x 3列)子图。我遍历两张3D图像(MovIm
和imshow
)(沿行显示),并对每张图像绘制3次图像:一次未定义extent
的“范围”(第1列),并手动设置PixAR
两次:一次使用像素(x和y)的纵横比(AxisAR
,第2列),一次使用轴本身的纵横比( extent
,第3列。
我关注了由贡献者提供的关于SO上类似问题的答案,这些问题涉及aspect
(例如,Pyplot imshow not showing square pixels when setting aspect ratio和Change values on matplotlib imshow() graph axis)使用imshow
和import numpy as np
import SimpleITK as sitk
import matplotlib.pyplot as plt
%matplotlib inline
%matplotlib notebook
SliceInd = 18
Images = [FixIm,MovIm]
Txts = ['Session 1','Session 2']
Nrows = 2
Ncols = 3
fig,ax = plt.subplots(Nrows,Ncols,figsize=(14,7*Nrows))
subplotNum = 0
for i in range(len(Images)):
Image = Images[i]
Txt = Txts[i]
PixArr3D = sitk.GetArrayFromImage(Image)
# Get the variables required for pixel and axis aspect ratios,and
# the axis extent.
PixArrShape = PixArr3D.shape
# Get dimensions in [x,y,z] order:
PixDims = [PixArrShape[i] for i in [1,2,0]]
Origin = Image.Getorigin()
PixSpacings = Image.GetSpacing() # e.g. (0.8984375,0.8984375,5.0) => (x,z)
Orient = [Image.GetDirection()[i] for i in range(len(Image.GetDirection()))]
# Reverse the sign of the cross terms so that the vectors are defined in
# the same way as Pydicom:
for i in [1,3,5,6,7]:
Orient[i] = - Orient[i]
# Pixel aspect ratio:
PixAR = PixSpacings[1]/PixSpacings[0] # y/x
# Get the axis extent and aspect ratio.
# Since Origin is defined at voxel [0,0],the min/max x and y
# coordinates are given by Origin[0] and Origin[1] + the x and y
# components of the z-direction cosine (Orient[6] and Orient[7]):
Xmin = Origin[0] + SliceInd*PixSpacings[2]*Orient[6]
Ymin = Origin[1] + SliceInd*PixSpacings[2]*Orient[7]
Xmax = Xmin + PixDims[0]*PixSpacings[0]*Orient[0] + PixDims[1]*PixSpacings[1]*Orient[3]
Ymax = Ymin + PixDims[0]*PixSpacings[0]*Orient[1] + PixDims[1]*PixSpacings[1]*Orient[4]
AxisExtent = [Xmin,Xmax,Ymax,Ymin]
AxisDx = (Xmax - Xmin) / PixDims[0]
AxisDy = (Ymax - Ymin) / PixDims[1]
# Axis aspect ratio:
AxisAR = AxisDx / AxisDy
# Get 2D pixel array for axial perspective:
PixArr2D = PixArr3D[SliceInd,:,:]
# Sub-plots:
# Plot with default extent:
subplotNum += 1
ax = plt.subplot(Nrows,subplotNum)
ax.imshow(PixArr2D,cmap=plt.cm.Greys_r,aspect=PixAR)
ax.set_title(Txt + f'\naspect = PixAR = {PixAR}' \
+ '\nextent = default')
# Plot with extent=AxisExtent and aspect=PixAR:
subplotNum += 1
ax = plt.subplot(Nrows,extent=AxisExtent,aspect=PixAR)
ax.set_title(Txt + f'\naspect = PixAR = {PixAR}' \
+ '\nextent = AxisExtent')
# Plot with extent=AxisExtent and aspect=AxisAR:
subplotNum += 1
ax = plt.subplot(Nrows,aspect=AxisAR)
ax.set_title(Txt + f'\naspect = AxisAR = {round(AxisAR,2)}' \
+ '\nextent = AxisExtent')
。尽管我尝试遵循其他人的指导,但在维持像素的纵横比方面并没有成功。
ax.set_aspect(PixAR)
我也尝试添加以下行:
imshow
在aspect
命令之后。
我的直觉告诉我,PixAR
应该设置为AxisAR
而不是aspect
,但是也许我误解了imshow
中的PixAR
参数。无论如何,我都尝试过同时使用AxisAR
和console.log
,很明显两者都没有保留长宽比。
我正在努力提出任何线索,说明为什么它无法按我预期的那样工作,所以任何建议都将不胜感激。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)