我正在尝试使用 C/CUDA 实现图像堆栈的 3D 旋转例程(主要是为了加快计算时间)。我使用 ImageJ 源代码作为代码的基础,因此旋转不是围绕原点自由旋转,而是沿着轴旋转。不过,我遇到了一个有趣的问题。我实现了一个对象绕 Y 轴的旋转,几乎没有问题。但是,当我尝试使用非常相似的代码绕 X 轴旋转时,会出现问题。我注意到在X旋转中,有明显的条纹,例如这个例子:
这在我正在进行的 Y 旋转中没有发生。
我提供了运行来绕每个轴旋转的 CUDA 内核(rotationY 是有效的,rotationX 是提供条纹的)。我想知道是否有人可以提供任何建议来解释为什么我会遇到其中一个而不是另一个的问题,只要它们在实现上非常相似。
编辑:我已将问题范围缩小到atomicMin() 无法正常工作。即使所有偏移量均已正确设置,zbuffer 也未正确更改。如果有人知道为什么这可能行不通,那就太好了。
__global__ void rotationY(int *input, int *projArray, int costheta, int sintheta, int width, int height, int depth, int xcenter, int zcenter,
int projectionwidth, int projectionsize, int *zbuffer, int adjCue, int depthCueSurf, int zmax, int zdiff){
int i=threadIdx.x + blockDim.x*blockIdx.x;
int zcostheta;
int zsintheta;
int offset;
int k, z, point, xnew, znew;
int y=i/width;
int x=i-y*width-xcenter;
int xcostheta = x*costheta;
int xsintheta = x*sintheta;
int offsetinit = y*projectionwidth;
zbuffer[i]=32767;
__syncthreads();
for(k=1; k<=depth; k++){
z = (int)(k-1+.5) - zcenter;
zcostheta = z*costheta;
zsintheta = z*sintheta;
point = i + (k-1)*width*height;
if(input[point]>0){
xnew = (xcostheta + zsintheta)/8192 + xcenter;
znew = (zcostheta - xsintheta)/8192 + zcenter;
offset = offsetinit + xnew;
if (offset<0 || offset>=projectionsize) offset = 0;
atomicMin(&zbuffer[offset],znew);
}
__syncthreads();
if(input[point]>0){
if(znew<=zbuffer[offset]) projArray[offset] = adjCue*input[point]/100+depthCueSurf*input[point]*(zmax-znew)/zdiff;
}
}
}
__global__ void rotationX(int *input, int *projArray, int costheta, int sintheta, int width, int height, int depth, int ycenter, int zcenter,
int projectionsize, int *zbuffer, int adjCue, int depthCueSurf, int zmax, int zdiff) {
int i=threadIdx.x + blockDim.x*blockIdx.x;
int zcostheta;
int zsintheta;
int offset;
int k, z, point, ynew, znew;
int y=i/width;
int x=i-y*width;
y=y-ycenter;
int ycostheta = y*costheta;
int ysintheta = y*sintheta;
zbuffer[i]=32767;
__syncthreads();
for(k=1; k<=depth; k++){
z = (int)(k-1+.5) - zcenter;
zcostheta = z*costheta;
zsintheta = z*sintheta;
point = i + (k-1)*width*height;
if(input[point]>0){
ynew = (ycostheta - zsintheta)/8192 + ycenter;
znew = (ysintheta + zcostheta)/8192 + zcenter;
offset = x + ynew*width;
if (offset<0 || offset>=projectionsize) offset = 0;
atomicMin(&zbuffer[offset], znew);
}
__syncthreads();
if(input[point]>0){
if(znew<=zbuffer[offset]) projArray[offset] = adjCue*input[point]/100+depthCueSurf*input[point]*(zmax-znew)/zdiff;
}
}
}
最佳答案
rotationX的函数原型(prototype)中缺少参数projectionwidth。 这是我目前出现的错误的最佳候选者。
关于c - C/CUDA 中的 3D 旋转问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6932037/