Difference between revisions of "3D Reslicing using COMKAT image tool (basic)"

From COMKAT wiki
Jump to navigation Jump to search
(Created page with "test")
 
Line 1: Line 1:
test
+
==Reslicing 3D image volume using COMKAT image tool (basic)==
 +
 
 +
===Overview===
 +
Reslicing a 3D (or 3D vs time) image dataset can be accomplished using the COMKAT image tool and sliceVolume().
 +
This example explains how to create image slices from a volume in at a position, plane orientation, and magnification.
 +
The approach is to load the image volume dataset into an instance if an ImageVolumeData (abbreviated IVD) object and to use the sliceVolume() method.
 +
 
 +
====Background====
 +
sliceVolume() is a mex-file written in c with an interface to MATLAB that makes the operation particularly efficient.  COMKATImageTool uses sliceVolume() and you can use it too.
 +
 
 +
----
 +
====Approach 1.====
 +
Load a file using COMKAT image tool and use the functions to translate and rotate the image volume as you desire.
 +
 
 +
  ivd = ImageVolumeData();
 +
 
 +
Use read data to ivd,  e.g. read_DICOM();
 +
 
 +
  ivd = read_DICOM(ivd, pathName, fileName); % load volume into an instance of IVD object;
 +
 
 +
Create a list of indicies of all pixels in slice that we are creating
 +
 
 +
  [i, j] = meshgrid(0 : Nc-1, 0 : Nr-1);
 +
    ij = [c(:)’ ; r(:)’];  % make matrix, each column corresponding to a single pixel in the slice we are creating
 +
 
 +
(set up coordinate transform for desired slice) ref p 275
 +
 
 +
  M = (Insert the method for generate the transformation);
 +
 
 +
User specifies this based on desired pixel spacing (aka zoom), position (location), orientation
 +
Calculate physical (mm) location of each pixel in the desired slice
 +
 
 +
  xyz = M * ij;
 +
 
 +
 
 +
this documents physical location voxels in the volume
 +
 
 +
  Mhat = ( transform for the stored volume)
 +
 
 +
Load a file using COMKAT image tool and use the functions to translate and rotate the image volume as you desire.
 +
 
 +
  ivd = ImageVolumeData();
 +
 
 +
Load a file using COMKAT image tool and use the functions to translate and rotate the image volume as you desire.
 +
 
 +
  ivd = ImageVolumeData();
 +
 
 +
 
 +
====Create an empty imageVolumeData object====
 +
Send the GUI handles of COMKAT image tool to MATLAB workspace.
 +
 
 +
[[Image:Example Reslice 1.jpg]]
 +
 
 +
 
 +
====Create the function for reslicing====
 +
Create following MATLAB function:
 +
 
 +
<pre>
 +
function outputVolume = fcnReSlice(GUI_handles, a_row, a_column, a_plane, flagUseCurrIvd)
 +
%%*****************************************************************************%%
 +
% Example:  Using ImageVolumeData::sliceVolume() to reslice 3D images
 +
% e.g.
 +
%  outputVolume = fcnReSlice(GUI_handles [, a_row, a_column, a_plane, flagUseCurrIvd]);
 +
%
 +
%  Parameters -
 +
%      GUI_handles : GUI handles obtained from comkatimagetool
 +
%                a_row : Desired aspect ratio in row direction    (default: 1.0)
 +
%            a_column : Desired aspect ratio in colume direction  (default: 1.0)
 +
%              a_plane : Desired aspect ratio in plane direction  (default: 1.0)
 +
%  flagUseCurrIvd : A flag to control the data used to reslice
 +
%                                ( 1: Current COMKAT ImageVolumeData (default), 0: Original)
 +
%    outputVolume : Resliced 3D volume images
 +
%
 +
%
 +
%  Dylan Su    2012-07-30
 +
%  kuan-hao.su@case.edu
 +
%%*****************************************************************************%%
 +
 
 +
%% Obtain the imageVolumeData object from GUI_handles
 +
ivd = GUI_handles.imageVolumeData{1}; % assume PET is image 1
 +
 
 +
