如何创建一个 3D 图像,其中每个平面都分配给一个图像而无需迭代

How to create a 3D image in which each planes are assigned to a single image without iteration

由于 dm 脚本不允许在不同的维度上进行简单的数学运算。我很好奇是否有任何函数可以创建一个 3D 图像,其中所有平面都被分配给一个图像而无需迭代。

这里是迭代版本:

Image src := GetFrontImage()    
Number sx, sy, sz
src.Get3DSize(sx, sy, sz)

Image  filter := RealImage("xmean",4,sx,sy)
filter = tert(iradius>10 & iradius<50,1,0)

Image filter3D := RealImage("xmean",4,sx,sy, sz)
for (number i=0; i<sz; i++) {
    filter3D.Slice2(0,0,i,0,sx,1,1,sy,1) = filter
};

我首先要改写你的问题:本质上,你想做的是:

number sx = 50
number sy = 50
number sz = 1024
image stack := RealImage( "3D Stack", 4, sx, sy, sz )
stack = random()
stack.ShowImage()

image mask2d := RealImage( "2D Mask", 4, sx, sy )
mask2d = iradius>10 & iradius<50 ? 1 : 0
mask2d.ShowImage()

image mask3d := RealImage( "3D Mask", 4, sx, sy, sz )
for( number i=0; i<sz; i++ )
    mask3d.slice2(0,0,i,0,sx,1,1,sy,1) = mask2D


image stackFiltered = stack * mask3d
stackFiltered.showimage()

并且您要求一种更有效地创建 mask3d.

的方法

在我的评论中,我的问题是为什么

您不需要在帮助程序堆栈上浪费时间和内存,只需这样做:

number sx = 50
number sy = 50
number sz = 1024
image stack := RealImage( "3D Stack", 4, sx, sy, sz )
stack = random()
stack.ShowImage()

image mask2d := RealImage( "2D Mask", 4, sx, sy )
mask2d = iradius>10 & iradius<50 ? 1 : 0
mask2d.ShowImage()

image stackFiltered := stack.ImageClone()
for( number i=0; i<sz; i++ )
    stackFiltered.slice2(0,0,i,0,sx,1,1,sy,1) *= mask2D

stackFiltered.showimage()

现在关于您的问题:您可以将 for 循环替换为内部变量表示法,如:

image mask2d := RealImage( "2D Mask", 4, sx, sy )
mask2d = iradius>10 & iradius<50 ? 1 : 0

image mask3d := RealImage( "3D Mask", 4, sx, sy, sz )
mask3d = mask2d[icol,irow,0]

或者没有 mask3d 只需使用:

image stackFiltered = stack * mask2d[icol,irow,0]

但是,我认为在一般情况下,这并不真的比 slice2 循环更快或更有效。

谢谢你,BmyGuest。 mask2d[icol,irow,0] 很简单。 如果图像尺寸 (sx, sy, sz) 变大,内部变量的速度变慢。我使用 slice3() 修改了循环。处理速度略有好转,但并没有太大的提升。

number sx = 128
number sy = 128
number sz = 1000

image mask2d := RealImage( "2D Mask", 4, sx, sy )
mask2d = iradius>10 & iradius<50 ? 1 : 0
mask2d.ShowImage()

image mask3d := RealImage( "3D Mask", 4, sx, sy, sz )

number t0,t1

//for loop with slice2
number i
t0=GetHighResTickCount()
for(i=0;i<sz;i++)
{
    mask3d.slice2(0,0,i,0,sx,1,1,sy,1)=mask2d
}
t1=GetHighResTickCount()
result("for loop with slice2: "+CalcHighResSecondsBetween(t0,t1)+" s\n")
//mask3d.showimage()

//icol,irow
mask3d=0 //reset
t0=GetHighResTickCount()
mask3d = mask2d[icol,irow,0]
t1=GetHighResTickCount()
result("intrinsic variable: "+CalcHighResSecondsBetween(t0,t1)+" s\n")
//mask3d.showimage()

//for loop with slice3
mask3d=0 //reset
t0=GetHighResTickCount()
number n=0
while(2**n<sz)
{
    n=n+1
}
n=n-1

mask3d.slice2(0,0,0,0,sx,1,1,sy,1)=mask2d
for(i=0;i<n;i++)
{
    mask3d.slice3(0,0,2**i,0,sx,1,1,sy,1,2,2**i,1)=mask3d.slice3(0,0,0,0,sx,1,1,sy,1,2,2**i,1)
}
if(sz-2**n>0)
{
    mask3d.slice3(0,0,2**n,0,sx,1,1,sy,1,2,sz-2**n,1)=mask3d.slice3(0,0,0,0,sx,1,1,sy,1,2,sz-2**n,1)
}
t1=GetHighResTickCount()
result("for loop with slice3: "+CalcHighResSecondsBetween(t0,t1)+" s\n")
mask3d.showimage()