Renfong
Renfong

Reputation: 33

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

Due to the dm-script is not allowed to do simple math in different dimension. I am curious if there are any functions to create a 3D image in which all the planes are assigned to a single image without iteration.

enter image description here

Here is the iteration version:

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
};

Upvotes: 0

Views: 143

Answers (2)

arksakura
arksakura

Reputation: 57

Thank you, BmyGuest. mask2d[icol,irow,0] is very simple. If the image size (sx, sy, sz) becomes larger, the speed becomes slower for intrinsic variable. I modified for loop using slice3(). The processing speed became slightly better, but was not greatly improved.

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()

Upvotes: 1

BmyGuest
BmyGuest

Reputation: 2949

I'm first rephrasing your question: Essentially, you want to do:

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()

And you ask for a way to more efficiently create mask3d.


As in my comment, my question is why ?

You don't need to waste time and memory on that helper-stack, by simply doing instead:

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()

Now as for your question: You could replace the for-loop with intrinsic variable notation as:

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]

or without the mask3d simply use:

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

However, I don't think this is really faster or more efficient than the slice2 loop in the general case.

Upvotes: 0

Related Questions