mirror of
https://github.com/c-sooyoung/fold_slice.git
synced 2026-09-17 19:29:08 +09:00
163 lines
5.9 KiB
Matlab
163 lines
5.9 KiB
Matlab
% IMSHIFT_FAST shift of stack of images by given number of
|
||
% pixels and if needed crop / pad image to fit into Npix_new
|
||
%
|
||
% img_new=imshift_fast(img_0, x,y, Npix_new=[], type='linear', default_val=0)
|
||
%
|
||
% Inputs:
|
||
% **img_0 - stack of images
|
||
% **x,y - horizontal / vertical shift in pixels (scalars)
|
||
% **Npix_new - empty/missing => keep original size, 2x1 vector => embed new image into given frame size
|
||
% **type - linear / nearest neighbor interpolation , (missing/empty => linear)
|
||
% **default_val - default value to fill empty regions created after the image shift
|
||
% returns:
|
||
% ++ img_new - shifted image padded to Npix_new
|
||
|
||
|
||
%*-----------------------------------------------------------------------*
|
||
%| |
|
||
%| 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 img_new=imshift_fast(img_0, x,y, Npix_new, type, default_val)
|
||
|
||
|
||
if nargin < 4 || isempty(Npix_new)
|
||
Npix_new = size(img_0);
|
||
end
|
||
Npix_new = Npix_new(1:2);
|
||
if nargin < 5
|
||
type = 'linear';
|
||
end
|
||
if nargin < 6
|
||
default_val = 0;
|
||
end
|
||
if length(x) > 1 || length(y) > 1
|
||
error('Only scalar position shifts are accepted')
|
||
end
|
||
|
||
[Nx, Ny, Nimgs] = size(img_0);
|
||
|
||
|
||
if x==0 && y == 0 && all([Nx,Ny] == Npix_new)
|
||
%% no change is needed, return original image
|
||
img_new = img_0;
|
||
return
|
||
end
|
||
|
||
|
||
pos = -[x,y];
|
||
if strcmp(type, 'linear') && any(round([x,y]) ~= [x,y]) && ~isa(img_0, 'logical')
|
||
shift = make_shift(pos - round(pos));
|
||
|
||
Npix_tmp = size(img_0);
|
||
Npix_tmp(1:2) = Npix_tmp(1:2) + 2;
|
||
img_tmp = zeros(Npix_tmp, 'like', img_0 );
|
||
for i = 1:Nimgs
|
||
img_tmp(:,:,i) = conv2(img_0(:,:,i), shift, 'full');
|
||
end
|
||
img_0 = img_tmp;
|
||
end
|
||
Npix = [Nx,Ny];
|
||
|
||
[oROI, pROI] = find_ROI( pos ,Npix_new, Npix );
|
||
|
||
|
||
if all(x==0) && all(y == 0) && all(Npix_new < Npix)
|
||
img_new = img_0(pROI{:},:);
|
||
else
|
||
if all(abs(pos) <= 1) && all( Npix_new == Npix)
|
||
img_new = img_0; % for tiny shift reuse the original array
|
||
else
|
||
img_new = ones([Npix_new,Nimgs], 'like', img_0 )*default_val;
|
||
end
|
||
img_new(oROI{:}, :) = img_0(pROI{:}, :);
|
||
end
|
||
end
|
||
|
||
function [oROI, pROI, oROI_, pROI_] = find_ROI( position, Nobj_new, Nobj_0 )
|
||
|
||
oROI = cell(2,1);
|
||
pROI = cell(2,1);
|
||
|
||
pos = round(position([2,1]));
|
||
%% correction for odd size of the Nobj_new
|
||
pos = pos - mod(Nobj_0-Nobj_new,2) .* (Nobj_new > Nobj_0);
|
||
oROI_ = zeros(2);
|
||
pROI_ = zeros(2);
|
||
for dim = 1:2
|
||
range_0 = round(pos(dim) + [1,Nobj_0(dim)] - Nobj_0(dim)/2 + Nobj_new(dim)/2);
|
||
oROI_(dim,:) = min(max(1,range_0), Nobj_new(dim));
|
||
l = oROI_(dim,2) - oROI_(dim,1) +1;
|
||
p1 = min(Nobj_0(dim), Nobj_0(dim) - (range_0(2) - Nobj_new(dim)));
|
||
pROI_(dim,1) = p1 - l+1;
|
||
pROI_(dim,2) = p1;
|
||
if pROI_(dim,1) < pROI_(dim,2)
|
||
pROI{dim} = pROI_(dim,1):pROI_(dim,2);
|
||
else
|
||
pROI{dim} = [];
|
||
end
|
||
if oROI_(dim,1) < oROI_(dim,2)
|
||
oROI{dim} = oROI_(dim,1):oROI_(dim,2);
|
||
else
|
||
oROI{dim} = [];
|
||
end
|
||
end
|
||
end
|
||
|
||
|
||
function shift_mat = make_shift(shift)
|
||
|
||
x = shift(2); % correction on pixel position
|
||
y = shift(1);
|
||
N = max(1, ceil(abs([x,y])));
|
||
x = x+N(1);
|
||
y = y+N(2);
|
||
dx = x-floor(x);
|
||
dy = y-floor(y);
|
||
|
||
|
||
w(1) = dx * dy;
|
||
w(2) = (1-dx) * dy;
|
||
w(3) = dx * (1-dy);
|
||
w(4) = (1-dx) * (1-dy);
|
||
|
||
ix = 1+floor(x);
|
||
iy = 1+floor(y);
|
||
|
||
shift_mat = zeros(2*N+1);
|
||
shift_mat(ix, iy) = w(4);
|
||
shift_mat(ix+1, iy) = w(3);
|
||
shift_mat(ix, iy+1) = w(2);
|
||
shift_mat(ix+1, iy+1) = w(1);
|
||
end
|