-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathslice3i.m
196 lines (167 loc) · 4.78 KB
/
slice3i.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
function h = slice3i(vol, I2X, slicedim, sliceidx, handle)
% Display a slice from a volume in 3-D
% h = slice3(vol, I2X, slicedim, sliceidx, handle)
%
% Vol is either a scalar or RGB volume, e.g. N x M x K or N x M x K x 3.
% I2X is a transformation matrix from volume coordinates to xyz 3-D world
% coordinates, similar to the transform used by image3i.
%
% [x y z 1]' = I2X * [i j k 1]'
%
% slicedim is 1, 2 or 3 and corresponds to i, j and k.
% sliceidx the index of the slice along slicedim
% handle an optional handle to a previous slice to reuse
% h the handle to the created slice.
%
% Example:
%
% load mri;
% T = [1 0 0 0;0 1 0 0;0 0 2.5 0];
% h1 = slice3i(squeeze(D),T,1,64);
% h2 = slice3i(squeeze(D),T,2,64);
% h3 = slice3i(squeeze(D),T,3,14);
% colormap gray(88);
% view(30,45); axis equal;
%
% SEE ALSO: image3i, imagesc3
%
% Author: Anders Brun, [email protected] (2009)
%
% Modified by Qianqian Fang, q.fang at neu.edu
%
% Features added:
% 1) compatible with octave 4.0 or newer
% 2) start 3D rotation by clicking/holding the middle mouse key
% 3) adjust colormap levels by dragging with the right mouse key
% 4) support 4-D data (up/down key to change frames)
%
try
h = update_slice(vol, I2X, slicedim, sliceidx, h);
catch
h = update_slice(vol, I2X, slicedim, sliceidx);
end
% set up gui
gui.handle = h;
gui.vol = vol;
gui.I2X = I2X;
gui.slicedim = slicedim;
gui.sliceidx = sliceidx;
set(gui.handle,'ButtonDownFcn',@startmovit);
set(h,'UserData',gui);
function stoprotate(src,hrot)
if strcmp(get(gcf,'SelectionType'), 'extend')
rotate3d off;
end
function startmovit(src,evnt)
if strcmp(get(gcf,'SelectionType'), 'extend')
rotate3d on;
return;
end
% Unpack gui object
gui = get(src,'UserData');
%turn off mouse pointer
%set(gcf,'PointerShapeCData',nan(16,16));
%set(gcf,'Pointer','custom');
thisfig = gcbf();
gui.startray = get(gca,'CurrentPoint');
gui.startidx = gui.sliceidx;
gui.p0=get(gcf,'currentpoint');
gui.level0=size(colormap,1);
% Store gui object
set(src,'UserData',gui);
set(thisfig,'WindowButtonMotionFcn',@movit);
set(thisfig,'WindowButtonUpFcn',@stopmovit);
set(thisfig,'UserData',src);
function movit(src,evnt)
% Unpack gui object
gui = get(get(gcf,'UserData'),'UserData');
% Some safetymeasures
try
if isequal(gui.startray,[])
return
end
catch
end
if strcmp(get(gcf,'SelectionType'), 'alt')
if(isempty(gui) || ~isfield(gui,'p0'))
return;
end
delta=get(gcf,'currentpoint')-gui.p0;
windim=get(gcf,'position');
delta=delta./windim(3:4);
currentlevel=round(gui.level0+delta(2)/4*256);
if(currentlevel>256)
currentlevel=256;
elseif(currentlevel<8)
currentlevel=8;
end
colormap(jet(currentlevel));
return;
end
% Do "smart" positioning of the markers...
nowray = get(gca,'CurrentPoint');
% Project rays on slice-axis
s = gui.I2X(1:3,gui.slicedim);
a = gui.startray(1,:)';
b = gui.startray(2,:)';
alphabeta = pinv([s'*s, -s'*(b-a);(b-a)'*s, -(b-a)'*(b-a)])*[s'*a, (b-a)'*a]';
pstart = alphabeta(1)*s;
alphastart = alphabeta(1);
a = nowray(1,:)';
b = nowray(2,:)';
alphabeta = pinv([s'*s, -s'*(b-a);(b-a)'*s, -(b-a)'*(b-a)])*[s'*a, (b-a)'*a]';
pnow = alphabeta(1)*s;
alphanow = alphabeta(1);
slicediff = alphanow-alphastart;
gui.sliceidx = gui.startidx+slicediff;
gui.sliceidx = min(max(1,gui.sliceidx),size(gui.vol,gui.slicedim));
update_slice(gui.vol, gui.I2X, gui.slicedim, gui.sliceidx, gui.handle);
drawnow;
% Store gui object
set(get(gcf,'UserData'),'UserData',gui);
function stopmovit(src,evnt)
thisfig = gcbf();
%set(gcf,'Pointer','arrow');
set(thisfig,'WindowButtonUpFcn','');
set(thisfig,'WindowButtonMotionFcn','');
gui = get(get(gcf,'UserData'),'UserData');
gui.startray = [];
%gui.sliceidx = gui.nextsliceidx
set(get(gcf,'UserData'),'UserData',gui);
set(gcf,'UserData',[]);
drawnow;
function h = update_slice(vol, I2X, slicedim, sliceidx, handle)
if ndims(vol) == 3 %Scalar mode
elseif ndims(vol) == 4 %RGB mode
if(size(vol,4)>3)
gui = get(get(gcf,'UserData'),'UserData');
if(~isempty(gui) && isfield(gui,'frame'))
vol=gui.vol(:,:,:,gui.frame);
else
vol=gui.vol(:,:,:,1);
end
end
else
error('Only scalar and RGB images supported')
end
% Create the slice
if slicedim == 3 % k
ij2xyz = I2X(:,[1 2]);
ij2xyz(:,3) = I2X*[0 0 sliceidx 1]';
sliceim = squeeze(vol(:,:,round(sliceidx),:));
elseif slicedim == 2 % j
ij2xyz = I2X(:,[1 3]);
ij2xyz(:,3) = I2X*[0 sliceidx 0 1]';
sliceim = squeeze(vol(:,round(sliceidx),:,:));
elseif slicedim == 1 % i
ij2xyz = I2X(:,[2 3]);
ij2xyz(:,3) = I2X*[sliceidx 0 0 1]';
sliceim = squeeze(vol(round(sliceidx),:,:,:));
else
error('Slicedim should be 1, 2 or 3')
end
if nargin<5 || handle == 0
h = image3i(sliceim,ij2xyz);
else
h = image3i(sliceim,ij2xyz,handle);
end