im[col, row, plane] = src[icol,irow,iplane]
The intrinsic variables icol, irow, iplane will be evaluated by the only fixed size image expression in the line. In your case col, row and plane (all of same size)
However, they are all 2D so what is internally happening is that you iterate over X & Y and then write the values:
im[ col(x,y), row(x,y), plane(x,y) ] = src[x,y,0] // iterated over all x/y
As Don I was mentioning in the comments, you would want to iterate over the z dimension.
Alternatively, you could make all of your images of size (sx,sy,sz) in your script.
This would work for the expression, but is horrifically inefficient.
In general, the best solution here is to no t use icol,irow,iplane at all, but make use of the Slice
commands. see this answer:
I would possibly code a line-wise x-shift for an SI like below:
The script utilizes the fact that one can shift whole "blocks" (X x 1 x Z) in x-direction, iterating over y.
number sx = 256
number sy = 256
number sz = 100
image testSI := realImage("SI",4,sx,sy,sz)
testSI = sin(itheta/(idepth-iplane)*idepth) + (iplane % (icol+1))/idepth
testSI.ShowImage()
image xdrift := RealImage("XDrift per line",4,sy)
xdrift = trunc(random()*5 + 20*sin(icol/iwidth*3*PI()))
xdrift.ShowImage()
// Apply linewise Drift to SI, assuming xDrift holds this data
xDrift -= min(xDrift) // ensure only positive shifts
image outSI := realImage("SI shifted",4,sx+max(xDrift),sy,sz)
outSI.ShowImage()
for( number y=0; y<sy; y++ ){
number yShift = sum(xDrift[y,0])
outSI.slice2( yShift,y,0, 0,sx,1, 2,sz,1 ) = testSI.slice2(0,y,0,0,sx,1,2,sz,1)
}
The script below performs the iteration "plane by plane", but does not have a restriction on the plane-wise shift.
In fact, here each pixel gets an assigned XY shift.
Note that you can use warp(source, xexpr, yexpr )
instead of 2D addressing source[ xexpr, yexpr ]
if you want to use bilinear interploation of values (and 0 truncation outside the valid range).
number sx = 256
number sy = 256
number sz = 100
image testSI := realImage("SI",4,sx,sy,sz)
testSI = sin(itheta/(idepth-iplane)*idepth) + (iplane % (icol+1))/idepth
testSI.ShowImage()
image xdrift := RealImage("pixelwise XDrift",4,sx,sy)
xdrift = irow%10*random() + 20*cos(irow/iheight*5*PI())
xdrift.ShowImage()
image ydrift := RealImage("pixelwise yDrift",4,sx,sy)
ydrift = 10*abs(cos(icol/iwidth* (irow/iheight) * 10 * PI())) + irow/iheight * 10
ydrift.ShowImage()
// Apply pixelwise Drift to SI
xDrift -= min(xDrift) // ensure only positive shifts
yDrift -= min(yDrift) // ensure only positive shifts
number mx = max(xDrift)
number my = max(yDrift)
image outSI := realImage("SI shifted",4,sx+mx,sy+my,sz)
outSI.ShowImage()
for( number z=0;z<sz;z++){
image outPlane := outSI.Slice2( 0,0,z, 0,sx+mx,1,1,sy+my,1)
image srcPlane := testSI.Slice2( 0,0,z, 0,sx,1,1,sy,1)
outPlane = srcPlane[ icol + xdrift[icol,irow] - mx, irow + ydrift[icol,irow] - my ]
// outPlane = srcPlane.warp( icol + xdrift[icol,irow] - mx, irow + ydrift[icol,irow] - my)
}