如何通过脚本在数字显微镜中旋转3D光谱图像?

问题描述 投票:3回答:2

我想找到相应的rotate(图像,度)脚本命令来围绕x或y轴旋转(我只需要90º旋转)。我知道我可以使用工具菜单来完成它,但如果我能找到一个命令或一个函数来使用脚本来完成它会更快。

先感谢您!

image-rotation dm-script
2个回答
1
投票

使用Slice命令可能会让人感到困惑,所以这里有一个关于使用该命令围绕X轴旋转的详细说明。

此示例显示如何使用Slice3命令围绕其X轴顺时针旋转3D数据(沿X查看)。

Slice3命令指定现有数据数组的新视图。

  • 它首先指定原点像素,即在新视图中由(0,0,0)表示的坐标(在原始数据中)。
  • 然后,它为每个新的三个轴指定采样方向,长度和步长。 第一个三元组指定坐标(在原始数据中)如何沿新图像的x方向改变,第二个三元组用于新图像的y方向和最后三元组用于新图像的z方向。

因此围绕x轴的旋转可以想象为:Rotation around X

对于“重新采样”数据:

  • 新(旋转)数据的原点是原始数据点(0,0,SZ-1)。
  • 它的X方向保持不变,即新数据中X的一步,也会使原始数据中的坐标三元组增加(1,0,0)。 一个步骤大小为1的SX步骤。
  • 它的Y方向基本上是之前的负Z方向,即新数据中Y的一步,也会使原始数据中的坐标三元组增加(0,0,-1)。 因此,一个SZ步骤的步长为-1。
  • 其Z方向基本上是之前的Y方向,即新数据中Z的一步,将原始数据中的坐标三元组增加(0,1,0)。 所以一个步骤大小为1的SY步骤。

因此,对于绕X轴顺时针旋转,命令为: img.Slice3( 0,0,SZ-1, 0,SX,1, 2,SZ,-1, 1,SY,1 )

这个命令只会在相同的数据上创建一个新视图(即没有使用附加内存。)因此,要将旋转的图像作为新图像(数据值应该在内存中对齐),可以将此视图克隆到一个新的形象使用ImageClone()

总的来说,以下脚本将此作为示例显示:

// Demo of rotating 3D data orthogonally around the X axis
// This is done by resampling the data using the Slice3 command

// Creation of test image with regcognizeable pattern
number SX = 100
number SY = 30
number SZ = 50
image img := RealImage("Test",4, SX,SY,SZ)

// trig. modulated linear increase in X
img =  icol/iwidth* sin( icol/(iwidth-1) * 5 * Pi() ) **2       
// Simple linear increase in Y
img += (irow/iheight) * 2                                   
// Modulation of values in Z 
// (doubling values for index 0,1, 3, 4, 9, 16, 25, 36, 49) 
img *= (SQRT(iplane) == trunc(SQRT(iplane)) ? 2 : 1 )       
img.ShowImage()

// Show captions. Image coordinate system is
// Origin (0,0,0) in top-left-front most pixel
// X axis goes left to right
// Y axis goes top to down
// Z axis goes front to back 
img.ImageSetDimensionCalibration(0,0,1,"orig X",0)
img.ImageSetDimensionCalibration(1,0,1,"orig Y",0)
img.ImageSetDimensionCalibration(2,0,1,"orig Z",0)
img.ImageGetImageDisplay(0).ImageDisplaySetCaptionOn(1)

// Rotation around X axis, clockwise looking along X
// X --> X`  (unchanged)
// Y --> Z'
// Z --> -Y'
// old origin moves to bottom-left-front most 
// This means for "new" sampling:
// Specify sampling starting point:
//   New origin (0,0,0)'  will be value which was at (0,0,SZ-1)
//   Going one step in X' in the new data, will be like going one step in X 
//   Going one step in Y' in the new data, will be like going one step backwards in Z 
//   Going one step in Z' in the new data, will be like going one step in Y
image rotXCW := img.Slice3( 0,0,SZ-1, 0,SX,1, 2,SZ,-1, 1,SY,1 ).ImageClone()
rotXCW.SetName("rotated X, CW")
rotXCW.ShowImage()
rotXCW.ImageGetImageDisplay(0).ImageDisplaySetCaptionOn(1)


