~ubuntu-branches/ubuntu/utopic/mricron/utopic

1 by Michael Hanke
Import upstream version 0.20100725.1~dfsg.1
1
unit reslice_fsl;
2
{$H+}
3
interface
4
uses
5
    nifti_hdr,define_types,metagraph,sysutils;
6
7
function ResliceImg (lTargetImgName,lSrcImgName,lSrc2TargetMatName,lOutputName: string): boolean;
8
procedure ResliceFSL;
9
10
implementation
11
12
uses nifti_img_view,dialogs,nifti_img,text,graphx,math,nifti_hdr_view,GraphicsMathLibrary,classes;
13
14
procedure ResliceFSL;
15
label
16
  666;
17
var
18
	lInc,lNumberofFiles: integer;
19
  lSrc2TargetMatName,lSrcImgName,lTargetImgName,lOutputName:string;
20
  lStrings : TStringList;
21
begin
22
	 ImgForm.CloseImagesClick(nil);
23
	  if not OpenDialogExecute(kImgFilter,'Select source image[s]',true) then exit;
24
	  lNumberofFiles:= HdrForm.OpenHdrDlg.Files.Count;
25
    if  lNumberofFiles < 1 then
26
		  exit;
27
    lStrings := TStringList.Create;
28
    lStrings.AddStrings(HdrForm.OpenHdrDlg.Files);
29
	  if not OpenDialogExecute('FSL (*.mat)|*.mat','Select FSL source-to-target matrix',false) then goto 666;
30
    lSrc2TargetMatName :=  HdrForm.OpenHdrDlg.Filename;
31
	  if not OpenDialogExecute(kImgFilter,'Select target image (source image will be warped to this)',false) then goto 666;
32
    lTargetImgName :=  HdrForm.OpenHdrDlg.Filename;
33
1.1.1 by Michael Hanke
Import upstream version 0.20100820.1~dfsg.1
34
    TextForm.MemoT.Lines.Clear;
1 by Michael Hanke
Import upstream version 0.20100725.1~dfsg.1
35
    for lInc:= 1 to lNumberofFiles do begin
36
            lSrcImgName := lStrings[lInc-1];
37
            lOutputName := ChangeFilePrefix (lSrcImgName,'w');
1.1.1 by Michael Hanke
Import upstream version 0.20100820.1~dfsg.1
38
            TextForm.MemoT.Lines.Add(' Source->Matrix->Target '+lSrcImgName+'->'+ lSrc2TargetMatName+'->'+lTargetImgName);
1 by Michael Hanke
Import upstream version 0.20100725.1~dfsg.1
39
            ResliceImg (lTargetImgName,lSrcImgName,lSrc2TargetMatName,lOutputName);
40
    end;//lLoop
41
        TextForm.Show;
42
        666:
43
    lStrings.free;
44
end;
45
46
function ReadFSLMat (var lMat: TMatrix; lSrc2TargetMatName: string):boolean;
47
var
48
   lF: TextFile;
49
   xx,xy,xz,xo
50
   ,yx,yy,yz,yo
51
   ,zx,zy,zz,zo: double;
52
begin
53
     result := false;
54
     if not fileexists(lSrc2TargetMatName) then exit;
55
     Assign(lF,lSrc2TargetMatName);
56
     Filemode := 0;
57
     Reset(lF);
58
     readln(lF,xx,xy,xz,xo,yx,yy,yz,yo,zx,zy,zz,zo);
59
      //read all with one readln -
60
      // separate readlns only work for native eoln
61
     CloseFile(lF);
62
          lMat:= Matrix3D (xx,xy,xz,xo
63
   ,yx,yy,yz,yo
64
   ,zx,zy,zz,zo
65
						  ,0,0,0,1);
66
    result := true;
67
    Filemode := 2;
68
end;
69
70
function Rx (var lDestHdr,lSrcHdr: TMRIcroHdr; var lInMat: TMatrix; var lOutputName: string):boolean;
71
var
72
   lPos,lXYs,lXYZs,lXs,lYs,lZs,lXi,lYi,lZi,lX,lY,lZ,
73
   lXo,lYo,lZo,lMinY,lMinZ,lMaxY,lMaxZ: integer;
74
   lXrM1,lYrM1,lZrM1,
75
   lXreal,lYreal,lZreal: double;
