Skip to content

Commit eac6873

Browse files
authored
Merge pull request #666 from defThu/offSource
added "offSource" to adjust the position of X-ray source
2 parents 0e66c55 + e4823f8 commit eac6873

12 files changed

Lines changed: 106 additions & 21 deletions

Common/CUDA/Siddon_projection.cu

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -668,9 +668,11 @@ void computeDeltas_Siddon(Geometry geo,int i, Point3D* uvorigin, Point3D* deltaU
668668

669669
Point3D S;
670670
S.x=geo.DSO[i];
671-
S.y=0;
672-
S.z=0;
673-
671+
//S.y=0;
672+
//S.z=0;
673+
S.y=geo.offSourceY[i];
674+
S.z=geo.offSourceZ[i];
675+
674676
//End point
675677
Point3D P,Pu0,Pv0;
676678

Common/CUDA/ray_interpolated_projection.cu

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -632,9 +632,11 @@ void splitImageInterp(unsigned int splits,Geometry geo,Geometry* geoArray, unsig
632632
void computeDeltas(Geometry geo,unsigned int i, Point3D* uvorigin, Point3D* deltaU, Point3D* deltaV, Point3D* source){
633633
Point3D S;
634634
S.x=geo.DSO[i];
635-
S.y=0;
636-
S.z=0;
637-
635+
//S.y=0;
636+
//S.z=0;
637+
S.y=geo.offSourceY[i];
638+
S.z=geo.offSourceZ[i];
639+
638640
//End point
639641
Point3D P,Pu0,Pv0;
640642

Common/CUDA/types_TIGRE.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ struct Geometry {
6363
float sDetecU, sDetecV;
6464
float dDetecU, dDetecV;
6565
float *offDetecU, *offDetecV;
66+
float *offSourceY,*offSourceZ;
6667
float* DSD;
6768
float* dRoll;
6869
float* dPitch;
@@ -106,4 +107,4 @@ struct Point3Ddouble{
106107
}
107108
};
108109

109-
#endif
110+
#endif

Common/CUDA/voxel_backprojection.cu

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -871,8 +871,8 @@ void computeDeltasCube(Geometry geo,int i, Point3D* xyzorigin, Point3D* deltaX,
871871
//Done for P, now source
872872
Point3Ddouble source;
873873
source.x=geo.DSD[i]; //already offseted for rotation
874-
source.y=-geo.offDetecU[i];
875-
source.z=-geo.offDetecV[i];
874+
source.y=geo.offSourceY[i]-geo.offDetecU[i];
875+
source.z=geo.offSourceZ[i]-geo.offDetecV[i];
876876
rollPitchYawT(geo,i,&source);
877877

878878
source.x=source.x-(geo.DSD[i]-geo.DSO[i]);// source.y=source.y-auxOff.y; source.z=source.z-auxOff.z;

Common/CUDA/voxel_backprojection2.cu

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -793,8 +793,8 @@ void computeDeltasCube(Geometry geo,int i, Point3D* xyzorigin, Point3D* deltaX,
793793
//Done for P, now source
794794
Point3Ddouble source;
795795
source.x=geo.DSD[i]; //already offseted for rotation
796-
source.y=-geo.offDetecU[i];
797-
source.z=-geo.offDetecV[i];
796+
source.y=geo.offSourceY[i]-geo.offDetecU[i];
797+
source.z=geo.offSourceZ[i]-geo.offDetecV[i];
798798
rollPitchYawT(geo,i,&source);
799799

800800

MATLAB/Demos/d01_CreateGeometry.m

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
geo.sVoxel=[256;256;256]; % total size of the image (mm)
7878
geo.dVoxel=geo.sVoxel./geo.nVoxel; % size of each voxel (mm)
7979
% Offsets
80+
geo.offSource = [0;0];
8081
geo.offOrigin =[0;0;0]; % Offset of image from origin (mm)
8182
geo.offDetector=[0; 0]; % Offset of Detector (mm)
8283
% These two can be also defined

MATLAB/Demos/d025_OffsetSource.m

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
%% DEMO 03: Generate sample data and add realistic CT noise to it.
2+
%
3+
% This demo will show how to generate sample data for image reconstruction
4+
%
5+
%
6+
%--------------------------------------------------------------------------
7+
%--------------------------------------------------------------------------
8+
% This file is part of the TIGRE Toolbox
9+
%
10+
% Copyright (c) 2015, University of Bath and
11+
% CERN-European Organization for Nuclear Research
12+
% All rights reserved.
13+
%
14+
% License: Open Source under BSD.
15+
% See the full license at
16+
% https://github.com/CERN/TIGRE/blob/master/LICENSE
17+
%
18+
19+
% Codes: https://github.com/CERN/TIGRE/
20+
% Coded by: Ander Biguri
21+
%--------------------------------------------------------------------------
22+
%% Initialize
23+
clear;
24+
close all;
25+
%% Geometry
26+
geo=defaultGeometry();
27+
head=headPhantom(geo.nVoxel);
28+
angles = linspace(0,2*pi,500);
29+
P0=Ax(head,geo,angles,'interpolated');
30+
31+
img_ref = FDK(P0,geo,angles);
32+
imtool(img_ref(:,:,128),[])
33+
34+
offset = 60;
35+
geo1 = geo;
36+
geo1.offSource = [offset;0];
37+
geo1.offDetector = [0;0];
38+
geo1.offOrigin = [0;0;0];
39+
P1=Ax(head,geo1,angles,'interpolated');
40+
41+
img = FDK(P1,geo1,angles);
42+
% show the difference caused by the offset of source
43+
imtool([P0(:,:,100)-P1(:,:,100)],[])
44+
% show the similar reconstruction images
45+
imtool([img_ref(:,:,128),img(:,:,128)],[])

MATLAB/Utilities/checkGeo.m

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
'DSO','DSD'};
77

88
geofields_optional={'offOrigin','offDetector','rotDetector','COR',...
9-
'mode','accuracy'};
9+
'mode','accuracy','offSource'};
1010
allfields=horzcat(geofields_mandatory,geofields_optional);
1111
fnames=fieldnames(geo);
1212
% Find if geo has fields we do not recongize
@@ -128,5 +128,14 @@
128128
end
129129

130130

131+
if isfield(geo,'offSource')
132+
assert(isequal(size(geo.offSource),[2 1]) | isequal(size(geo.offSource),[2 size(angles,2)]),'TIGRE:checkGeo:BadGeometry','geo.offSource Should be 2x1 or 2xsize(angles,2)')
133+
assert(isa(geo.offSource,'double'),'TIGRE:checkGeo:BadGeometry','Field geo.offSource is not double type.' )
134+
if isequal(size(geo.offSource),[2 1])
135+
geo.offSource=repmat(geo.offSource,[1, size(angles,2)]);
136+
end
137+
else
138+
geo.offSource=zeros(2,size(angles,2));
139+
end
131140
end
132141

MATLAB/Utilities/computeV.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
auxgeo.DSD = geo.DSD(auxindex);
2525
auxgeo.DSO = geo.DSO(auxindex);
2626
auxgeo.offOrigin = geo.offOrigin(:,auxindex);
27+
auxgeo.offSource = geo.offSource(:,auxindex);
2728
auxgeo.offDetector = geo.offDetector(:,auxindex);
2829
auxgeo.rotDetector = geo.rotDetector(:,auxindex);
2930
auxgeo.COR = geo.COR(auxindex);
@@ -53,4 +54,3 @@
5354
gpuids=p.Results.gpuids;
5455
end
5556
end
56-

MATLAB/Utilities/cuda_interface/Atb_mex.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ void mexFunction(int nlhs , mxArray *plhs[],
165165
mxArray * geometryMex=(mxArray*)prhs[1];
166166

167167
// IMPORTANT-> Make sure Matlab creates the struct in this order.
168-
const char *fieldnames[14];
168+
const char *fieldnames[15];
169169
fieldnames[0] = "nVoxel";
170170
fieldnames[1] = "sVoxel";
171171
fieldnames[2] = "dVoxel";
@@ -180,6 +180,7 @@ void mexFunction(int nlhs , mxArray *plhs[],
180180
fieldnames[11]= "mode";
181181
fieldnames[12]= "COR";
182182
fieldnames[13]= "rotDetector";
183+
fieldnames[14]= "offSource";
183184
// Make sure input is structure
184185

185186
mxArray *tmp;
@@ -189,13 +190,13 @@ void mexFunction(int nlhs , mxArray *plhs[],
189190

190191
double * nVoxel, *nDetec; //we need to cast these to int
191192
double * sVoxel, *dVoxel,*sDetec,*dDetec, *DSO, *DSD,*offOrig,*offDetec;
192-
double *acc, *COR,*rotDetector;
193+
double *acc, *COR,*rotDetector,*offSource;
193194
const char* mode;
194195
bool coneBeam=true;
195196
Geometry geo;
196197
int c;
197198
geo.unitX=1;geo.unitY=1;geo.unitZ=1;
198-
for(int ifield=0; ifield<14; ifield++) {
199+
for(int ifield=0; ifield<15; ifield++) {
199200
tmp=mxGetField(geometryMex,0,fieldnames[ifield]);
200201
if(tmp==NULL){
201202
//tofix
@@ -314,6 +315,17 @@ void mexFunction(int nlhs , mxArray *plhs[],
314315

315316
}
316317
break;
318+
case 14:
319+
geo.offSourceY=(float*)malloc(nangles * sizeof(float));
320+
geo.offSourceZ=(float*)malloc(nangles * sizeof(float));
321+
322+
offSource=(double *)mxGetData(tmp);
323+
for (int i=0;i<nangles;i++){
324+
c=i;
325+
geo.offSourceY[i]=(float)offSource[0+2*c];
326+
geo.offSourceZ[i]=(float)offSource[1+2*c];
327+
}
328+
break;
317329
default:
318330
mexErrMsgIdAndTxt( "CBCT:MEX:Atb:unknown","This should not happen. Weird");
319331
break;

0 commit comments

Comments
 (0)