if nargin == 1,
 +
    a_row = 1;
 +
    a_column = 1;
 +
    a_plane = 1;
 +
end
 +
 
 +
if nargin < 5,
 +
    flagUseCurrIvd = 1;  % 1: use current COMKAT image volume
 +
end
 +
 
 +
if (~flagUseCurrIvd),
 +
    %% Get the information from origianl data
 +
    positionInput = get(ivd,'ImagePositionPatient');
 +
    orientationInput = get(ivd,'ImageOrientationPatient');
 +
    pixelSpacing = get(ivd, 'PixelSpacing');
 +
    [nr, nc, np, ~] = get(ivd, 'VolumeDimension');
 +
    nrows = nr;
 +
    ncols = nc;
 +
    nplanes = np;
 +
   
 +
else
 +
    %% Get the information from current COMKAT imageVolumeData
 +
    idxSA = 1;  % get infor from short axis (SA) view
 +
   
 +
    positionInput = GUI_handles.view{idxSA}.position{1};
 +
    orientationInput = GUI_handles.view{idxSA}.orientation{1};
 +
    pixelSpacing = repmat( GUI_handles.view{idxSA}.pixelSpacing(1),[1,3]);
 +
    nrows = GUI_handles.rows;
 +
    ncols = GUI_handles.columns;
 +
   
 +
    [~, ~, np, ~] = get(ivd, 'VolumeDimension');
 +
   
 +
    pixelSpacingOrg = get(ivd, 'PixelSpacing');
 +
   
 +
    nplanes = ceil(np * pixelSpacingOrg(3) / pixelSpacing(3));
 +
end
 +
 
 +
%% Calculate the desired dimension
 +
dnrows = ceil(nrows * a_row);
 +
dncols = ceil(ncols * a_column);
 +
dnplanes = ceil(nplanes * a_plane);
 +
 
 +
% calcualte new pixelSpacing by preserving the original FOV size
 +
pixelSpacing = pixelSpacing ./ [dnrows/nrows, dncols/ncols, dnplanes/nplanes];
 +
 
 +
%% Set the scale and offset the same as the original volume
 +
% use same scale and offset for subvolume as original volume
 +
% 0 = scaledPixel = rawPixel * s + o --> rawPixel = -o/s;
 +
s = get(ivd, 'VolumeFrameBufferScaleFactor');
 +
o = get(ivd, 'VolumeFrameBufferRescaleIntercept');
 +
 
 +
rawBackgroundPixelValue = -o/s;
 +
 
 +
%% Determine location of first pixel in output volume
 +
posSA = positionInput;
 +
 
 +
% xyz of the center of first pixel
 +
if (~flagUseCurrIvd),
 +
    % for subject's data, 'posSA' is the center of the first pixel
 +
    position = posSA;
 +
else
 +
    % for imageVolumeData, 'posSA' is the center of the folume
 +
    position = posSA - orientationInput(:,3) * (dnplanes * pixelSpacing(3)) / 2;
 +
end
 +
 
 +
planePosStep = orientationInput(:,3) * pixelSpacing(3); % calculate the step of new plane position
 +
 
 +
%% Build output volume plane-by-plane
 +
outputVolume = zeros(dnrows, dncols, dnplanes);  % initialize the output images
 +
 
 +
for idxP = 1 : dnplanes,
 +
    planePos = position + (idxP - 1) * planePosStep; % position of plane to be interpolated
 +
   
 +
    % determine indicies in original volume corresponding to xyz physical (mm) location of plane
 +
    [u, v, w] = coordinateGen(ivd, ...
 +
        dncols, dnrows, pixelSpacing, planePos, orientationInput);
 +
   
 +
    % obtain a slice by interpolating from the ivd volumeFrameBuffer
 +
    fprintf('plane ==> %i/%i\n', idxP, dnplanes);
 +
    outputVolume(:, :, idxP) = sliceVolume(ivd, v , u , w, rawBackgroundPixelValue,'linear');
 +
   
 +
end
 +
 
 +
</pre>
 +
 
 +
 
 +
====Use the function to reslice the image volume====
 +