以下方法执行90度旋转:

// Functions for 90degree rotations of data
image RotateXCW( image input )
{
    number SX,SY,SZ
    input.Get3DSize(SX,SY,SZ)
    return input.Slice3( 0,0,SZ-1, 0,SX,1, 2,SZ,-1, 1,SY,1 ).ImageClone()
}

image RotateXCCW( image input )
{
    number SX,SY,SZ
    input.Get3DSize(SX,SY,SZ)
    return input.Slice3( 0,SY-1,0, 0,SX,1, 2,SZ,1, 1,SY,-1 ).ImageClone()
}

image RotateYCW( image input )
{
    number SX,SY,SZ
    input.Get3DSize(SX,SY,SZ)
    return input.Slice3( SX-1,0,0, 2,SZ,1, 1,SY,1, 0,SX,-1 ).ImageClone()
}

image RotateYCCW( image input )
{
    number SX,SY,SZ
    input.Get3DSize(SX,SY,SZ)
    return input.Slice3( 0,0,SZ-1, 2,SZ,-1, 1,SY,1, 0,SX,1 ).ImageClone()
}

image RotateZCW( image input )
{
    number SX,SY,SZ
    input.Get3DSize(SX,SY,SZ)
    return input.Slice3( 0,SY-1,0, 1,SY,-1, 0,SX,1, 2,SZ,1 ).ImageClone()
}

image RotateZCCW( image input )
{
    number SX,SY,SZ
    input.Get3DSize(SX,SY,SZ)
    return input.Slice3( SX-1,0,0, 1,SY,1, 0,SX,-1, 2,SZ,1 ).ImageClone()
}

围绕z轴的旋转也可以用RotateRight()RotateLeft()完成。但请注意,这些命令不会调整图像的尺寸校准,而Slice3命令则会。


0
投票

对于纯正交旋转,最简单(和最快)的方法是使用'虱子'命令,即用于3D图像的'slice3'。事实证明,最新版本的GMS在帮助文档中有一个例子,所以我只是在这里复制粘贴代码:

number sx = 10
number sy = 10
number sz = 10

number csx, csy, csz 
image img3D := RealImage( "3D", 4, sx, sy, sz )
img3D = 1000 + sin( 2*PI() * iplane/(idepth-1) ) * 100 + icol * 10  + irow
img3D.ShowImage()

// Rotate existing image
if ( OKCancelDialog( "Rotate clockwise (each plane)\n= Rotate block around z-axis" ) )
 img3D.RotateRight()



if ( OKCancelDialog( "Rotate counter-clockwise (each plane)\n= Rotate block around z-axis" ) )
 img3D.RotateLeft()


if ( OKCancelDialog( "Rotate block counter-clockwise around X-axis" ) )
{
 // Equivalent of sampling the data anew
 // x-axis remains 
 // y- and z-axis change their role
 img3D.Get3DSize( csx, csy, csz )        // current size along axes
 img3D = img3D.Slice3( 0,0,0, 0,csx,1, 2,csz,1, 1,csy,1 )
}

if ( OKCancelDialog( "Rotate block clockwise around X-axis" ) )
{
 // Equivalent of sampling the data anew
 // x-axis remains 
 // y- and z-axis change their role
 img3D.Get3DSize( csx, csy, csz )        // current size along axes
 img3D = img3D.Slice3( 0,csy-1,csz-1, 0,csx,1, 2,csz,-1, 1,csy,-1 )
}

if ( OKCancelDialog( "Rotate 30 degree (each plane)\n= Rotate block around z-axis" ) )
{
 number aDeg = 30
 number interpolMeth = 2
 number keepSize = 1
 image rotImg := img3D.Rotate( 2*Pi()/360 * aDeg, interpolMeth, keepSize )
 rotImg.ShowImage()
}

您可能还想查看this answer以获取有关二次取样和创建不同数据视图的更多信息。

© www.soinside.com 2019 - 2024. All rights reserved.