定义范围时无法保持像素长宽比

问题描述

我正在使用DICOM图像,尽管在使用imshow和matplotlib得出的轴extent使用extent时,我能够以正确的宽高比绘制它们,但是我遇到了问题手动设置SliceInd = 18时,绘图的纵横比。目的:将轴从像素数更改为体素的物理坐标(以毫米为单位)。

图像是SimpleITK“图像”-在这种情况下,每个3D图像都由一堆2D图像组成。为简单起见,下面仅绘制每个图像的单个切片(PixArr3D = sitk.GetArrayFromImage(Image) )。对于不熟悉SimpleITK的用户,命令:

Image

从sitk图像(FixIm)中创建一个numpy数组。

为说明问题,以下代码用于2x3(2行x 3列)子图。我遍历两张3D图像(MovImimshow)(沿行显示),并对每张图像绘制3次图像:一次未定义extent的“范围”(第1列),并手动设置PixAR两次:一次使用像素(x和y)的纵横比(AxisAR,第2列),一次使用轴本身的纵横比( extent,第3列。

我关注了由贡献者提供的关于SO上类似问题的答案,这些问题涉及aspect(例如,Pyplot imshow not showing square pixels when setting aspect ratioChange values on matplotlib imshow() graph axis)使用imshowimport 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参数。无论如何,我都尝试过同时使用AxisARconsole.log,很明显两者都没有保留长宽比。

我正在努力提出任何线索,说明为什么它无法按我预期的那样工作,所以任何建议都将不胜感激。

Resulting_plot

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)