mirror of
https://github.com/c-sooyoung/fold_slice.git
synced 2026-09-17 22:59:07 +09:00
initial commit
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
% FUNCTION full_array = add_to_3D(full_array, small_array, position)
|
||||
% add one small 3D block into large 3D array
|
||||
% Inputs:
|
||||
% full_array
|
||||
% small_array
|
||||
% position - offset from (1,1,1) coordinate in pixels
|
||||
|
||||
% *-----------------------------------------------------------------------*
|
||||
% | |
|
||||
% | Except where otherwise noted, this work is licensed under a |
|
||||
% | Creative Commons Attribution-NonCommercial-ShareAlike 4.0 |
|
||||
% | International (CC BY-NC-SA 4.0) license. |
|
||||
% | |
|
||||
% | Copyright (c) 2017 by Paul Scherrer Institute (http://www.psi.ch) |
|
||||
% | |
|
||||
% | Author: CXS group, PSI |
|
||||
% *-----------------------------------------------------------------------*
|
||||
% You may use this code with the following provisions:
|
||||
%
|
||||
% If the code is fully or partially redistributed, or rewritten in another
|
||||
% computing language this notice should be included in the redistribution.
|
||||
%
|
||||
% If this code, or subfunctions or parts of it, is used for research in a
|
||||
% publication or if it is fully or partially rewritten for another
|
||||
% computing language the authors and institution should be acknowledged
|
||||
% in written form in the publication: “Data processing was carried out
|
||||
% using the “cSAXS matlab package” developed by the CXS group,
|
||||
% Paul Scherrer Institut, Switzerland.”
|
||||
% Variations on the latter text can be incorporated upon discussion with
|
||||
% the CXS group if needed to more specifically reflect the use of the package
|
||||
% for the published work.
|
||||
%
|
||||
% A publication that focuses on describing features, or parameters, that
|
||||
% are already existing in the code should be first discussed with the
|
||||
% authors.
|
||||
%
|
||||
% This code and subroutines are part of a continuous development, they
|
||||
% are provided “as they are” without guarantees or liability on part
|
||||
% of PSI or the authors. It is the user responsibility to ensure its
|
||||
% proper use and the correctness of the results.
|
||||
%
|
||||
%
|
||||
%
|
||||
function full_array = add_to_3D(full_array, small_array, position)
|
||||
|
||||
position = round(position);
|
||||
N_f = size(full_array);
|
||||
N_s = size(small_array);
|
||||
|
||||
for i = 1:ndims(full_array)
|
||||
ind_f{i} = unique(min(N_f(i),max(1,position(i)+(1:N_s(i)))));
|
||||
ind_s{i} = unique(min(N_s(i),max(1,ind_f{i}-position(i))));
|
||||
end
|
||||
|
||||
full_array(ind_f{:}) = full_array(ind_f{:}) + small_array(ind_s{:});
|
||||
|
||||
|
||||
end
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
|
||||
% IMSHIFT_GENERIC auxiliar function to be performed bu block_fun on GPU
|
||||
% it applies imshift_fft on the provided image that was first upsampled
|
||||
% to Npix (if needed) and cropped to region ROI
|
||||
% after shifting, the image is downsampled by the chosen interpolation
|
||||
% method "intep_method" that is more accurate than simple binning
|
||||
%
|
||||
% img = imshift_generic(img, shift, Npix, affine_matrix, smooth, ROI, downsample, intep_method, interp_sign)
|
||||
%
|
||||
% Inputs:
|
||||
% **img 2D stacked image
|
||||
% **shift Nx2 vector of shifts applied on the image
|
||||
% **Npix 2x1 int, size of the img to be upsampled before shift, Npix = [] -> no upsampling
|
||||
% **affine_matrix affine metrix ! not implemented yet!
|
||||
% **smooth how many pixels around edges will be smoothed before shifting the array
|
||||
% **ROI cell array, used to crop the array to smaller size
|
||||
% **downsample downsample factor , 1 == no downsampling
|
||||
% **intep_method interpolation method: linear, fft
|
||||
% **interp_sign sign used for subpixel shifts of the dataset, +1 for unwrapped phase, -1 for phase differene
|
||||
% *returns*
|
||||
% ++img 2D stacked image
|
||||
|
||||
function img = imshift_generic(img, shift, Npix, affine_matrix, smooth, ROI, downsample, intep_method, interp_sign)
|
||||
|
||||
if nargin < 9
|
||||
interp_sign = 0;
|
||||
end
|
||||
|
||||
import math.*
|
||||
import utils.*
|
||||
|
||||
if isa(img, 'uint8') || (isa(img, 'gpuArray') && strcmpi(classUnderlying(img),'uint8'))
|
||||
img = single(img) / 255; % assume that the provided image is only compressed into uint8
|
||||
end
|
||||
|
||||
% if needed upsample to the size of the projection
|
||||
if ~isempty(Npix) && any(Npix(1:2) ~= [size(img,1),size(img,2)])
|
||||
switch intep_method
|
||||
case 'linear', img = utils.interpolate_linear(img, Npix);
|
||||
case 'fft', img = utils.interpolateFT(img, Npix);
|
||||
end
|
||||
end
|
||||
|
||||
isReal = isreal(img);
|
||||
|
||||
if any(shift(:) ~=0 )
|
||||
smooth_axis = 3-find(any(shift ~= 0));
|
||||
img = smooth_edges(img, smooth, smooth_axis);
|
||||
if ~ismatrix(img)
|
||||
switch intep_method
|
||||
case 'linear'
|
||||
img = utils.imshift_linear(img,shift); % interpolation of the weights does not need such precision
|
||||
case 'fft'
|
||||
%%% APPLY SHIFT USING FFT -> periodic boundary
|
||||
img = imshift_fft(img, shift);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
% crop the FOV after shift and before "downsample"
|
||||
if ~isempty(ROI)
|
||||
img = img(ROI{:},:); % crop to smaller ROI if provided
|
||||
% apply crop after imshift_fft
|
||||
end
|
||||
|
||||
Np = size(img);
|
||||
|
||||
% perform interpolation instead of downsample , it provides more accurate results
|
||||
if downsample > 1
|
||||
img = utils.imgaussfilt3_conv(img,[downsample,downsample,0]);
|
||||
% correct for boundary effects of the convolution based smoothing
|
||||
img = img ./ utils.imgaussfilt3_conv(ones(Np(1:2), 'like', img),[downsample,downsample,0]);
|
||||
switch intep_method
|
||||
case 'linear', img = utils.interpolate_linear(img,ceil(Np(1:2)/downsample/2)*2); % interpolation of the weights does not need such precision
|
||||
case 'fft', img = utils.interpolateFT_centered(utils.smooth_edges(img, 2*downsample),ceil(Np(1:2)/downsample/2)*2, interp_sign); % accurate interpolation using FFT
|
||||
end
|
||||
end
|
||||
if isReal; img = real(img); end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,102 @@
|
||||
/* iradon_c.c:
|
||||
sub-routine of a modified iradon.m, i.e., the time consuming loop
|
||||
of this routine in C.
|
||||
|
||||
Compilation from Matlab:
|
||||
mex iradon_c.c
|
||||
maybe a tiny bit faster code is generated by
|
||||
mex -O COPTIMFLAGS='-O2' LDOPTIMFLAGS='-O2' iradon_c.c
|
||||
|
||||
Usage from Matlab:
|
||||
iradon_c( p, theta, x, y );
|
||||
*/
|
||||
|
||||
#include "mex.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
|
||||
void mexFunction(int nlhs, mxArray *plhs[],
|
||||
int nrhs, const mxArray *prhs[])
|
||||
{
|
||||
int dim1, dim2, dim1_data;
|
||||
int i, no_of_angles, ctrIdx;
|
||||
double *data, *theta, *xorg, *yorg, *imgorg;
|
||||
|
||||
/* Check for proper number of arguments. */
|
||||
if (nrhs != 4)
|
||||
mexErrMsgTxt("Four input arguments required: Data, theta, x and y.");
|
||||
else if (nlhs != 1)
|
||||
mexErrMsgTxt("One output argument has to be specified.");
|
||||
|
||||
/* Input must be double. */
|
||||
if (mxIsDouble(prhs[0]) != 1)
|
||||
mexErrMsgTxt("Input 1 (data) must be of double precision floating point type.");
|
||||
if (mxIsDouble(prhs[1]) != 1)
|
||||
mexErrMsgTxt("Input 2 (theta) must be of double precision floating point type.");
|
||||
if (mxIsDouble(prhs[2]) != 1)
|
||||
mexErrMsgTxt("Input 3 (x) must be of double precision floating point type.");
|
||||
if (mxIsDouble(prhs[3]) != 1)
|
||||
mexErrMsgTxt("Input 4 (y) must be of double precision floating point type.");
|
||||
|
||||
|
||||
/* get number of different angles */
|
||||
if (mxGetM(prhs[1]) == 1) {
|
||||
no_of_angles = mxGetN(prhs[1]);
|
||||
} else {
|
||||
if (mxGetN(prhs[1]) == 1) {
|
||||
no_of_angles = mxGetM(prhs[1]);
|
||||
} else {
|
||||
mexErrMsgTxt("Theta has to be a vector, not an array.");
|
||||
}
|
||||
}
|
||||
|
||||
/* get dimensions and check that they are consistent */
|
||||
dim1 = mxGetM(prhs[2]);
|
||||
dim2 = mxGetN(prhs[2]);
|
||||
if ((dim1 != mxGetM(prhs[3])) || (dim1 != mxGetN(prhs[3])))
|
||||
mexErrMsgTxt("x and y must have the same dimensions.");
|
||||
if (no_of_angles > mxGetN(prhs[0]))
|
||||
mexErrMsgTxt("The second dimension of data must be at least as large as the number of theta angles.");
|
||||
dim1_data = mxGetM(prhs[0]);
|
||||
|
||||
/* allocate memory for image data, to be returned */
|
||||
plhs[0] =
|
||||
mxCreateNumericMatrix(dim1, dim2, mxDOUBLE_CLASS, mxREAL);
|
||||
if (plhs[0] == NULL)
|
||||
mexErrMsgTxt("Could not allocate memory for return data.");
|
||||
|
||||
/* get pointers to input and output data */
|
||||
data = mxGetPr(prhs[0]);
|
||||
theta = mxGetPr(prhs[1]);
|
||||
xorg = mxGetPr(prhs[2]);
|
||||
yorg = mxGetPr(prhs[3]);
|
||||
imgorg = mxGetPr(plhs[0]);
|
||||
|
||||
/* index to image center */
|
||||
ctrIdx = ceil(mxGetM(prhs[0]) / 2);
|
||||
|
||||
for (i=0; i < no_of_angles; i++) {
|
||||
double *x = xorg;
|
||||
double *y = yorg;
|
||||
double *img = imgorg;
|
||||
/* temporary variables */
|
||||
double costheta = cos(*theta);
|
||||
double sintheta = sin(*theta);
|
||||
double *proj = &data[i*dim1_data +1];
|
||||
int j;
|
||||
for (j=0; j < dim2; j++) {
|
||||
int k;
|
||||
for (k=0; k < dim1; k++) {
|
||||
double t = *x * costheta + *y * sintheta;
|
||||
int a = floor(t);
|
||||
*img += (t-a) * proj[a+ctrIdx] + (a+1-t) * proj[a+ctrIdx-1];
|
||||
x++;
|
||||
y++;
|
||||
img++;
|
||||
}
|
||||
}
|
||||
theta++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
% FUNCTION full_array = set_to_3D(full_array, small_array, position)
|
||||
% add one small 3D block into large 3D array
|
||||
% Inputs:
|
||||
% full_array
|
||||
% small_array
|
||||
% position - [3 x 1] offset from (1,1,1) coordinate in pixels
|
||||
|
||||
% *-----------------------------------------------------------------------*
|
||||
% | |
|
||||
% | Except where otherwise noted, this work is licensed under a |
|
||||
% | Creative Commons Attribution-NonCommercial-ShareAlike 4.0 |
|
||||
% | International (CC BY-NC-SA 4.0) license. |
|
||||
% | |
|
||||
% | Copyright (c) 2017 by Paul Scherrer Institute (http://www.psi.ch) |
|
||||
% | |
|
||||
% | Author: CXS group, PSI |
|
||||
% *-----------------------------------------------------------------------*
|
||||
% You may use this code with the following provisions:
|
||||
%
|
||||
% If the code is fully or partially redistributed, or rewritten in another
|
||||
% computing language this notice should be included in the redistribution.
|
||||
%
|
||||
% If this code, or subfunctions or parts of it, is used for research in a
|
||||
% publication or if it is fully or partially rewritten for another
|
||||
% computing language the authors and institution should be acknowledged
|
||||
% in written form in the publication: “Data processing was carried out
|
||||
% using the “cSAXS matlab package” developed by the CXS group,
|
||||
% Paul Scherrer Institut, Switzerland.”
|
||||
% Variations on the latter text can be incorporated upon discussion with
|
||||
% the CXS group if needed to more specifically reflect the use of the package
|
||||
% for the published work.
|
||||
%
|
||||
% A publication that focuses on describing features, or parameters, that
|
||||
% are already existing in the code should be first discussed with the
|
||||
% authors.
|
||||
%
|
||||
% This code and subroutines are part of a continuous development, they
|
||||
% are provided “as they are” without guarantees or liability on part
|
||||
% of PSI or the authors. It is the user responsibility to ensure its
|
||||
% proper use and the correctness of the results.
|
||||
%
|
||||
%
|
||||
|
||||
function full_array = set_to_3D(full_array, small_array, position)
|
||||
|
||||
position = round(position);
|
||||
N_f = size(full_array);
|
||||
N_s = size(small_array);
|
||||
|
||||
for i = 1:3
|
||||
ind_f{i} = unique(min(N_f(i),max(1,position(i)+(1:N_s(i)))));
|
||||
end
|
||||
|
||||
full_array(ind_f{:}) = small_array;
|
||||
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user