Then, you can reslice the volume data with this function.
 +
        e.g.  outputVolume = fcnReSlice( GUI_handles );
 +
                 
 +
                  The ’outputVolume‘ is the resliced 3D volume.
 +
 
 +
 
 +
Or you may input the desired aspect ratios in each direction to vary the sampled resolutions of the resliced images.
 +
        e.g.  outputVolume = fcnReSlice( GUI_handles , 1.0, 1.0, 2.0);
 +
                 
 +
                  In this case, the number of sampling in the plane-direction would be doubled.
 +
 
 +
 
 +
If you’d like to reslice the image volume from original image data without pre-sampling, translation and rotation, you may set the fifth parameter to zero.
 +
        e.g.  outputVolume = fcnReSlice( GUI_handles , 1.0, 1.0, 2.0, 0);
 +
                 
 +
                  So now the ‘outputVolume’ is the resliced volume of the original data.

Revision as of 19:57, 7 August 2012

Reslicing 3D image volume using COMKAT image tool (basic)

Overview

Reslicing a 3D (or 3D vs time) image dataset can be accomplished using the COMKAT image tool and sliceVolume(). This example explains how to create image slices from a volume in at a position, plane orientation, and magnification. The approach is to load the image volume dataset into an instance if an ImageVolumeData (abbreviated IVD) object and to use the sliceVolume() method.

Background

sliceVolume() is a mex-file written in c with an interface to MATLAB that makes the operation particularly efficient. COMKATImageTool uses sliceVolume() and you can use it too.


Approach 1.

Load a file using COMKAT image tool and use the functions to translate and rotate the image volume as you desire.

  ivd = ImageVolumeData();

Use read data to ivd, e.g. read_DICOM();

  ivd = read_DICOM(ivd, pathName, fileName); % load volume into an instance of IVD object;

Create a list of indicies of all pixels in slice that we are creating

  [i, j] = meshgrid(0 : Nc-1, 0 : Nr-1);
   ij = [c(:)’ ; r(:)’];  % make matrix, each column corresponding to a single pixel in the slice we are creating

(set up coordinate transform for desired slice) ref p 275

  M = (Insert the method for generate the transformation);

User specifies this based on desired pixel spacing (aka zoom), position (location), orientation Calculate physical (mm) location of each pixel in the desired slice

  xyz = M * ij;


this documents physical location voxels in the volume

  Mhat = ( transform for the stored volume)

Load a file using COMKAT image tool and use the functions to translate and rotate the image volume as you desire.

  ivd = ImageVolumeData();

Load a file using COMKAT image tool and use the functions to translate and rotate the image volume as you desire.

  ivd = ImageVolumeData();


Create an empty imageVolumeData object

Send the GUI handles of COMKAT image tool to MATLAB workspace.

Example Reslice 1.jpg


Create the function for reslicing

Create following MATLAB function:

function outputVolume = fcnReSlice(GUI_handles, a_row, a_column, a_plane, flagUseCurrIvd)
%%*****************************************************************************%%
% Example:  Using ImageVolumeData::sliceVolume() to reslice 3D images
% e.g. 
%  outputVolume = fcnReSlice(GUI_handles [, a_row, a_column, a_plane, flagUseCurrIvd]);
% 
%  Parameters -
%       GUI_handles : GUI handles obtained from comkatimagetool
%                 a_row : Desired aspect ratio in row direction     (default: 1.0)
%            a_column : Desired aspect ratio in colume direction  (default: 1.0)
%              a_plane : Desired aspect ratio in plane direction   (default: 1.0)
%   flagUseCurrIvd : A flag to control the data used to reslice 
%                                 ( 1: Current COMKAT ImageVolumeData (default), 0: Original)
%     outputVolume : Resliced 3D volume images
%
%
%   Dylan Su     2012-07-30
%   kuan-hao.su@case.edu
%%*****************************************************************************%%

%% Obtain the imageVolumeData object from GUI_handles
ivd = GUI_handles.imageVolumeData{1}; % assume PET is image 1

