|
@@ -1,291 +0,0 @@
|
|
|
-function imshow3D( Img, disprange )
|
|
|
-%IMSHOW3D displays 3D grayscale images in slice by slice fashion with mouse
|
|
|
-%based slice browsing and window and level adjustment control.
|
|
|
-%
|
|
|
-% Usage:
|
|
|
-% imshow3D ( Image )
|
|
|
-% imshow3D ( Image , [] )
|
|
|
-% imshow3D ( Image , [LOW HIGH] )
|
|
|
-%
|
|
|
-% Image: 3D image MxNxK (K slices of MxN images)
|
|
|
-% [LOW HIGH]: display range that controls the display intensity range of
|
|
|
-% a grayscale image (default: the widest available range)
|
|
|
-%
|
|
|
-% Use the scroll bar or mouse scroll wheel to switch between slices. To
|
|
|
-% adjust window and level values keep the mouse right button pressed and
|
|
|
-% drag the mouse up and down (for level adjustment) or right and left (for
|
|
|
-% window adjustment).
|
|
|
-%
|
|
|
-% "Auto W/L" button adjust the window and level automatically
|
|
|
-%
|
|
|
-% While "Fine Tune" check box is checked the window/level adjustment gets
|
|
|
-% 16 times less sensitive to mouse movement, to make it easier to control
|
|
|
-% display intensity rang.
|
|
|
-%
|
|
|
-% Note: The sensitivity of mouse based window and level adjustment is set
|
|
|
-% based on the user defined display intensity range; the wider the range
|
|
|
-% the more sensitivity to mouse drag.
|
|
|
-%
|
|
|
-%
|
|
|
-% Example
|
|
|
-% --------
|
|
|
-% % Display an image (MRI example)
|
|
|
-% load mri
|
|
|
-% Image = squeeze(D);
|
|
|
-% figure,
|
|
|
-% imshow3D(Image)
|
|
|
-%
|
|
|
-% % Display the image, adjust the display range
|
|
|
-% figure,
|
|
|
-% imshow3D(Image,[20 100]);
|
|
|
-%
|
|
|
-% See also IMSHOW.
|
|
|
-
|
|
|
-%
|
|
|
-% - Maysam Shahedi (mshahedi@gmail.com)
|
|
|
-% - Released: 1.0.0 Date: 2013/04/15
|
|
|
-% - Revision: 1.1.0 Date: 2013/04/19
|
|
|
-%
|
|
|
-
|
|
|
-sno = size(Img,3); % number of slices
|
|
|
-S = round(sno/2);
|
|
|
-
|
|
|
-global InitialCoord;
|
|
|
-
|
|
|
-MinV = 0;
|
|
|
-MaxV = max(Img(:));
|
|
|
-LevV = (double( MaxV) + double(MinV)) / 2;
|
|
|
-Win = double(MaxV) - double(MinV);
|
|
|
-WLAdjCoe = (Win + 1)/1024;
|
|
|
-FineTuneC = [1 1/16]; % Regular/Fine-tune mode coefficients
|
|
|
-
|
|
|
-if isa(Img,'uint8')
|
|
|
- MaxV = uint8(Inf);
|
|
|
- MinV = uint8(-Inf);
|
|
|
- LevV = (double( MaxV) + double(MinV)) / 2;
|
|
|
- Win = double(MaxV) - double(MinV);
|
|
|
- WLAdjCoe = (Win + 1)/1024;
|
|
|
-elseif isa(Img,'uint16')
|
|
|
- MaxV = uint16(Inf);
|
|
|
- MinV = uint16(-Inf);
|
|
|
- LevV = (double( MaxV) + double(MinV)) / 2;
|
|
|
- Win = double(MaxV) - double(MinV);
|
|
|
- WLAdjCoe = (Win + 1)/1024;
|
|
|
-elseif isa(Img,'uint32')
|
|
|
- MaxV = uint32(Inf);
|
|
|
- MinV = uint32(-Inf);
|
|
|
- LevV = (double( MaxV) + double(MinV)) / 2;
|
|
|
- Win = double(MaxV) - double(MinV);
|
|
|
- WLAdjCoe = (Win + 1)/1024;
|
|
|
-elseif isa(Img,'uint64')
|
|
|
- MaxV = uint64(Inf);
|
|
|
- MinV = uint64(-Inf);
|
|
|
- LevV = (double( MaxV) + double(MinV)) / 2;
|
|
|
- Win = double(MaxV) - double(MinV);
|
|
|
- WLAdjCoe = (Win + 1)/1024;
|
|
|
-elseif isa(Img,'int8')
|
|
|
- MaxV = int8(Inf);
|
|
|
- MinV = int8(-Inf);
|
|
|
- LevV = (double( MaxV) + double(MinV)) / 2;
|
|
|
- Win = double(MaxV) - double(MinV);
|
|
|
- WLAdjCoe = (Win + 1)/1024;
|
|
|
-elseif isa(Img,'int16')
|
|
|
- MaxV = int16(Inf);
|
|
|
- MinV = int16(-Inf);
|
|
|
- LevV = (double( MaxV) + double(MinV)) / 2;
|
|
|
- Win = double(MaxV) - double(MinV);
|
|
|
- WLAdjCoe = (Win + 1)/1024;
|
|
|
-elseif isa(Img,'int32')
|
|
|
- MaxV = int32(Inf);
|
|
|
- MinV = int32(-Inf);
|
|
|
- LevV = (double( MaxV) + double(MinV)) / 2;
|
|
|
- Win = double(MaxV) - double(MinV);
|
|
|
- WLAdjCoe = (Win + 1)/1024;
|
|
|
-elseif isa(Img,'int64')
|
|
|
- MaxV = int64(Inf);
|
|
|
- MinV = int64(-Inf);
|
|
|
- LevV = (double( MaxV) + double(MinV)) / 2;
|
|
|
- Win = double(MaxV) - double(MinV);
|
|
|
- WLAdjCoe = (Win + 1)/1024;
|
|
|
-elseif isa(Img,'logical')
|
|
|
- MaxV = 0;
|
|
|
- MinV = 1;
|
|
|
- LevV =0.5;
|
|
|
- Win = 1;
|
|
|
- WLAdjCoe = 0.1;
|
|
|
-end
|
|
|
-
|
|
|
-SFntSz = 9;
|
|
|
-LFntSz = 10;
|
|
|
-WFntSz = 10;
|
|
|
-LVFntSz = 9;
|
|
|
-WVFntSz = 9;
|
|
|
-BtnSz = 10;
|
|
|
-ChBxSz = 10;
|
|
|
-
|
|
|
-if (nargin < 2)
|
|
|
- [Rmin Rmax] = WL2R(Win, LevV);
|
|
|
-elseif numel(disprange) == 0
|
|
|
- [Rmin Rmax] = WL2R(Win, LevV);
|
|
|
-else
|
|
|
- LevV = (double(disprange(2)) + double(disprange(1))) / 2;
|
|
|
- Win = double(disprange(2)) - double(disprange(1));
|
|
|
- WLAdjCoe = (Win + 1)/1024;
|
|
|
- [Rmin Rmax] = WL2R(Win, LevV);
|
|
|
-end
|
|
|
-
|
|
|
-axes('position',[0,0.2,1,0.8]), imshow(Img(:,:,S), [Rmin Rmax])
|
|
|
-
|
|
|
-FigPos = get(gcf,'Position');
|
|
|
-S_Pos = [50 45 uint16(FigPos(3)-100)+1 20];
|
|
|
-Stxt_Pos = [50 65 uint16(FigPos(3)-100)+1 15];
|
|
|
-Wtxt_Pos = [50 20 60 20];
|
|
|
-Wval_Pos = [110 20 60 20];
|
|
|
-Ltxt_Pos = [175 20 45 20];
|
|
|
-Lval_Pos = [220 20 60 20];
|
|
|
-BtnStPnt = uint16(FigPos(3)-250)+1;
|
|
|
-if BtnStPnt < 300
|
|
|
- BtnStPnt = 300;
|
|
|
-end
|
|
|
-Btn_Pos = [BtnStPnt 20 100 20];
|
|
|
-ChBx_Pos = [BtnStPnt+110 20 100 20];
|
|
|
-
|
|
|
-if sno > 1
|
|
|
- shand = uicontrol('Style', 'slider','Min',1,'Max',sno,'Value',S,'SliderStep',[1/(sno-1) 10/(sno-1)],'Position', S_Pos,'Callback', {@SliceSlider, Img});
|
|
|
- stxthand = uicontrol('Style', 'text','Position', Stxt_Pos,'String',sprintf('Slice# %d / %d',S, sno), 'BackgroundColor', [0.8 0.8 0.8], 'FontSize', SFntSz);
|
|
|
-else
|
|
|
- stxthand = uicontrol('Style', 'text','Position', Stxt_Pos,'String','2D image', 'BackgroundColor', [0.8 0.8 0.8], 'FontSize', SFntSz);
|
|
|
-end
|
|
|
-ltxthand = uicontrol('Style', 'text','Position', Ltxt_Pos,'String','Level: ', 'BackgroundColor', [0.8 0.8 0.8], 'FontSize', LFntSz);
|
|
|
-wtxthand = uicontrol('Style', 'text','Position', Wtxt_Pos,'String','Window: ', 'BackgroundColor', [0.8 0.8 0.8], 'FontSize', WFntSz);
|
|
|
-lvalhand = uicontrol('Style', 'edit','Position', Lval_Pos,'String',sprintf('%6.0f',LevV), 'BackgroundColor', [1 1 1], 'FontSize', LVFntSz,'Callback', @WinLevChanged);
|
|
|
-wvalhand = uicontrol('Style', 'edit','Position', Wval_Pos,'String',sprintf('%6.0f',Win), 'BackgroundColor', [1 1 1], 'FontSize', WVFntSz,'Callback', @WinLevChanged);
|
|
|
-Btnhand = uicontrol('Style', 'pushbutton','Position', Btn_Pos,'String','Auto W/L', 'FontSize', BtnSz, 'Callback' , @AutoAdjust);
|
|
|
-ChBxhand = uicontrol('Style', 'checkbox','Position', ChBx_Pos,'String','Fine Tune', 'BackgroundColor', [0.8 0.8 0.8], 'FontSize', ChBxSz);
|
|
|
-
|
|
|
-set (gcf, 'WindowScrollWheelFcn', @mouseScroll);
|
|
|
-set (gcf, 'ButtonDownFcn', @mouseClick);
|
|
|
-set(get(gca,'Children'),'ButtonDownFcn', @mouseClick);
|
|
|
-set(gcf,'WindowButtonUpFcn', @mouseRelease)
|
|
|
-set(gcf,'ResizeFcn', @figureResized)
|
|
|
-
|
|
|
-
|
|
|
-% -=< Figure resize callback function >=-
|
|
|
- function figureResized(object, eventdata)
|
|
|
- FigPos = get(gcf,'Position');
|
|
|
- S_Pos = [50 45 uint16(FigPos(3)-100)+1 20];
|
|
|
- Stxt_Pos = [50 65 uint16(FigPos(3)-100)+1 15];
|
|
|
- BtnStPnt = uint16(FigPos(3)-250)+1;
|
|
|
- if BtnStPnt < 300
|
|
|
- BtnStPnt = 300;
|
|
|
- end
|
|
|
- Btn_Pos = [BtnStPnt 20 100 20];
|
|
|
- ChBx_Pos = [BtnStPnt+110 20 100 20];
|
|
|
- if sno > 1
|
|
|
- set(shand,'Position', S_Pos);
|
|
|
- end
|
|
|
- set(stxthand,'Position', Stxt_Pos);
|
|
|
- set(ltxthand,'Position', Ltxt_Pos);
|
|
|
- set(wtxthand,'Position', Wtxt_Pos);
|
|
|
- set(lvalhand,'Position', Lval_Pos);
|
|
|
- set(wvalhand,'Position', Wval_Pos);
|
|
|
- set(Btnhand,'Position', Btn_Pos);
|
|
|
- set(ChBxhand,'Position', ChBx_Pos);
|
|
|
- end
|
|
|
-
|
|
|
-% -=< Slice slider callback function >=-
|
|
|
- function SliceSlider (hObj,event, Img)
|
|
|
- S = round(get(hObj,'Value'));
|
|
|
- set(get(gca,'children'),'cdata',Img(:,:,S))
|
|
|
- caxis([Rmin Rmax])
|
|
|
- if sno > 1
|
|
|
- set(stxthand, 'String', sprintf('Slice# %d / %d',S, sno));
|
|
|
- else
|
|
|
- set(stxthand, 'String', '2D image');
|
|
|
- end
|
|
|
- end
|
|
|
-
|
|
|
-% -=< Mouse scroll wheel callback function >=-
|
|
|
- function mouseScroll (object, eventdata)
|
|
|
- UPDN = eventdata.VerticalScrollCount;
|
|
|
- S = S - UPDN;
|
|
|
- if (S < 1)
|
|
|
- S = 1;
|
|
|
- elseif (S > sno)
|
|
|
- S = sno;
|
|
|
- end
|
|
|
- if sno > 1
|
|
|
- set(shand,'Value',S);
|
|
|
- set(stxthand, 'String', sprintf('Slice# %d / %d',S, sno));
|
|
|
- else
|
|
|
- set(stxthand, 'String', '2D image');
|
|
|
- end
|
|
|
- set(get(gca,'children'),'cdata',Img(:,:,S))
|
|
|
- end
|
|
|
-
|
|
|
-% -=< Mouse button released callback function >=-
|
|
|
- function mouseRelease (object,eventdata)
|
|
|
- set(gcf, 'WindowButtonMotionFcn', '')
|
|
|
- end
|
|
|
-
|
|
|
-% -=< Mouse click callback function >=-
|
|
|
- function mouseClick (object, eventdata)
|
|
|
- MouseStat = get(gcbf, 'SelectionType');
|
|
|
- if (MouseStat(1) == 'a') % RIGHT CLICK
|
|
|
- InitialCoord = get(0,'PointerLocation');
|
|
|
- set(gcf, 'WindowButtonMotionFcn', @WinLevAdj);
|
|
|
- end
|
|
|
- end
|
|
|
-
|
|
|
-% -=< Window and level mouse adjustment >=-
|
|
|
- function WinLevAdj(varargin)
|
|
|
- PosDiff = get(0,'PointerLocation') - InitialCoord;
|
|
|
-
|
|
|
- Win = Win + PosDiff(1) * WLAdjCoe * FineTuneC(get(ChBxhand,'Value')+1);
|
|
|
- LevV = LevV - PosDiff(2) * WLAdjCoe * FineTuneC(get(ChBxhand,'Value')+1);
|
|
|
- if (Win < 1)
|
|
|
- Win = 1;
|
|
|
- end
|
|
|
-
|
|
|
- [Rmin, Rmax] = WL2R(Win,LevV);
|
|
|
- caxis([Rmin, Rmax])
|
|
|
- set(lvalhand, 'String', sprintf('%6.0f',LevV));
|
|
|
- set(wvalhand, 'String', sprintf('%6.0f',Win));
|
|
|
- InitialCoord = get(0,'PointerLocation');
|
|
|
- end
|
|
|
-
|
|
|
-% -=< Window and level text adjustment >=-
|
|
|
- function WinLevChanged(varargin)
|
|
|
-
|
|
|
- LevV = str2double(get(lvalhand, 'string'));
|
|
|
- Win = str2double(get(wvalhand, 'string'));
|
|
|
- if (Win < 1)
|
|
|
- Win = 1;
|
|
|
- end
|
|
|
-
|
|
|
- [Rmin, Rmax] = WL2R(Win,LevV);
|
|
|
- caxis([Rmin, Rmax])
|
|
|
- end
|
|
|
-
|
|
|
-% -=< Window and level to range conversion >=-
|
|
|
- function [Rmn Rmx] = WL2R(W,L)
|
|
|
- Rmn = L - (W/2);
|
|
|
- Rmx = L + (W/2);
|
|
|
- if (Rmn >= Rmx)
|
|
|
- Rmx = Rmn + 1;
|
|
|
- end
|
|
|
- end
|
|
|
-
|
|
|
-% -=< Window and level auto adjustment callback function >=-
|
|
|
- function AutoAdjust(object,eventdata)
|
|
|
- Win = double(max(Img(:))-min(Img(:)));
|
|
|
- Win (Win < 1) = 1;
|
|
|
- LevV = double(min(Img(:)) + (Win/2));
|
|
|
- [Rmin, Rmax] = WL2R(Win,LevV);
|
|
|
- caxis([Rmin, Rmax])
|
|
|
- set(lvalhand, 'String', sprintf('%6.0f',LevV));
|
|
|
- set(wvalhand, 'String', sprintf('%6.0f',Win));
|
|
|
- end
|
|
|
-
|
|
|
-end
|
|
|
-% -=< Maysam Shahedi (mshahedi@gmail.com), April 19, 2013>=-
|