Xmipp  v3.23.11-Nereus
bspline_helper.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  *
3  * Authors: David Strelak (davidstrelak@gmail.com)
4  *
5  * Unidad de Bioinformatica of Centro Nacional de Biotecnologia , CSIC
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20  * 02111-1307 USA
21  *
22  * All comments concerning this program package may be sent to the
23  * e-mail address 'xmipp@cnb.csic.es'
24  ***************************************************************************/
25 
26 #include "bspline_helper.h"
27 
28 template
29 std::pair<Matrix1D<float>, Matrix1D<float>> BSplineHelper::computeBSplineCoeffs(const Dimensions &movieSize,
30  const LocalAlignmentResult<float> &alignment,
31  const Dimensions &controlPoints, const std::pair<size_t, size_t> &noOfPatches,
32  int verbosity, int solverIters);
33 template<typename T>
34 std::pair<Matrix1D<T>, Matrix1D<T>> BSplineHelper::computeBSplineCoeffs(const Dimensions &movieSize,
35  const LocalAlignmentResult<T> &alignment,
36  const Dimensions &controlPoints, const std::pair<size_t, size_t> &noOfPatches,
37  int verbosity, int solverIters) {
38  if(verbosity) std::cout << "Computing BSpline coefficients" << std::endl;
39  // get coefficients of the BSpline that can represent the shifts (formula from the paper)
40  int lX = controlPoints.x();
41  int lY = controlPoints.y();
42  int lT = controlPoints.n();
43  int noOfPatchesXY = noOfPatches.first * noOfPatches.second;
44  Matrix2D<T>A(noOfPatchesXY*movieSize.n(), lX * lY * lT);
45  Matrix1D<T>bX(noOfPatchesXY*movieSize.n());
46  Matrix1D<T>bY(noOfPatchesXY*movieSize.n());
47  T hX = (lX == 3) ? movieSize.x() : (movieSize.x() / (T)(lX-3));
48  T hY = (lY == 3) ? movieSize.y() : (movieSize.y() / (T)(lY-3));
49  T hT = (lT == 3) ? movieSize.n() : (movieSize.n() / (T)(lT-3));
50 
51  for (auto &&r : alignment.shifts) {
52  auto meta = r.first;
53  auto shift = r.second;
54  int tileIdxT = meta.id_t;
55  int tileCenterT = tileIdxT * 1 + 0 + 0;
56  int tileIdxX = meta.id_x;
57  int tileIdxY = meta.id_y;
58  int tileCenterX = meta.rec.getCenter().x;
59  int tileCenterY = meta.rec.getCenter().y;
60  int i = (tileIdxY * noOfPatches.first) + tileIdxX;
61 
62  for(int controlIdxT = -1; controlIdxT < (lT - 1); ++controlIdxT) {
63  T tmpT = Bspline03((tileCenterT / hT) - controlIdxT);
64  if (tmpT == (T)0) continue;
65  for(int controlIdxY = -1; controlIdxY < (lY - 1); ++controlIdxY) {
66  T tmpY = Bspline03((tileCenterY / hY) - controlIdxY);
67  if (tmpY == (T)0) continue;
68  for(int controlIdxX = -1; controlIdxX < (lX - 1); ++controlIdxX) {
69  T tmpX = Bspline03((tileCenterX / hX) - controlIdxX);
70  T val = tmpT * tmpY * tmpX;
71  int j = ((controlIdxT + 1) * lX * lY) +
72  ((controlIdxY + 1) * lX) + (controlIdxX + 1);
73  MAT_ELEM(A,tileIdxT*noOfPatchesXY + i, j) = val;
74  }
75  }
76  }
77  VEC_ELEM(bX,tileIdxT*noOfPatchesXY + i) = -shift.x; // we want the BSPline describing opposite transformation,
78  VEC_ELEM(bY,tileIdxT*noOfPatchesXY + i) = -shift.y; // so that we can use it to compensate for the shift
79  }
80 
81  // solve the equation system for the spline coefficients
82  Matrix1D<T> coefsX;
83  Matrix1D<T> coefsY;
84  EquationSystemSolver::solve(bX, bY, A, coefsX, coefsY, verbosity + 1, solverIters);
85  return std::make_pair(coefsX, coefsY);
86 }
87 
88 template
89 std::pair<float, float> BSplineHelper::getShift(const BSplineGrid<float> &grid, Dimensions dim,
90  size_t x, size_t y, size_t n);
91 template
92 std::pair<double, double> BSplineHelper::getShift(const BSplineGrid<double> &grid, Dimensions dim,
93  size_t x, size_t y, size_t n);
94 template<typename T>
95 std::pair<T, T> BSplineHelper::getShift(const BSplineGrid<T> &grid, Dimensions dim,
96  size_t x, size_t y, size_t n) {
97  T shiftX = 0;
98  T shiftY = 0;
99  getShift(grid.getDim().x(), grid.getDim().y(), grid.getDim().n(),
100  dim.x(), dim.y(), dim.n(),
101  x, y, n,
102  shiftX, shiftY,
103  grid.getCoeffsX().vdata, grid.getCoeffsY().vdata);
104 
105  return std::make_pair(shiftX, shiftY);
106 }
107 
108 template<typename T>
109 void BSplineHelper::getShift(int lX, int lY, int lN,
110  int xdim, int ydim, int ndim,
111  int x, int y, int n,
112  T &shiftY, T &shiftX,
113  const T *coeffsX, const T *coeffsY) {
114  using std::max;
115  using std::min;
116 
117  T delta = 0.0001;
118  // take into account end points
119  T hX = (lX == 3) ? xdim : (xdim / (T) (lX - 3));
120  T hY = (lY == 3) ? ydim : (ydim / (T) (lY - 3));
121  T hT = (lN == 3) ? ndim : (ndim / (T) (lN - 3));
122  // index of the 'cell' where pixel is located (<0, N-3> for N control points)
123  T xPos = x / hX;
124  T yPos = y / hY;
125  T tPos = n / hT;
126  // indices of the control points are from -1 .. N-2 for N points
127  // pixel in 'cell' 0 may be influenced by points with indices <-1,2>
128  for (int idxT = max(-1, (int) (tPos) - 1);
129  idxT <= min((int) (tPos) + 2, lN - 2);
130  ++idxT) {
131  T tmpT = Bspline03(tPos - idxT);
132  for (int idxY = max(-1, (int) (yPos) - 1);
133  idxY <= min((int) (yPos) + 2, lY - 2);
134  ++idxY) {
135  T tmpY = Bspline03(yPos - idxY);
136  for (int idxX = max(-1, (int) (xPos) - 1);
137  idxX <= min((int) (xPos) + 2, lX - 2);
138  ++idxX) {
139  T tmpX = Bspline03(xPos - idxX);
140  T tmp = tmpX * tmpY * tmpT;
141  if (fabsf(tmp) > delta) {
142  size_t coeffOffset = (idxT + 1) * (lX * lY)
143  + (idxY + 1) * lX + (idxX + 1);
144  shiftX += coeffsX[coeffOffset] * tmp;
145  shiftY += coeffsY[coeffOffset] * tmp;
146  }
147  }
148  }
149  }
150 }
void min(Image< double > &op1, const Image< double > &op2)
#define VEC_ELEM(v, i)
Definition: matrix1d.h:245
static std::pair< T, T > getShift(const BSplineGrid< T > &grid, Dimensions dim, size_t x, size_t y, size_t n)
std::vector< std::pair< FramePatchMeta< T >, Point2D< T > > > shifts
static double * y
static T Bspline03(T argument)
constexpr const Matrix1D< T > & getCoeffsX() const
Definition: bspline_grid.h:46
constexpr const Dimensions & getDim() const
Definition: bspline_grid.h:42
doublereal * x
#define i
constexpr const Matrix1D< T > & getCoeffsY() const
Definition: bspline_grid.h:50
#define MAT_ELEM(m, i, j)
Definition: matrix2d.h:116
Definition: mask.h:36
CUDA_HD constexpr size_t x() const
Definition: dimensions.h:51
static void solve(Matrix1D< T > &bXt, Matrix1D< T > &bYt, Matrix2D< T > &At, Matrix1D< T > &shiftXt, Matrix1D< T > &shiftYt, int verbosity, int iterations)
void max(Image< double > &op1, const Image< double > &op2)
CUDA_HD constexpr size_t y() const
Definition: dimensions.h:60
CUDA_HD constexpr size_t n() const
Definition: dimensions.h:78
#define j
static std::pair< Matrix1D< T >, Matrix1D< T > > computeBSplineCoeffs(const Dimensions &movieSize, const LocalAlignmentResult< T > &alignment, const Dimensions &controlPoints, const std::pair< size_t, size_t > &noOfPatches, int verbosity, int solverIters)
int * n
double * delta