76
   lOutImg: bytep;
77
   lScale,lMat: TMatrix;
78
begin
79
     result := false;
80
     lXs := lSrcHdr.NIFTIhdr.Dim[1];
81
     lYs := lSrcHdr.NIFTIhdr.Dim[2];
82
     lZs := lSrcHdr.NIFTIhdr.Dim[3];
83
     if (gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems <> lXs*lYs*lZs) then begin
84
        showmessage('Reslice error: background image not loaded.');
85
        exit;
86
     end;
87
     lXYs:=lXs*lYs; //slicesz
88
     lXYZs := lXYs*lZs;
89
     lX := lDestHdr.NIFTIhdr.Dim[1];
90
     lY := lDestHdr.NIFTIhdr.Dim[2];
91
     lZ := lDestHdr.NIFTIhdr.Dim[3];
92
     //TextForm.Memo1.Lines.Add(inttostr(lXs)+'x'+inttostr(lYs)+'x'+inttostr(lZs)+'->'+inttostr(lX)+'x'+inttostr(lY)+'x'+inttostr(lZ));
93
     lDestHdr.NIFTIhdr.Dim[4] := 1;
94
     getmem(lOutImg, lX*lY*lZ*sizeof(byte));
95
     lPos := 0;
96
     //http://eeg.sourceforge.net/MJenkinson_coordtransforms.pdf
97
     //FLIRT transforms are in world coordinates [mm]
98
     //to convert to a vxl-vxl transform, the matrix must be
99
     //PRE-multiplied by inv(Dest) and POST-multiplied by Src
100
     //where Dest and Src are the spatial dimensions in mm
101
lScale:= Matrix3D (abs(lSrcHdr.NIFTIhdr.pixdim[1]),0,0,0
102
   ,0,abs(lSrcHdr.NIFTIhdr.pixdim[2]),0,0
103
   ,0,0,abs(lSrcHdr.NIFTIhdr.pixdim[3]),0
104
						  ,0,0,0,1);
105
   lScale := InvertMatrix3D(lScale);
106
   lMat := MultiplyMatrices(lScale,lInMat);
107
   lScale:= Matrix3D (abs(lDestHdr.NIFTIhdr.pixdim[1]),0,0,0
108
   ,0,abs(lDestHdr.NIFTIhdr.pixdim[2]),0,0
109
   ,0,0,abs(lDestHdr.NIFTIhdr.pixdim[3]),0
110
						  ,0,0,0,1);
111
   lMat := MultiplyMatrices(lMat,lScale);
112
     for lZi := 0 to (lZ-1) do begin
113
         for lYi := 0 to (lY-1) do begin
114
             for lXi := 0 to (lX-1) do begin
115
                 inc(lPos);
116
                 lOutImg^[lPos] := 0;
117
                 lXreal := (lXi*lMat.matrix[1][1]+lYi*lMat.matrix[1][2]+lZi*lMat.matrix[1][3]+lMat.matrix[1][4]);
118
                 lYreal := (lXi*lMat.matrix[2][1]+lYi*lMat.matrix[2][2]+lZi*lMat.matrix[2][3]+lMat.matrix[2][4]);
119
                 lZreal := (lXi*lMat.matrix[3][1]+lYi*lMat.matrix[3][2]+lZi*lMat.matrix[3][3]+lMat.matrix[3][4]);
120
                 //need to test Xreal as -0.01 truncates to zero
121
                 if (lXreal >= 0) and (lYreal >= 1) and (lZreal >= 1) and
122
                     (lXreal < (lXs -1)) and (lYreal < (lYs -1) ) and (lZreal < (lZs -1))
123
                  then begin
124
			        lXo := trunc(lXreal);
125
			        lYo := trunc(lYreal);
126
			        lZo := trunc(lZreal);
127
			        lXreal := lXreal-lXo;
128
			        lYreal := lYreal-lYo;
129
			        lZreal := lZreal-lZo;
130
			        lXrM1 := 1-lXreal;
131
			        lYrM1 := 1-lYreal;
132
			        lZrM1 := 1-lZreal;
133
			        lMinY := ((lYo)*lXs);
134
			        lMinZ := ((lZo)*lXYs);
135
			        lMaxY := ((lYo+1)*lXs);
136
			        lMaxZ := ((lZo+1)*lXYs);
