Reputation: 33
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.
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
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
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
.
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