resizing 3D matrix (image) in MATLAB

前端 未结 3 1456
再見小時候
再見小時候 2020-11-28 10:46

I have a 3D matrix (MxNxK) and want to resize it to (M\'xN\'xK\') (like imresize in matlab). I am using image pyramid, but its result is not very accurate and need a better

相关标签:
3条回答
  • 2020-11-28 11:19

    Look at the example Exploring Slices from a 3-Dimensional MRI Data Set in the Image Processing Toolbox. It looks more complicated than it actually is. You also can choose the interpolation method easily when working according to this example. To resize a volume isotrope by x, you'd have to use something like (I didn't test it):

    T = maketform('affine',[x 0 0; 0 x 0; 0 0 x; 0 0 0;]);
    R = makeresampler({'cubic','cubic','cubic'},'fill');
    ImageScaled = tformarray(Image,T,R,[1 2 3],[1 2 3], round(size(Image)*x),[],0);
    

    If you're working with binary images/volumes it might be better to change the 'cubic' interpolation to 'nearest'.

    0 讨论(0)
  • 2020-11-28 11:21

    Here is the resize function we are using in the kWave toolbox.

    function mat_rs = resize(varargin)
    %RESIZE     Resize a matrix.
    
    % DESCRIPTION:
    %       Resize a matrix to a given size using interp2 (2D) or interp3
    %       (3D).
    %       Use interpolation to redivide the [0,1] interval into Nx, Ny, Nz 
    %       voxels, where 0 is the center of first voxel, and 1 is the center 
    %       of the last one.
    %
    % USAGE:
    %       mat_rs = resize(mat, new_size)
    %       mat_rs = resize(mat, new_size, interp_mode)
    %
    % INPUTS:
    %       mat         - matrix to resize
    %       new_size    - desired matrix size in elements given by [Nx, Ny] in
    %                     2D and [Nx, Ny, Nz] in 3D. Here Nx is the number of
    %                     elements in the row direction, Ny is the number of
    %                     elements in the column direction, and Nz is the
    %                     number of elements in the depth direction.
    %
    % OPTIONAL INPUTS:
    %       interp_mode - interpolation mode used by interp2 and interp3 
    %                     (default = '*linear')
    %
    % OUTPUTS:
    %       mat_rs      - resized matrix
    
    % check the inputs for release B.0.2 compatability
    if length(varargin{2}) == 1 && nargin >= 3 && length(varargin{3}) == 1
    
    % display warning message
    disp('WARNING: input usage deprecated, please see documentation.');
    disp('In future releases this usage will no longer be functional.');    
    
    % recursively call resize with the correct inputs
    if nargin == 3
        mat_rs = resize(varargin{1}, [varargin{2}, varargin{3}]);
    else
        mat_rs = resize(varargin{1}, [varargin{2}, varargin{3}], varargin{4});
    end
    return
    
    end
    
    % update command line status
    disp('Resizing matrix...');
    
    % assign the matrix input
    mat = varargin{1};
    
    % check for interpolation mode input
    if nargin == 2
        interp_mode = '*linear';
    elseif nargin ~= 3
        error('incorrect number of inputs');
    else
        interp_mode = varargin{3};
    end
    
    % check inputs
    if numDim(mat) ~= length(varargin{2})
        error('resolution input must have the same number of elements as data dimensions');
    end
    
    switch numDim(mat)
    case 2
        % extract the original number of pixels from the size of the matrix
        [Nx_input, Ny_input] = size(mat);
    
        % extract the desired number of pixels
        Nx_output = varargin{2}(1);
        Ny_output = varargin{2}(2);
    
        % update command line status
        disp(['  input grid size: ' num2str(Nx_input) ' by ' num2str(Ny_input) ' elements']);
        disp(['  output grid size: ' num2str(Nx_output) ' by ' num2str(Ny_output) ' elements']);         
    
        % check the size is different to the input size
        if Nx_input ~= Nx_output || Ny_input ~= Ny_output 
    
            % resize the input matrix to the desired number of pixels
            mat_rs = interp2(0:1/(Ny_input - 1):1, (0:1/(Nx_input - 1):1)', mat, 0:1/(Ny_output - 1):1, (0:1/(Nx_output - 1):1)', interp_mode);
    
        else
            mat_rs = mat;
        end
    case 3
    
        % extract the original number of pixels from the size of the matrix
        [Nx_input, Ny_input, Nz_input] = size(mat);
    
        % extract the desired number of pixels
        Nx_output = varargin{2}(1);
        Ny_output = varargin{2}(2); 
        Nz_output = varargin{2}(3);        
    
        % update command line status
        disp(['  input grid size: ' num2str(Nx_input) ' by ' num2str(Ny_input) ' by ' num2str(Nz_input) ' elements']);
        disp(['  output grid size: ' num2str(Nx_output) ' by ' num2str(Ny_output) ' by ' num2str(Nz_output) ' elements']); 
    
        % create normalised plaid grids of current discretisation
        [x_mat, y_mat, z_mat] = ndgrid((0:Nx_input-1)/(Nx_input-1), (0:Ny_input-1)/(Ny_input-1), (0:Nz_input-1)/(Nz_input-1));       
    
        % create plaid grids of desired discretisation
        [x_mat_interp, y_mat_interp, z_mat_interp] = ndgrid((0:Nx_output-1)/(Nx_output-1), (0:Ny_output-1)/(Ny_output-1), (0:Nz_output-1)/(Nz_output-1));
    
        % compute interpolation; for a matrix indexed as [M, N, P], the
        % axis variables must be given in the order N, M, P
        mat_rs = interp3(y_mat, x_mat, z_mat, mat, y_mat_interp, x_mat_interp, z_mat_interp, interp_mode);        
    
    otherwise
        error('input matrix must be 2 or 3 dimensional');
    end
    
    0 讨论(0)
  • 2020-11-28 11:33

    You could use interp3 (since you want to interpolate 3D data):

    im=rand(2,3,4); %% input image
    ny=3;nx=3;nz=5; %% desired output dimensions
    [y x z]=...
       ndgrid(linspace(1,size(im,1),ny),...
              linspace(1,size(im,2),nx),...
              linspace(1,size(im,3),nz));
    imOut=interp3(im,x,y,z);
    
    0 讨论(0)
提交回复
热议问题