137
                    inc(lXo);//images incremented from 1 not 0
138
                    {if lMax <(lXreal) then
139
                       lMax := lXreal;
140
                    if lMin >(lXreal) then
141
                       lMin := lXreal;  }
142
                          lOutImg^[lPos] :=
143
                           round (
144
		 	   {all min} ( (lXrM1*lYrM1*lZrM1)*gMRIcroOverlay[kBGOverlayNum].ScrnBuffer^[lXo+lMinY+lMinZ])
145
			   {x+1}+((lXreal*lYrM1*lZrM1)*gMRIcroOverlay[kBGOverlayNum].ScrnBuffer^[lXo+1+lMinY+lMinZ])
146
			   {y+1}+((lXrM1*lYreal*lZrM1)*gMRIcroOverlay[kBGOverlayNum].ScrnBuffer^[lXo+lMaxY+lMinZ])
147
			   {z+1}+((lXrM1*lYrM1*lZreal)*gMRIcroOverlay[kBGOverlayNum].ScrnBuffer^[lXo+lMinY+lMaxZ])
148
			   {x+1,y+1}+((lXreal*lYreal*lZrM1)*gMRIcroOverlay[kBGOverlayNum].ScrnBuffer^[lXo+1+lMaxY+lMinZ])
149
			   {x+1,z+1}+((lXreal*lYrM1*lZreal)*gMRIcroOverlay[kBGOverlayNum].ScrnBuffer^[lXo+1+lMinY+lMaxZ])
150
			   {y+1,z+1}+((lXrM1*lYreal*lZreal)*gMRIcroOverlay[kBGOverlayNum].ScrnBuffer^[lXo+lMaxY+lMaxZ])
151
			   {x+1,y+1,z+1}+((lXreal*lYreal*lZreal)*gMRIcroOverlay[kBGOverlayNum].ScrnBuffer^[lXo+1+lMaxY+lMaxZ]) );
152
                 end;
153
             end;//z
154
         end;//y
155
     end;//z
156
     deletefile(lOutputName);
157
     SaveAsVOIorNIFTIcore (lOutputName,lOutImg, lX*lY*lZ, 1,1,lDestHdr.NIFTIhdr);
158
     lPos := 1;
159
     while (lPos <= (lX*lY*lZ)) and (lOutImg^[lPos] = 0) do
160
           inc(lPos);
161
     if lPos > (lX*lY*lZ) then
162
        result := false
163
     else
164
         result := true;
165
     freemem(lOutImg);
166
end;
167
168
function ResliceImg (lTargetImgName,lSrcImgName,lSrc2TargetMatName,lOutputName: string): boolean;
169
label
170
 666;
171
var
172
   lReslice,lOrtho : boolean;
173
   lDestHdr,lSrcHdr: TMRIcroHdr;
174
   lMat: TMatrix;
175
begin
176
     result := false;
177
     if not fileexists(lTargetImgName) then exit;
178
     if not fileexists(lSrcImgName) then exit;
179
     if not fileexists(lSrc2TargetMatName) then exit;
180
     if not ReadFSLMat(lMat,lSrc2TargetMatName) then exit;
181
     ImgForm.CloseImagesClick(nil);
182
     lReslice := gBGImg.ResliceOnLoad;
183
     lOrtho := gBGImg.OrthoReslice;
184
     gBGImg.OrthoReslice := false;
185
     gBGImg.ResliceOnLoad := false;
186
     //if not HdrForm.OpenAndDisplayHdr(lTargetImgName,lDestHdr) then goto 666;
187
     if not NIFTIhdr_LoadHdr(lTargetImgName, lDestHdr) then goto 666;
188
     if not NIFTIhdr_LoadHdr(lSrcImgName, lSrcHdr) then goto 666;
189
     ImgForm.OpenAndDisplayImg(lSrcImgName,True);
190
     if not Rx(lDestHdr,lSrcHdr,lMat,lOutputName) then goto 666;
191
     result := true;
192
666:
193
     if not result then
194
        showmessage('Error applying transform '+lSrcImgName+'->'+lTargetImgName+' using '+lSrc2TargetMatName);
195
     gBGImg.ResliceOnLoad := lReslice;
196
     gBGImg.OrthoReslice := lOrtho;
197
end;
198
199
200
end.
201