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,103 @@
|
||||
% function f = local_TV3D_chambolle(f, lambda, niter)
|
||||
% apply local total variation usiniter matlab functions, it uses chambolle
|
||||
% solver -> faster but more memory demanding
|
||||
% Inputs: f - 3D array to be regularized
|
||||
% lambda - constant to be tuned
|
||||
% niter - number of iterations
|
||||
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| 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 followiniter provisions:
|
||||
%
|
||||
% If the code is fully or partially redistributed, or rewritten in another
|
||||
% computiniter laniteruage 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
|
||||
% computiniter laniteruage the authors and institution should be acknowledged
|
||||
% in written form in the publication: “Data processiniter was carried out
|
||||
% usiniter 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 describiniter features, or parameters, that
|
||||
% are already existiniter 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 x = local_TV3D_chambolle(x,lambda, niter)
|
||||
[M,N,O] = size(x);
|
||||
|
||||
if lambda == 0
|
||||
return
|
||||
end
|
||||
|
||||
x0 = x;
|
||||
xi = zeros(M,N,O,3, class(x));
|
||||
tau=2/8;
|
||||
%%% INNER LOOP
|
||||
for iinner = 1:niter
|
||||
% chambolle step
|
||||
gdv = grad( div(xi) - x/lambda );
|
||||
|
||||
%% isotropic
|
||||
% d = sqrt(sum(gdv.^2,3));
|
||||
%% anisotropic
|
||||
d = sum( abs(gdv), 4);
|
||||
xi = bsxfun(@times, xi + tau*gdv, 1 ./ ( 1+tau*d ));
|
||||
% reconstruct
|
||||
x = x - lambda*div( xi );
|
||||
|
||||
end
|
||||
|
||||
% prevent pushing values to zero by the TV regularization
|
||||
x = sum(x0(:).* x(:)) / sum(x(:).^2) * x;
|
||||
|
||||
end
|
||||
|
||||
function fd = div(P)
|
||||
|
||||
% div - divergence (backward difference)
|
||||
%
|
||||
% fd = div(P);
|
||||
|
||||
Px = P(:,:,:,1);
|
||||
Py = P(:,:,:,2);
|
||||
Pz = P(:,:,:,3);
|
||||
|
||||
|
||||
fx = Px-Px([1 1:end-1],:,:);
|
||||
fy = Py-Py(:,[1 1:end-1],:);
|
||||
fz = Pz-Pz(:,:,[1 1:end-1]);
|
||||
fd = fx+fy+fz;
|
||||
|
||||
end
|
||||
|
||||
function f = grad(M)
|
||||
|
||||
% grad - gradient, forward differences
|
||||
% g = grad(M);
|
||||
|
||||
fx = M([2:end end],:,:)-M;
|
||||
fy = M(:,[2:end end],:)-M;
|
||||
fz = M(:,:,[2:end end])-M;
|
||||
|
||||
f = cat(4,fx,fy,fz);
|
||||
|
||||
end
|
||||
@@ -0,0 +1,72 @@
|
||||
% function f = local_TV3D_grad(f, dtvg, niter)
|
||||
% apply local total variation usiniter matlab functions, it uses basic
|
||||
% steepest descent solver.
|
||||
% Inputs: f - 3D array to be regularized
|
||||
% dtvg - gradient descent step (constant to be tuned)
|
||||
% niter - number of iterations
|
||||
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| 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 followiniter provisions:
|
||||
%
|
||||
% If the code is fully or partially redistributed, or rewritten in another
|
||||
% computiniter laniteruage 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
|
||||
% computiniter laniteruage the authors and institution should be acknowledged
|
||||
% in written form in the publication: “Data processiniter was carried out
|
||||
% usiniter 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 describiniter features, or parameters, that
|
||||
% are already existiniter 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 f = local_TV3D_grad(f, dtvg, niter)
|
||||
for ii=1:niter
|
||||
% Steepest descend of TV norm
|
||||
%% CUDA version will make it more memory effecient => almost inplace !!
|
||||
df=gradientTVnormForward(f);
|
||||
df=df./sqrt(mean(df(:).^2)); % it will be close to 1 anyway
|
||||
f=f-dtvg.*df;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
%% Forward differences
|
||||
function tvg=gradientTVnormForward(f)
|
||||
% gradient
|
||||
|
||||
Gx=diff(f,1,1);
|
||||
Gy=diff(f,1,2);
|
||||
Gz=diff(f,1,3);
|
||||
|
||||
Gx=cat(1,Gx,zeros(size(Gx(end,:,:)), class(f)));
|
||||
Gy=cat(2,Gy,zeros(size(Gy(:,end,:)), class(f)));
|
||||
Gz=cat(3,Gz,zeros(size(Gz(:,:,end)), class(f)));
|
||||
|
||||
nrm=sqrt(Gx.^2+Gy.^2+Gz.^2)+1e-7;
|
||||
|
||||
% divergence
|
||||
tvg=Gx([1,1:end-1],:,:)-Gx + Gy(:,[1,1:end-1],:)-Gy+Gz(:,:,[1,1:end-1])-Gz;
|
||||
tvg=tvg ./ nrm;
|
||||
end
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
% Vol = local_TV_zsplit(Vol, lambda, eps, Niter, use_chambolle)
|
||||
% FUNCTION
|
||||
% - split volume on smaller blocks for processing by local total variation
|
||||
% - splitting is done automatically in order to fit to GPU memory
|
||||
% Inputs:
|
||||
% Vol - refined volume
|
||||
% lambda - refinement step (tunning constant)
|
||||
% eps - regularization term (tunning constant)
|
||||
% Niter - number of iterations
|
||||
% use_chambolle - if true use Chambolle method, if false use simple gradient descent solver
|
||||
% Recompile:
|
||||
% mexcuda -output +regularization/private/local_TV_mex +regularization/private/TV_cuda_texture.cu +regularization/private/local_TV_mex.cpp
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| 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 Vol = local_TV_zsplit(Vol, lambda, eps, Niter, use_chambolle)
|
||||
|
||||
keep_on_gpu = isa(Vol, 'gpuArray');
|
||||
|
||||
gpu = gpuDevice;
|
||||
Nlayers = size(Vol,3);
|
||||
Nblocks = ceil(numel(Vol)*4 / 1024e6);
|
||||
% empirically tested condition
|
||||
Nblocks = max(Nblocks, ceil((numel(Vol)*4*14) / gpu.AvailableMemory));
|
||||
Nlayers_on_GPU = ceil(Nlayers/Nblocks);
|
||||
Nblocks = ceil(Nlayers/Nlayers_on_GPU);
|
||||
if Nblocks > 1
|
||||
for i = 1:Nblocks
|
||||
utils.progressbar(i, ceil(Nlayers/Nlayers_on_GPU))
|
||||
ind = (1+(i-1)*Nlayers_on_GPU):min(i*Nlayers_on_GPU, Nlayers);
|
||||
Vol_tmp = gpuArray(Vol(:,:,ind));
|
||||
Vol_tmp = local_TV_mex(Vol_tmp,lambda,eps, Niter, use_chambolle);
|
||||
if ~keep_on_gpu; Vol_tmp = gather(Vol_tmp);end
|
||||
Vol(:,:,ind) = Vol_tmp;
|
||||
end
|
||||
else
|
||||
Vol = local_TV_mex(Vol,lambda,eps, Niter, use_chambolle);
|
||||
if ~keep_on_gpu; Vol = gather(Vol);end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,100 @@
|
||||
% [Im] = nonlocalTV_GPU(Im0,CloseInd, Neighbours, Rwin,Niter,lambda, dt, eps)
|
||||
% FUNCTION
|
||||
% nonlocal total variation solved by a simple steepest descent solver
|
||||
% Inputs:
|
||||
% Im0 - regularized array (3D volume)
|
||||
% CloseInd - close indices generated by nonlocalTV_weight code
|
||||
% Neighbours - number of neighbors used for calculation
|
||||
% Rwin - radius of the window used to find similar regions
|
||||
% Niter - number of reconstruction iterations
|
||||
% lambda - step size (tunning value), usually < 1, if zero ->
|
||||
% completelly ignore data and just find the solution that most fits to
|
||||
% nonlocal TV constraint
|
||||
% dt - also kind of step size (tunning value), usually << 1
|
||||
% eps - regularization constant (tunning value), usually << 1
|
||||
% RECOMPILE COMMAND
|
||||
% mexcuda -output +regularization/private/nonlocalTV_tex +regularization/private/TV_cuda_texture.cu +regularization/private/nonlocalTV_mex.cpp
|
||||
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| 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 [Im] = nonlocalTV_GPU(Im0,CloseInd, Neighbours, Rwin,Niter,lambda, dt, eps)
|
||||
|
||||
keep_on_gpu = isa(Im0, 'gpuArray');
|
||||
|
||||
CloseInd = gpuArray(uint8(CloseInd));
|
||||
Im0 = gpuArray(single(Im0));
|
||||
|
||||
try
|
||||
%Input should be between 0 and 1 to make the regularizations constants selection
|
||||
%kind of repeatable for similar samples
|
||||
minIm=min(Im0(:));
|
||||
Im0=Im0-minIm;
|
||||
maxIm=prctile(Im0(1:10:end), 99);
|
||||
Im0=Im0/maxIm;
|
||||
|
||||
catch err
|
||||
error(err.message)
|
||||
|
||||
end
|
||||
|
||||
Nclose = size(CloseInd,ndims(CloseInd));
|
||||
|
||||
|
||||
|
||||
%% primitive replacement of the real weights based on assumption that CloseInd is sorted by importance !!!
|
||||
Nnbrs = size(CloseInd,ndims(CloseInd));
|
||||
% Nbrs_weights = single(exp(-linspace(0,1,Nnbrs)));
|
||||
Nbrs_weights = single(1./(1:Nnbrs));
|
||||
% Nbrs_weights = ones(Nnbrs,1, 'single');
|
||||
|
||||
% keyboard
|
||||
|
||||
% tic
|
||||
Im = nonlocalTV_tex(Im0,CloseInd,uint8(Neighbours), Nbrs_weights, dt, eps, lambda, Nclose, Rwin,Niter);
|
||||
% wait(gpu)
|
||||
% toc
|
||||
|
||||
|
||||
%Back to original pixel range
|
||||
Im=Im*maxIm;
|
||||
Im=Im+minIm;
|
||||
|
||||
if ~keep_on_gpu
|
||||
Im = gather(Im);
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
@@ -0,0 +1,157 @@
|
||||
% [CloseInd,Neighbours] = nonlocalTV_weight_GPU(Im0, Rpatch, Rwin, Nclose, sigma)
|
||||
% FUNCTION
|
||||
% find close indices for the nonlocalTV_GPU method , similar to the nonlocal means method
|
||||
% Inputs:
|
||||
% Im0 - volume to be regularized
|
||||
% Rpatch - radius of the patch used to ocompare similarities
|
||||
% Rwin - radius of the window used to find similar regions
|
||||
% Nclose - number of most similar regions searched
|
||||
% sigma - similarity threshold, (tunning constant, value < 1)
|
||||
% Outputs:
|
||||
% CloseInd - close indices generated by nonlocalTV_weight code
|
||||
% Neighbours - list of neighboring pixels used for calculation and excluded from CloseInd
|
||||
|
||||
|
||||
% RECOMPILE COMMAND
|
||||
% mexcuda -output +regularization/private/nonlocalTV_weight_tex +regularization/private/TV_cuda_texture.cu +regularization/private/nonlocalTV_mex_weight.cpp
|
||||
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| 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 [CloseInd,Neighbours] = nonlocalTV_weight_GPU(Im0, Rpatch, Rwin, Nclose, sigma)
|
||||
%% nonlocal TV
|
||||
|
||||
% mexcuda -output nonlocalTV_weight_tex TV_cuda_texture.cu nonlocalTV_mex_weight.cpp
|
||||
|
||||
|
||||
Nwin= 2*Rwin+1;
|
||||
Nclose_min=2;
|
||||
Nclose_max = 256;
|
||||
|
||||
if Nclose > Nclose_max
|
||||
error('Nclose is more than Nclose_max')
|
||||
end
|
||||
if ismatrix(Im0)
|
||||
assert(Nwin^2 < Nclose_max, 'Too large Nwin')
|
||||
% Neighbours=uint8(sub2ind([Nwin,Nwin],...
|
||||
% Rwin+1+[0,-1,1,0,0],Rwin+1+[0,0,0,-1,1]));
|
||||
Neighbours=uint8(sub2ind([Nwin,Nwin],...
|
||||
Rwin+1,Rwin+1));
|
||||
else
|
||||
assert(Nwin^3 < Nclose_max, 'Too large Nwin')
|
||||
% include all neighbors
|
||||
% Neighbours=uint8(sub2ind([Nwin,Nwin,Nwin],...
|
||||
% Rwin+1+[0,-1,1,0,0,0,0], ...
|
||||
% Rwin+1+[0,0,0,-1,1,0,0], ...
|
||||
% Rwin+1+[0,0,0,0,0,-1,1]));
|
||||
% only the central point !!
|
||||
Neighbours=uint8(sub2ind([Nwin,Nwin,Nwin],...
|
||||
Rwin+1, Rwin+1,Rwin+1));
|
||||
end
|
||||
|
||||
% keyboard
|
||||
|
||||
[Nx, Ny, Nz] = size(Im0);
|
||||
MAX_SIZE = 512; %% TESTED FOR TITAN X 12GB !!!
|
||||
% MAX_SIZE = 320; %% roughly for Quadro K4200
|
||||
split = ceil([Nx, Ny, Nz]/MAX_SIZE);
|
||||
|
||||
|
||||
|
||||
|
||||
if prod(split) == 1
|
||||
CloseInd = nonlocalTV_weight_GPU_partial(Im0, Rpatch, Rwin, Nclose,Nclose_min,sigma, Neighbours);
|
||||
else %% in case of too large datasets
|
||||
warning('Volume is too large, it will be sliced')
|
||||
CloseInd = zeros(Nx, Ny,Nz,Nclose, 'uint8');
|
||||
ind = {':',':',':'};
|
||||
|
||||
for i = 1:split(1)
|
||||
ind{1} = (1+(i-1)*ceil(Nx/split(1))):min(Nx,i*ceil(Nx/split(1)));
|
||||
for j = 1:split(2)
|
||||
ind{2} = (1+(j-1)*ceil(Ny/split(2))):min(Ny,j*ceil(Ny/split(2)));
|
||||
for k = 1:split(3)
|
||||
ind{3} = (1+(k-1)*ceil(Nz/split(3))):min(Nz,j*ceil(Nz/split(3)));
|
||||
CloseInd(ind{:},:) = gather(nonlocalTV_weight_GPU_partial(Im0(ind{:}), Rpatch, Rwin, Nclose,Nclose_min, sigma, Neighbours));
|
||||
utils.progressbar(k + (j-1)*split(2)+(i-1)*split(1)*split(2), prod(split))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
end
|
||||
|
||||
function CloseInd = nonlocalTV_weight_GPU_partial(Im0, Rpatch, Rwin, Nclose, Nclose_min, sigma, Neighbours)
|
||||
|
||||
|
||||
Im0_gpu = gpuArray(single(Im0));
|
||||
|
||||
|
||||
|
||||
Npatch= 2*Rpatch+1;
|
||||
%% get simple estimate of the average gradients
|
||||
|
||||
if ismatrix(Im0_gpu)
|
||||
dx = diff(Im0_gpu,1,1);
|
||||
dx = dx(:,2:end).^2;
|
||||
dy = diff(Im0_gpu,1,2);
|
||||
dy = dy(2:end,:).^2;
|
||||
ker = ones(Npatch, 'single');
|
||||
threshold = mean2(sqrt(conv2( (dx + dy)/2,ker, 'same')));
|
||||
elseif ndims(Im0_gpu) == 3
|
||||
dx = diff(Im0_gpu,1,1);
|
||||
dx = dx(:,2:end,2:end).^2;
|
||||
dy = diff(Im0_gpu,1,2);
|
||||
dy = dy(2:end,:,2:end).^2;
|
||||
dz = diff(Im0_gpu,1,3);
|
||||
dz = dz(2:end,2:end,:).^2;
|
||||
ker = ones([Npatch,Npatch,Npatch], 'single');
|
||||
threshold = mean2(sqrt(convn( (dx + dy + dz)/3,ker, 'same')));
|
||||
end
|
||||
|
||||
|
||||
% sigma is changing the threshold level
|
||||
%% patched more different than threshold will be rejected !!!
|
||||
threshold = gather(threshold ) * sigma;
|
||||
clear dx dy dz
|
||||
|
||||
% tic
|
||||
CloseInd = nonlocalTV_weight_tex(Im0_gpu,Neighbours,Nclose,Nclose_min,Rwin,Rpatch,threshold);
|
||||
% toc
|
||||
|
||||
end
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,23 @@
|
||||
#ifndef TV_GPU_tex_HPP
|
||||
#define TV_GPU_tex_HPP
|
||||
|
||||
#include "tmwtypes.h"
|
||||
|
||||
|
||||
int checkLastError(char * msg);
|
||||
|
||||
void nonlocal_TV_init( float * Img, const float * Img0, const uint8_T *CloseInd,
|
||||
const uint8_T * neighbours, const float * p_Nbrs_weights, const float dt, const float eps, const float lambda,const unsigned int Nclose, const unsigned int Nbrs, const int Rwin,
|
||||
const unsigned int N, const unsigned int M, const unsigned int O, const unsigned int Niter);
|
||||
|
||||
void nonlocal_weight_TV_init( uint8_T *c, const float * p,
|
||||
const uint8_T * neighbours, const unsigned int Nclose, const unsigned int Nclose_min, const unsigned int Nbrs, const int Rwin, const int Rpatch,
|
||||
const unsigned int N, const unsigned int M, const unsigned int O, const float threshold);
|
||||
|
||||
void local_TV_init( float * Img, const float dt, const float eps, const unsigned int M, const unsigned int N, const unsigned int O, const unsigned int Niter);
|
||||
|
||||
void local_TV_chambolle_init( float * Img, float ** Xi, const float dt, const float tau,
|
||||
const unsigned int M, const unsigned int N, const unsigned int O, const unsigned int Niter);
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,124 @@
|
||||
#include "mex.h"
|
||||
#include "gpu/mxGPUArray.h"
|
||||
#include "TV_texture.hpp"
|
||||
|
||||
//mexcuda -output private/local_TV_mex private/TV_cuda_texture.cu private/local_TV_mex.cpp
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
|
||||
|
||||
*-----------------------------------------------------------------------*
|
||||
| |
|
||||
| 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
|
||||
|
||||
|
||||
*
|
||||
* MEX gateway
|
||||
*/
|
||||
void mexFunction(int nlhs , mxArray *plhs[],
|
||||
int nrhs, mxArray const *prhs[])
|
||||
{
|
||||
char const * const errId = "parallel:gpu:mexGPUExample:InvalidInput";
|
||||
char const * const errMsg = "Invalid input to MEX file.";
|
||||
|
||||
// Initialize the MathWorks GPU API.
|
||||
mxInitGPU();
|
||||
|
||||
if (nrhs!=5) {
|
||||
mexPrintf("Wrong number of inputs\n");
|
||||
mexErrMsgIdAndTxt(errId, errMsg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
const float dt = (float)mxGetScalar(prhs[1]);
|
||||
const float tau = (float)mxGetScalar(prhs[2]);
|
||||
const int Niter = (int)mxGetScalar(prhs[3]);
|
||||
const int UseChambolle = (int)mxGetScalar(prhs[4]);
|
||||
|
||||
/* allocate output image field */
|
||||
mxGPUArray * m_Img_new = mxGPUCopyFromMxArray(prhs[0]);
|
||||
if ((mxGPUGetClassID(m_Img_new) != mxSINGLE_CLASS)) {
|
||||
mexPrintf("m_Img_new\n");
|
||||
mexErrMsgIdAndTxt(errId, errMsg);
|
||||
}
|
||||
float * p_Img_new = (float *)mxGPUGetData(m_Img_new);
|
||||
|
||||
|
||||
mwSize const * dimensions = mxGPUGetDimensions(m_Img_new);
|
||||
mwSize Ndim = mxGPUGetNumberOfDimensions(m_Img_new);
|
||||
int M = (int)dimensions[0];
|
||||
int N = (int)dimensions[1];
|
||||
int O = Ndim > 2 ? (int)dimensions[2] : 1;
|
||||
mxGPUArray * mXi[3] ;
|
||||
|
||||
if (UseChambolle ) {
|
||||
/* allocate Xi field */
|
||||
float * Xi[3] ;
|
||||
mwSize xiSize[3] = {M,N,O};
|
||||
|
||||
for( int i = 0; i < 3; i++) {
|
||||
mXi[i] = mxGPUCreateGPUArray(3,
|
||||
xiSize,
|
||||
mxSINGLE_CLASS,
|
||||
mxREAL,
|
||||
MX_GPU_INITIALIZE_VALUES);
|
||||
Xi[i] = (float *)mxGPUGetData(mXi[i]);
|
||||
}
|
||||
//mexPrintf("local_TV_chambolle_init\n");
|
||||
local_TV_chambolle_init( p_Img_new, Xi, dt, tau, M, N, O, Niter);
|
||||
} else {
|
||||
// mexPrintf("local_TV_init\n");
|
||||
local_TV_init( p_Img_new, dt, tau, N, M, O, Niter);
|
||||
}
|
||||
|
||||
|
||||
|
||||
checkLastError("After iteration");
|
||||
|
||||
//mexcuda -output utils3D\local_TV_mex utils3D\TV_cuda_texture.cu utils3D\local_TV_mex.cpp
|
||||
|
||||
|
||||
|
||||
plhs[0] = mxGPUCreateMxArrayOnGPU(m_Img_new);
|
||||
|
||||
mxGPUDestroyGPUArray(m_Img_new);
|
||||
if (UseChambolle )
|
||||
for( int i = 0; i < 3; i++)
|
||||
mxGPUDestroyGPUArray( mXi[i]);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
|
||||
#include "mex.h"
|
||||
#include "gpu/mxGPUArray.h"
|
||||
#include "TV_texture.hpp"
|
||||
|
||||
/**
|
||||
*
|
||||
**-----------------------------------------------------------------------*
|
||||
| |
|
||||
| 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
|
||||
|
||||
*
|
||||
*
|
||||
* MEX gateway
|
||||
*/
|
||||
void mexFunction(int nlhs , mxArray *plhs[],
|
||||
int nrhs, mxArray const *prhs[])
|
||||
{
|
||||
char const * const errId = "parallel:gpu:mexGPUExample:InvalidInput";
|
||||
char const * const errMsg = "Invalid input to MEX file.";
|
||||
|
||||
// Initialize the MathWorks GPU API.
|
||||
mxInitGPU();
|
||||
|
||||
if (nrhs!=10) {
|
||||
mexPrintf("nargin\n");
|
||||
mexErrMsgIdAndTxt(errId, errMsg);
|
||||
}
|
||||
|
||||
// Im0,CloseInd,neighbours, dt, eps, lambda, Nclose, Rwin, Niter, Nx, Ny
|
||||
|
||||
|
||||
|
||||
mxGPUArray const * m_Img = mxGPUCreateFromMxArray(prhs[0]);
|
||||
if ((mxGPUGetClassID(m_Img) != mxSINGLE_CLASS)) {
|
||||
mexPrintf("m_Img\n");
|
||||
mexErrMsgIdAndTxt(errId, errMsg);
|
||||
}
|
||||
const float * p_Img = (float *)mxGPUGetDataReadOnly(m_Img);
|
||||
|
||||
mxGPUArray const * m_CloseInd = mxGPUCreateFromMxArray(prhs[1]);
|
||||
if ((mxGPUGetClassID(m_CloseInd) != mxUINT8_CLASS)) {
|
||||
mexPrintf("m_CloseInd\n");
|
||||
mexErrMsgIdAndTxt(errId, errMsg);
|
||||
}
|
||||
const uint8_T * p_CloseInd = (uint8_T *)mxGPUGetDataReadOnly(m_CloseInd);
|
||||
|
||||
|
||||
mxGPUArray const * m_Nbrs = mxGPUCreateFromMxArray(prhs[2]);
|
||||
if ((mxGPUGetClassID(m_Nbrs) != mxUINT8_CLASS)) {
|
||||
mexPrintf("m_Nbrs\n");
|
||||
mexErrMsgIdAndTxt(errId, errMsg);
|
||||
}
|
||||
const uint8_T * p_Nbrs = (uint8_T *)mxGPUGetDataReadOnly(m_Nbrs);
|
||||
|
||||
mxGPUArray const * mNbrs_weights = mxGPUCreateFromMxArray(prhs[3]);
|
||||
if ((mxGPUGetClassID(mNbrs_weights) != mxSINGLE_CLASS)) {
|
||||
mexPrintf("mNbrs_weights\n");
|
||||
mexErrMsgIdAndTxt(errId, errMsg);
|
||||
}
|
||||
const float * p_Nbrs_weights = (float *)mxGPUGetDataReadOnly(mNbrs_weights);
|
||||
|
||||
|
||||
|
||||
const float dt = (float)mxGetScalar(prhs[4]);
|
||||
const float eps = (float)mxGetScalar(prhs[5]);
|
||||
const float lambda = (float)mxGetScalar(prhs[6]);
|
||||
|
||||
const int Nclose = (int)mxGetScalar(prhs[7]);
|
||||
const int Rwin = (int)mxGetScalar(prhs[8]);
|
||||
|
||||
const int Niter = (int)mxGetScalar(prhs[9]);
|
||||
|
||||
const int Nnbrs = mxGetNumberOfElements(prhs[2]);
|
||||
|
||||
|
||||
mwSize const * dimensions = mxGPUGetDimensions(m_Img);
|
||||
mwSize Ndim = mxGPUGetNumberOfDimensions(m_Img);
|
||||
int M = (int)dimensions[0];
|
||||
int N = (int)dimensions[1];
|
||||
int O = Ndim > 2 ? (int)dimensions[2] : 1;
|
||||
|
||||
|
||||
|
||||
/* allocate output image field */
|
||||
mxGPUArray * m_Img_new = mxGPUCopyFromMxArray(prhs[0]);
|
||||
float * p_Img_new = (float *)mxGPUGetData(m_Img_new);
|
||||
|
||||
|
||||
// for(int i = 0; i < Nnbrs; i++)
|
||||
// mexPrintf("neighbours %i\n", p_Nbrs[i]);
|
||||
// for(int i = 0; i < Nnbrs; i++)
|
||||
// mexPrintf("Nbrs_weights %g\n", p_Nbrs_weights[i]);
|
||||
|
||||
|
||||
|
||||
nonlocal_TV_init( p_Img_new, p_Img, p_CloseInd, p_Nbrs, p_Nbrs_weights, dt, eps,
|
||||
lambda, Nclose, Nnbrs, Rwin, N, M, O, Niter);
|
||||
checkLastError("After iteration");
|
||||
|
||||
|
||||
|
||||
plhs[0] = mxGPUCreateMxArrayOnGPU(m_Img_new);
|
||||
mxGPUDestroyGPUArray(m_CloseInd);
|
||||
mxGPUDestroyGPUArray(m_Img);
|
||||
mxGPUDestroyGPUArray(m_Nbrs);
|
||||
mxGPUDestroyGPUArray(m_Img_new);
|
||||
mxGPUDestroyGPUArray(mNbrs_weights);
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
|
||||
#include "mex.h"
|
||||
#include "gpu/mxGPUArray.h"
|
||||
#include "TV_texture.hpp"
|
||||
|
||||
/**
|
||||
*
|
||||
**-----------------------------------------------------------------------*
|
||||
| |
|
||||
| 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
|
||||
|
||||
*
|
||||
*
|
||||
* MEX gateway
|
||||
*/
|
||||
void mexFunction(int nlhs , mxArray *plhs[],
|
||||
int nrhs, mxArray const *prhs[])
|
||||
{
|
||||
char const * const errId = "parallel:gpu:mexGPUExample:InvalidInput";
|
||||
char const * const errMsg = "Invalid input to MEX file.";
|
||||
|
||||
// Initialize the MathWorks GPU API.
|
||||
mxInitGPU();
|
||||
|
||||
if (nrhs!=7) {
|
||||
mexPrintf("nargin\n");
|
||||
mexErrMsgIdAndTxt(errId, errMsg);
|
||||
}
|
||||
|
||||
mxGPUArray const * m_Img = mxGPUCreateFromMxArray(prhs[0]);
|
||||
if ((mxGPUGetClassID(m_Img) != mxSINGLE_CLASS)) {
|
||||
mexPrintf("m_Img\n");
|
||||
mexErrMsgIdAndTxt(errId, errMsg);
|
||||
}
|
||||
const float * p_Img = (float *)mxGPUGetDataReadOnly(m_Img);
|
||||
|
||||
|
||||
|
||||
mxGPUArray const * m_Nbrs = mxGPUCreateFromMxArray(prhs[1]);
|
||||
if ((mxGPUGetClassID(m_Nbrs) != mxUINT8_CLASS)) {
|
||||
mexPrintf("m_Nbrs\n");
|
||||
|
||||
mexErrMsgIdAndTxt(errId, errMsg);
|
||||
}
|
||||
const uint8_T * p_Nbrs = (uint8_T *)mxGPUGetDataReadOnly(m_Nbrs);
|
||||
|
||||
|
||||
const int Nclose = (int)mxGetScalar(prhs[2]);
|
||||
const int Nclose_min = (int)mxGetScalar(prhs[3]);
|
||||
|
||||
const int Rwin = (int)mxGetScalar(prhs[4]);
|
||||
const int Rpatch = (int)mxGetScalar(prhs[5]);
|
||||
const float threshold = (float)mxGetScalar(prhs[6]);
|
||||
|
||||
//mexPrintf("thresh %3.5g \n ", threshold);
|
||||
|
||||
|
||||
|
||||
mwSize const * dimensions = mxGPUGetDimensions(m_Img);
|
||||
mwSize const Ndim = mxGPUGetNumberOfDimensions(m_Img);
|
||||
const int M = (int)dimensions[0];
|
||||
const int N = (int)dimensions[1];
|
||||
const int O = Ndim > 2 ? (int)dimensions[2] : 1;
|
||||
|
||||
// mexPrintf("%i %i %i \n ", M,N,O);
|
||||
// mexPrintf("Nc %i Rw %i Rp%i \n ", Nclose, Rwin, Rpatch);
|
||||
|
||||
const int Nnbrs = mxGetNumberOfElements(prhs[1]);
|
||||
|
||||
|
||||
|
||||
/* allocate index of closest patches field */
|
||||
mwSize matSize[4];
|
||||
matSize[0] = M;
|
||||
matSize[1] = N;
|
||||
matSize[2] = O;
|
||||
matSize[3] = Nclose;
|
||||
mxGPUArray* m_CloseInd = mxGPUCreateGPUArray(4,
|
||||
matSize,
|
||||
mxUINT8_CLASS,
|
||||
mxREAL,
|
||||
MX_GPU_INITIALIZE_VALUES);
|
||||
|
||||
|
||||
uint8_T * p_CloseInd = (uint8_T *)mxGPUGetData(m_CloseInd);
|
||||
|
||||
// mexPrintf("%i %i %i \n ", matSize[0], matSize[1], matSize[2]);
|
||||
|
||||
|
||||
|
||||
nonlocal_weight_TV_init( p_CloseInd, p_Img, p_Nbrs, Nclose,Nclose_min, Nnbrs, Rwin, Rpatch, N, M, O, threshold);
|
||||
|
||||
|
||||
|
||||
plhs[0] = mxGPUCreateMxArrayOnGPU(m_CloseInd);
|
||||
mxGPUDestroyGPUArray(m_CloseInd);
|
||||
mxGPUDestroyGPUArray(m_Img);
|
||||
mxGPUDestroyGPUArray(m_Nbrs);
|
||||
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user