if nargin == 1,
    a_row = 1;
    a_column = 1;
    a_plane = 1;
end

if nargin < 5,
    flagUseCurrIvd = 1;  % 1: use current COMKAT image volume
end

if (~flagUseCurrIvd),
    %% Get the information from origianl data
    positionInput = get(ivd,'ImagePositionPatient');
    orientationInput = get(ivd,'ImageOrientationPatient');
    pixelSpacing = get(ivd, 'PixelSpacing');
    [nr, nc, np, ~] = get(ivd, 'VolumeDimension');
    nrows = nr;
    ncols = nc;
    nplanes = np;
    
else
    %% Get the information from current COMKAT imageVolumeData
    idxSA = 1;  % get infor from short axis (SA) view
    
    positionInput = GUI_handles.view{idxSA}.position{1};
    orientationInput = GUI_handles.view{idxSA}.orientation{1};
    pixelSpacing = repmat( GUI_handles.view{idxSA}.pixelSpacing(1),[1,3]);
    nrows = GUI_handles.rows;
    ncols = GUI_handles.columns;
    
    [~, ~, np, ~] = get(ivd, 'VolumeDimension');
    
    pixelSpacingOrg = get(ivd, 'PixelSpacing');
    
    nplanes = ceil(np * pixelSpacingOrg(3) / pixelSpacing(3)); 
end

%% Calculate the desired dimension
dnrows = ceil(nrows * a_row);
dncols = ceil(ncols * a_column);
dnplanes = ceil(nplanes * a_plane);

% calcualte new pixelSpacing by preserving the original FOV size
pixelSpacing = pixelSpacing ./ [dnrows/nrows, dncols/ncols, dnplanes/nplanes];

%% Set the scale and offset the same as the original volume
% use same scale and offset for subvolume as original volume
% 0 = scaledPixel = rawPixel * s + o --> rawPixel = -o/s;
s = get(ivd, 'VolumeFrameBufferScaleFactor');
o = get(ivd, 'VolumeFrameBufferRescaleIntercept');

rawBackgroundPixelValue = -o/s;

%% Determine location of first pixel in output volume
posSA = positionInput;

% xyz of the center of first pixel
if (~flagUseCurrIvd),
    % for subject's data, 'posSA' is the center of the first pixel
    position = posSA;
else
    % for imageVolumeData, 'posSA' is the center of the folume
    position = posSA - orientationInput(:,3) * (dnplanes * pixelSpacing(3)) / 2;
end

planePosStep = orientationInput(:,3) * pixelSpacing(3); % calculate the step of new plane position

%% Build output volume plane-by-plane
outputVolume = zeros(dnrows, dncols, dnplanes);  % initialize the output images

for idxP = 1 : dnplanes,
    planePos = position + (idxP - 1) * planePosStep; % position of plane to be interpolated
    
    % determine indicies in original volume corresponding to xyz physical (mm) location of plane
    [u, v, w] = coordinateGen(ivd, ...
        dncols, dnrows, pixelSpacing, planePos, orientationInput);
    
    % obtain a slice by interpolating from the ivd volumeFrameBuffer
    fprintf('plane ==> %i/%i\n', idxP, dnplanes);
    outputVolume(:, :, idxP) = sliceVolume(ivd, v , u , w, rawBackgroundPixelValue,'linear');
    
end


Use the function to reslice the image volume

Then, you can reslice the volume data with this function.

        e.g.   outputVolume = fcnReSlice( GUI_handles );
                 
                 The ’outputVolume‘ is the resliced 3D volume. 


Or you may input the desired aspect ratios in each direction to vary the sampled resolutions of the resliced images.

        e.g.   outputVolume = fcnReSlice( GUI_handles , 1.0, 1.0, 2.0);
                 
                 In this case, the number of sampling in the plane-direction would be doubled.


If you’d like to reslice the image volume from original image data without pre-sampling, translation and rotation, you may set the fifth parameter to zero.

        e.g.   outputVolume = fcnReSlice( GUI_handles , 1.0, 1.0, 2.0, 0);
                 
                 So now the ‘outputVolume’ is the resliced volume of the original data.