📄 sliceomatic.m
字号:
function sliceomatic(p1,p2)% SLICEOMATIC - Slice and isosurface volume exploration GUI%% SLICEOMATIC(DATA) - Use 3D double matrix DATA as a volume data%% Example:%% [x,y,z] = meshgrid(-2:.2:2, -2:.25:2, -2:.16:2);% v = x .* exp(-x.^2 - y.^2 - z.^2);% sliceomatic(v)%% Using SLICEOMATIC with no arguments is equivalent to the above% example.%% Using the GUI:% -------------% The white bars on the top, left, and right allow insertion of% new slices on the X, Y, and Z planes. Click in an empty area to% add a new slice or surface. Click on a control arrow to add a% new slice or surface.%% The colored bar at the bottom is used to place and position an% isosurface. The color in the bar indicates a position (as seen% in the slice) where the isosurface will go.%% When the rotate camera button is on, the popup menu will control% the camera. Turn off camera rotation in order to get individual% control over properties of the slices and isosurfaces.%% The defaults menu provides default features of newly created% slices and surfaces. The AllSlices menu controls properties of% all the slices and surfaces in the scene. Use popup menus on the% objects themselves, or the control arrows to change indivudual% properties.%% If the data is very large, a reduced model of the data is created.% This reduced data set is used for interactivly positioning% isosurfaces.%% The Colormap popdown controls the currenlty active colormap.% This map is used to color the slices. The Alphamap popdown% controls the alphamap used on the slices.%% Doing Cool Stuff:% ----------------%% Exploration:% You can get a quick feel of the current data set by adding a% slice using the ColorTexture option. Such a slice can be dragged% through the data very quickly.%% Highlight an Area:% If certain values in your data are interesting (very large, very% small, or very median values) you can use transparency to make% parts of your slices disappear. Choose AlphaTexture options from% the defaults, and sweep some slices across your data. Use the% AlphaMap to pick out certain data sets. The exaple given here% looks best with the `vdown' alphamap.%% You can also add a contour onto a slice to further extract shapes% from the data you are exploring.%% Hidden Shapes:% Use the isosurface control bar to create an isosurface. Be% patient with this control. It often takes a while for the% surface to be created. Click and hold the mouse button down% until the first surface appears. Drag the surface through the% values until you get something you like, then let go. If your% data set is very large, you will need to wait while the new and% more accurate isosurface is created.%% Volumes:% You can simulate a volume object by creating lots of stacked% slices. Simply use the proper Alphamap and transparent textures% to highlight the correct data, and a large stack of slices will% let you simulate a volume object.%% BUGS:% ----%% 1) Sliceomatic does not use the `slice' command. All slices are% created by explicitly extracting data from the volume. As such,% only slices at integer values are allowed.% %% See Also: SLICE, ISOSURFACE, ISOCAPS, CONTOURC, COLORMAP, SURFACE % This is version 2.0 of sliceomatic.%% Sliceomatic is a tool I wrote for fun. There are no warrenties% expressed or implied.% Written by Eric Ludlam <eludlam@mathworks.com>% Copyright 2000, 2001, 2002 The MathWorks Inc% % Slightly modified to work with MIA_gui.m (medical image analysis) by Laszlo Balkay% (balkay@pet.dote.hu). 2003% 1. at the startup the program sets up 3 default slices at the half of the axis% 2. scaling the axis (DataAspectRatio) regarding the pixelsize of the input volume% The pixelsize info should come from the "scaninfo" structure by the p2 argin.% 3. If the size(volume,1 or 2) > 128, then the volume will be resized to 128*128*size(volume,3) % 4. more colormap is added to the sliceomaticfigure.m if nargin==0 [x,y,z] = meshgrid(-2:.2:2, -2:.25:2, -2:.16:2); v = x .* exp(-x.^2 - y.^2 - z.^2); sliceomatic(v) return end if isa(p1,'double')% $$$ if nargin==4% $$$ d.Xv=p1;% $$$ d.Yv=p2;% $$$ d.Zv=p3% $$$ p1=p4;% $$$ else% $$$ d.Yv=1:size(p1,1);% $$$ d.Xv=1:size(p1,2);% $$$ d.Zv=1:size(p1,3);% $$$ end scaninfo = p2; RenderSize = 128; imaVOL = uint16(p1); if scaninfo.imfm(1) > RenderSize % setting up the progression bar info.color=[1 0 0]; info.title='Sliceomatic in progress ...'; info.size=1; info.pos='topleft'; hpbar = progbar(info); imaVOLr = uint16(zeros(RenderSize,RenderSize,scaninfo.num_of_slice)); for i = 1: scaninfo.num_of_slice progbar(hpbar,round(i/scaninfo.num_of_slice*100)); imaVOLr(:,:,i) = imresize(imaVOL(:,:,i), [RenderSize RenderSize],'bilinear'); end close(hpbar); else imaVOLr = imaVOL; end d.data=double(imaVOLr); d.UseGenericOpenGL = scaninfo.UseGenericOpenGL; pixsize = scaninfo.pixsize; d = sliceomaticfigure(d); d = sliceomaticsetdata(d); setappdata(gcf,'sliceomatic',d); %set the axis aspect ratio referring to the pixelsize info currPBA = get(gca,'PlotBoxAspectratio'); %DataAspectRatio = [size(d.data,1)*pixsize(1) ... % size(d.data,2)*pixsize(2) size(d.data,3)*pixsize(3)]; %set(gca,'DataAspectRatio',DataAspectRatio.*(currPBA)); newPBA = [size(imaVOL,1)*pixsize(1) ... size(imaVOL,2)*pixsize(2) size(imaVOL,3)*pixsize(3)]; set(gca,'DataAspectRatioMode','auto'); set(gca,'PlotBoxAspectRatio',newPBA); setappdata(gcf,'sliceomatic',d); zoom(1.2); colormap(scaninfo.colormap); %set up the default X slice hX = findall(gcf,'tag','Xslice'); %axis(hX); X = round(size(d.data,1)/2); newa=arrow(hX,'down',[X 0]); set(gcf,'currentaxes',d.axmain); new=localslice(d.data, X, [], []); setappdata(new,'controlarrow',newa); setappdata(newa(2),'arrowslice',new); set(new,'alphadata',get(new,'cdata'),'alphadatamapping','scaled'); set(newa,'buttondownfcn','sliceomatic Xmove'); set([new newa],'uicontextmenu',d.uic); d.draggedarrow=newa(2); dragprep(newa(2)); setpointer(gcf,'SOM leftright'); set(d.motionmetaslice,'visible','off'); dragfinis(d.draggedarrow); setappdata(gcf,'sliceomatic',d);%set up the default Y slice hY = findall(gcf,'tag','Yslice'); axis(hY); Y = round(size(d.data,2)/2); newa=arrow(hY,'right',[0 Y]); set(gcf,'currentaxes',d.axmain); new=localslice(d.data, [], Y, []); setappdata(new,'controlarrow',newa); setappdata(newa(2),'arrowslice',new); set(new,'alphadata',get(new,'cdata'),'alphadatamapping','scaled'); set(newa,'buttondownfcn','sliceomatic Ymove'); set([new newa],'uicontextmenu',d.uic); d.draggedarrow=newa(2); dragprep(newa(2)); setpointer(gcf,'SOM topbottom'); set(d.motionmetaslice,'visible','off'); dragfinis(d.draggedarrow); setappdata(gcf,'sliceomatic',d);%set up the default Z slice hZ = findall(gcf,'tag','Zslice'); axis(hZ); Z = round(size(d.data,3)/2); newa=arrow(hZ,'left', [0 Z]); set(gcf,'currentaxes',d.axmain); new=localslice(d.data, [], [], Z); set(new,'alphadata',get(new,'cdata'),'alphadatamapping','scaled'); setappdata(new,'controlarrow',newa); setappdata(newa(2),'arrowslice',new); set(newa,'buttondownfcn','sliceomatic Zmove'); set([new newa],'uicontextmenu',d.uic); d.draggedarrow=newa(2); dragprep(newa(2)); setpointer(gcf,'SOM topbottom'); set(d.motionmetaslice,'visible','off'); dragfinis(d.draggedarrow); setappdata(gcf,'sliceomatic',d); else % Interpret commands d=getappdata(gcf,'sliceomatic'); try switch p1 case 'Xnew' if strcmp(get(gcf,'selectiontype'),'normal') pt=get(gcbo,'currentpoint'); axis(gcbo); X=pt(1,1); newa=arrow(gcbo,'down',[X 0]); set(gcf,'currentaxes',d.axmain); new=localslice(d.data, X, [], []); setappdata(new,'controlarrow',newa); setappdata(newa(2),'arrowslice',new); set(new,'alphadata',get(new,'cdata'),'alphadatamapping','scaled'); set(newa,'buttondownfcn','sliceomatic Xmove'); set([new newa],'uicontextmenu',d.uic); % Make sure whatever buttonupfcn on the figure is run now to "turn % off" whatever was going on before we got our callback on the % arrow. buf = get(gcf,'windowbuttonupfcn'); if ~strcmp(buf,'') eval(buf); end d.draggedarrow=newa(2); dragprep(newa(2)); setpointer(gcf,'SOM leftright'); set(d.motionmetaslice,'visible','off'); end case 'Ynew' if strcmp(get(gcf,'selectiontype'),'normal') pt=get(gcbo,'currentpoint'); Y=pt(1,2); newa=arrow(gcbo,'right',[0 Y]); set(gcf,'currentaxes',d.axmain); new=localslice(d.data, [], Y, []); setappdata(new,'controlarrow',newa); setappdata(newa(2),'arrowslice',new); set(new,'alphadata',get(new,'cdata'),'alphadatamapping','scaled'); set(newa,'buttondownfcn','sliceomatic Ymove'); set([new newa],'uicontextmenu',d.uic); % Make sure whatever buttonupfcn on the figure is run now to "turn % off" whatever was going on before we got our callback on the % arrow. buf = get(gcf,'windowbuttonupfcn'); if ~strcmp(buf,'') eval(buf); end d.draggedarrow=newa(2); dragprep(newa(2)); setpointer(gcf,'SOM topbottom'); set(d.motionmetaslice,'visible','off'); end % if strcmp(get(gcf, case 'Znew' if strcmp(get(gcf,'selectiontype'),'normal') pt=get(gcbo,'currentpoint'); Y=pt(1,2); newa=arrow(gcbo,'left', [0 Y]); set(gcf,'currentaxes',d.axmain); new=localslice(d.data, [], [], Y); set(new,'alphadata',get(new,'cdata'),'alphadatamapping','scaled'); setappdata(new,'controlarrow',newa); setappdata(newa(2),'arrowslice',new); set(newa,'buttondownfcn','sliceomatic Zmove'); set([new newa],'uicontextmenu',d.uic); % Make sure whatever buttonupfcn on the figure is run now to "turn % off" whatever was going on before we got our callback on the % arrow. buf = get(gcf,'windowbuttonupfcn'); if ~strcmp(buf,'') eval(buf); end d.draggedarrow=newa(2); dragprep(newa(2)); setpointer(gcf,'SOM topbottom'); set(d.motionmetaslice,'visible','off'); end % if strcmp(get(gcf, case 'ISO' if strcmp(get(gcf,'selectiontype'),'normal') pt=get(gcbo,'currentpoint'); V=pt(1,1); newa=arrow(gcbo,'up',[V 0]); set(gcf,'currentaxes',d.axmain); new=localisosurface(d.reducelims,d.reduce,d.reducesmooth,V); set([newa new],'uicontextmenu',d.uiciso); setappdata(new,'controlarrow',newa); setappdata(new,'reduced',1); setappdata(newa(2),'arrowiso',new); set(newa,'buttondownfcn','sliceomatic ISOmove'); % Make sure whatever buttonupfcn on the figure is run now to "turn % off" whatever was going on before we got our callback on the % arrow. buf = get(gcf,'windowbuttonupfcn'); if ~strcmp(buf,'') eval(buf); end d.draggedarrow=newa(2); dragprep(newa(2)); setpointer(gcf,'SOM leftright'); end % if strcmp(get(gcf, case 'Xmove' if strcmp(get(gcf,'selectiontype'),'normal') [a s]=getarrowslice; d.draggedarrow=a; dragprep(a); end case 'Ymove' if strcmp(get(gcf,'selectiontype'),'normal') [a s]=getarrowslice; d.draggedarrow=a; dragprep(a); end case 'Zmove' if strcmp(get(gcf,'selectiontype'),'normal') [a s]=getarrowslice; d.draggedarrow=a; dragprep(a); end case 'ISOmove' if strcmp(get(gcf,'selectiontype'),'normal') [a s]=getarrowslice; d.draggedarrow=a; dragprep(a); end case 'up' if strcmp(get(gcf,'selectiontype'),'normal') dragfinis(d.draggedarrow); end case 'motion' % Make sure our cursor is ok a=d.draggedarrow; % The arrow being dragged s=getappdata(a,'arrowslice'); % The slice to 'move' if isempty(s) s=getappdata(a,'arrowiso'); % or the isosurface end aa=get(a,'parent'); % arrow's parent axes pos=getappdata(a,'arrowcenter'); % the line the arrow points at. apos=get(aa,'currentpoint'); if aa==d.axx | aa==d.axiso % We are moving an X slice xdiff=apos(1,1)-pos(1,1); v=get(a,'vertices'); v(:,1)=v(:,1)+xdiff; set([a getappdata(a,'arrowedge')],'vertices',v); np=[ apos(1,1) 0 ]; % This might be a slice, or an isosurface! if aa==d.axiso new=localisosurface(d.reducelims,d.reduce,d.reducesmooth,... apos(1,1),s); setappdata(new,'reduced',1); movetipforarrow(d.tip, aa, apos(1,1), [ apos(1,1) 6 ], 'bottom','center') else if round(apos(1,1))~=round(pos(1,1)) localslice(d.data, apos(1,1), [], [],s); end movetipforarrow(d.tip, aa, apos(1,1), [ apos(1,1) .5 ],'top','center') end else % We are moving a Y or Z slice ydiff=apos(1,2)-pos(1,2); v=get(a,'vertices'); v(:,2)=v(:,2)+ydiff; set([a getappdata(a,'arrowedge')],'vertices',v); np=[ 0 apos(1,2) ]; if aa==d.axy if round(apos(1,2))~=round(pos(1,2)) localslice(d.data, [], apos(1,2), [], s); end movetipforarrow(d.tip, aa, apos(1,2), [ 5.5 apos(1,2) ], 'middle','left'); else if round(apos(1,2))~=round(pos(1,2)) localslice(d.data, [], [], apos(1,2), s); end movetipforarrow(d.tip, aa, apos(1,2), [ .5 apos(1,2) ], 'middle','right'); end end setappdata(a,'arrowcenter',np); drawnow; % % IsoSurface context menu items % case 'isotogglevisible' [a s]=getarrowslice; if propcheck(s,'visible','on') set(s,'visible','off'); else set(s,'visible','on'); end case 'isodelete' [a s]=getarrowslice; if numel(a)==1 delete(getappdata(a,'arrowedge')); end cap=getappdata(s,'sliceomaticisocap'); if ~isempty(cap) delete(cap); end delete(s); delete(a); case 'isoflatlight' [a s]=getarrowslice; set(s,'facelighting','flat'); case 'isosmoothlight' [a s]=getarrowslice; set(s,'facelighting','phong'); case 'isocolor' [a s]=getarrowslice; c=uisetcolor(get(s,'facecolor')); set(s,'facecolor',c);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -