How to interpolate with different voxel sizes?
6 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Lieke Pullen
el 6 de Feb. de 2022
Comentada: William Rose
el 8 de Feb. de 2022
Hi all,
I want to load in a PET image which has the dimensions 171x171x127 voxels, with each voxel being 4.17x4.17x2.03 mm. Within this image, there is for example a sphere with a radius of 30 voxels. I want to interpolate this to a grid in which each voxel has the dimensions of 3x3x3 mm, in which this sphere adjusts to the new grid, where the radius of the sphere then has a different number of voxels as a radius (in the new grid that would be 10 voxels then). I have the following code already:
x=171; y=171; z=121;
PETimage=zeros(x,y,z);
rad=30;
PETimage(round(.5*x)-rad:round(.5*x)+rad,round(.5*y)-rad:round(.5*y)+rad,round(.5*z)-rad:round(.5*z)+rad)=1;
size_x=4.17;
size_y=4.17;
size_z=2.03;
x_grid=x*size_x; x_newgrid=floor(x_grid/3);
y_grid=y*size_y; y_newgrid=floor(y_grid/3);
z_grid=z*size_z; z_newgrid=floor(z_grid/3);
newgrid=zeros(x_newgrid,y_newgrid,z_newgrid);
I think I now have to use either interpol3 or griddedInterpolant, but I don't know how. Can anybody help me out?
Greetings, Lieke
0 comentarios
Respuesta aceptada
William Rose
el 6 de Feb. de 2022
I would use interp3(). First you must create the grids X,Y,Z (the old coordinates of the voxels) and Xq,Yq,Zq (the coordinates of the new voxels) with meshgrid. Then you call interp3(). See code below.
nx=171; ny=171; nz=121;
dx=4.17; dy=4.17; dz=2.03;
x=(0:nx-1)*dx; %vector of x coords
y=(0:ny-1)*dy; %vector of y coords
z=(0:nz-1)*dz; %vector of z coords
[X,Y,Z]=meshgrid(x,y,z); %make three 3-D meshes X,Y,Z
dx2=3.0; dy2=3.0; dz2=3.0;
nx2=floor(nx*dx/dx2);
ny2=floor(ny*dy/dy2);
nz2=floor(nz*dz/dz2);
x2=(0:nx2-1)*dx2; %vector new of x coords
y2=(0:ny2-1)*dy2; %vector of new y coords
z2=(0:nz2-1)*dz2; %vector of new z coords
[X2,Y2,Z2]=meshgrid(x2,y2,z2); %make three 3-D meshes X2,Y2,Z2
PETimage=zeros(nx,ny,nz);
rad=30;
PETimage(round(.5*nx)-rad:round(.5*nx)+rad,round(.5*ny)-rad:round(.5*ny)+rad,round(.5*nz)-rad:round(.5*nz)+rad)=1;
PETimage2=zeros(nx2,ny2,nz2);
PETimage2=interp3(X,Y,Z,PETimage,X2,Y2,Z2);
fprintf('Size of image 1=%dx%dx%d. Size of image 2 = %dx%dx%d.\n',size(PETimage),size(PETimage2));
Try it. Good luck.
5 comentarios
William Rose
el 8 de Feb. de 2022
Your original code used the line
%PETimage(round(.5*nx)-rad:round(.5*nx)+rad,round(.5*ny)-rad:round(.5*ny)+rad,round(.5*nz)-rad:round(.5*nz)+rad)=1;
The line above creates a rectangular tumor, 2*rad+1 voxels in each direction, in the original coordinates. To create a spherical tumor of radius r, centered at (x0,y0,z0), in the original coordinates, create a function that returns True=1 if (x,y,z) is inside or on the sphere, and 0 otherwise. Then make a loop (actually 3 nested loops for x,y,z) to call the function for each voxel in the cube that bounds the sphere. Set PETimage to the tumor denisty in the voxels where the function returns True. The code below shows examples of calls to the function, folowed by the function itself.
After you create the tumor in the orignal image array, it will be correctly represented in the new array.
%examples of calls to isInside are below, followed by the function
isInside([1,0,0],[0,0,0],1)
isInside([1,-1,0],[0,0,0],1)
isInside([27,14,26],[20,20,20],11)
function x=isInside(p,p0,r)
%ISINSIDE determines if a point is (in or on) a specified sphere, or not
%Inputs: p=[x,y,z]=position, p0=[x0,y0,z0]=sphere center, r=sphere radius
%Output: x=True if ||p-p0||<=r, else x=False
x=sum((p-p0).^2)<=r^2;
end
Try it.
Más respuestas (0)
Ver también
Categorías
Más información sobre Interpolation en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!