Xmipp  v3.23.11-Nereus
Functions
applyGeometryImpl Namespace Reference

Functions

template<typename T1 , typename T , bool wrap>
void applyGeometry2DDegree1 (MultidimArray< T > &__restrict__ V2, const MultidimArray< T1 > &__restrict__ V1, const Matrix2D< double > &Aref)
 

Function Documentation

◆ applyGeometry2DDegree1()

template<typename T1 , typename T , bool wrap>
void applyGeometryImpl::applyGeometry2DDegree1 ( MultidimArray< T > &__restrict__  V2,
const MultidimArray< T1 > &__restrict__  V1,
const Matrix2D< double > &  Aref 
)

Definition at line 200 of file transformations.h.

204 {
205  // 2D transformation
206  const double Aref00=MAT_ELEM(Aref,0,0);
207  const double Aref10=MAT_ELEM(Aref,1,0);
208 
209  // Find center and limits of image
210  const double cen_y = (int)(YSIZE(V2) / 2);
211  const double cen_x = (int)(XSIZE(V2) / 2);
212  const double cen_yp = (int)(YSIZE(V1) / 2);
213  const double cen_xp = (int)(XSIZE(V1) / 2);
214  const double minxp = -cen_xp;
215  const double minyp = -cen_yp;
216  const double minxpp = minxp-XMIPP_EQUAL_ACCURACY;
217  const double minypp = minyp-XMIPP_EQUAL_ACCURACY;
218  const double maxxp = XSIZE(V1) - cen_xp - 1;
219  const double maxyp = YSIZE(V1) - cen_yp - 1;
220  const double maxxpp = maxxp+XMIPP_EQUAL_ACCURACY;
221  const double maxypp = maxyp+XMIPP_EQUAL_ACCURACY;
222  const int Xdim = XSIZE(V1);
223  const int Ydim = YSIZE(V1);
224 
225  // Now we go from the output image to the input image, ie, for any pixel
226  // in the output image we calculate which are the corresponding ones in
227  // the original image, make an interpolation with them and put this value
228  // at the output pixel
229 
230 #ifdef DEBUG_APPLYGEO
231  std::cout << "A\n" << Aref << std::endl
232  << "(cen_x ,cen_y )=(" << cen_x << "," << cen_y << ")\n"
233  << "(cen_xp,cen_yp)=(" << cen_xp << "," << cen_yp << ")\n"
234  << "(min_xp,min_yp)=(" << minxp << "," << minyp << ")\n"
235  << "(max_xp,max_yp)=(" << maxxp << "," << maxyp << ")\n";
236 #endif
237  // Calculate position of the beginning of the row in the output image
238  const double x = -cen_x;
239  double y = -cen_y;
240  for (size_t i = 0; i < YSIZE(V2); i++)
241  {
242  // Calculate this position in the input image according to the
243  // geometrical transformation
244  // they are related by
245  // coords_output(=x,y) = A * coords_input (=xp,yp)
246  double xp = x * MAT_ELEM(Aref, 0, 0) + y * MAT_ELEM(Aref, 0, 1) + MAT_ELEM(Aref, 0, 2);
247  double yp = x * MAT_ELEM(Aref, 1, 0) + y * MAT_ELEM(Aref, 1, 1) + MAT_ELEM(Aref, 1, 2);
248 
249  // Loop over j is splitted according to wrap (wrap==true is not
250  // vectorizable) and also according to SplineDegree value
251  // (I have not fully analyzed vector dependences for
252  // SplineDegree==3 and else branch)
253  if (wrap)
254  {
255  // This is original implementation
256  for (int j=0; j<XSIZE(V2) ;j++)
257  {
258 #ifdef DEBUG_APPLYGEO
259 
260  std::cout << "Computing (" << i << "," << j << ")\n";
261  std::cout << " (y, x) =(" << y << "," << x << ")\n"
262  << " before wrapping (y',x')=(" << yp << "," << xp << ") "
263  << std::endl;
264 #endif
265  bool x_isOut = XMIPP_RANGE_OUTSIDE_FAST(xp, minxpp, maxxpp);
266  bool y_isOut = XMIPP_RANGE_OUTSIDE_FAST(yp, minypp, maxypp);
267 
268  if (x_isOut)
269  {
270  xp = realWRAP(xp, minxp - 0.5, maxxp + 0.5);
271  }
272 
273  if (y_isOut)
274  {
275  yp = realWRAP(yp, minyp - 0.5, maxyp + 0.5);
276  }
277 
278 #ifdef DEBUG_APPLYGEO
279 
280  std::cout << " after wrapping (y',x')=(" << yp << "," << xp << ") "
281  << std::endl;
282  std::cout << " Interp = " << interp << std::endl;
283  // The following line sounds dangerous...
284  //x++;
285 #endif
286 
287  // Linear interpolation
288  // Calculate the integer position in input image, be
289  // careful that it is not the nearest but the one
290  // at the top left corner of the interpolation square.
291  // Ie, (0.7,0.7) would give (0,0)
292  // Calculate also weights for point m1+1,n1+1
293  double wx = xp + cen_xp;
294  double wy = yp + cen_yp;
295  int m1 = (int) wx;
296  int n1 = (int) wy;
297  int n2 = n1 + 1;
298  int m2 = m1 + 1;
299  wx = wx - m1;
300  wy = wy - n1;
301  double wx_1 = 1 - wx;
302  double wy_1 = 1 - wy;
303 
304  // m2 and n2 can be out by 1 so wrap must be check here
305  if (m2 >= Xdim)
306  m2 = 0;
307  if (n2 >= Ydim)
308  n2 = 0;
309 
310 #ifdef DEBUG_APPLYGEO
311  std::cout << " From (" << n1 << "," << m1 << ") and ("
312  << n2 << "," << m2 << ")\n";
313  std::cout << " wx= " << wx << " wy= " << wy
314  << std::endl;
315 #endif
316 
317  // Perform interpolation
318  double v1 = wy_1 * wx_1 * DIRECT_A2D_ELEM(V1, n1, m1);
319  double v2 = wy_1 * wx * DIRECT_A2D_ELEM(V1, n1, m2);
320  double v3 = wx_1 * wy * DIRECT_A2D_ELEM(V1, n2, m1);
321  double v4 = wx * wy * DIRECT_A2D_ELEM(V1, n2, m2);
322 
323  dAij(V2, i, j) = (T) (v1 + v2 + v3 + v4);
324 #ifdef DEBUG_APPYGEO
325  std::cout << " val= " << dAij(V2, i, j) << std::endl;
326 #endif
327 
328  // Compute new point inside input image
329  xp += Aref00;
330  yp += Aref10;
331  }
332  } /* wrap == true */
333  else
334  {
335 
336  // Inner loop boundaries.
337  int globalMin=0, globalMax=XSIZE(V2);
338 
339  // First and last iteration with valid values for x and y coordinates.
340  int minX, maxX, minY, maxY;
341 
342  // Compute valid iterations in x and y coordinates. If one of them is always out
343  // of boundaries then the inner loop is not executed this iteration.
344  if (!getLoopRange( xp, minxpp, maxxpp, Aref00, XSIZE(V2), minX, maxX) ||
345  !getLoopRange( yp, minypp, maxypp, Aref10, XSIZE(V2), minY, maxY))
346  {
347  y++;
348  continue;
349  }
350  else
351  {
352  // Compute initial iteration.
353  globalMin = minX;
354  if (minX < minY)
355  {
356  globalMin = minY;
357  }
358 
359  // Compute last iteration.
360  globalMax = maxX;
361  if (maxX > maxY)
362  {
363  globalMax = maxY;
364  }
365  globalMax++;
366 
367  // Check max iteration is not higher than image.
368  if ((globalMax >= 0) && ((size_t)globalMax > XSIZE(V2)))
369  {
370  globalMax = XSIZE(V2);
371  }
372 
373  xp += globalMin*Aref00;
374  yp += globalMin*Aref10;
375  }
376 
377 
378  #pragma simd reduction (+:xp,yp)
379  for (int j=globalMin; j<globalMax ;j++)
380  {
381 #ifdef DEBUG_APPLYGEO
382 
383  std::cout << "Computing (" << i << "," << j << ")\n";
384  std::cout << " (y, x) =(" << y << "," << x << ")\n"
385  << " before wrapping (y',x')=(" << yp << "," << xp << ") "
386  << std::endl;
387 
388  std::cout << " after wrapping (y',x')=(" << yp << "," << xp << ") "
389  << std::endl;
390  std::cout << " Interp = " << interp << std::endl;
391  // The following line sounds dangerous...
392  //x++;
393 #endif
394 
395  // Linear interpolation
396 
397  // Calculate the integer position in input image, be careful
398  // that it is not the nearest but the one at the top left corner
399  // of the interpolation square. Ie, (0.7,0.7) would give (0,0)
400  // Calculate also weights for point m1+1,n1+1
401  double wx = xp + cen_xp;
402  int m1 = (int) wx;
403  wx = wx - m1;
404  int m2 = m1 + 1;
405  double wy = yp + cen_yp;
406  int n1 = (int) wy;
407  wy = wy - n1;
408  int n2 = n1 + 1;
409 
410 #ifdef DEBUG_APPLYGEO
411  std::cout << " From (" << n1 << "," << m1 << ") and ("
412  << n2 << "," << m2 << ")\n";
413  std::cout << " wx= " << wx << " wy= " << wy << std::endl;
414 #endif
415 
416  // Perform interpolation
417  // if wx == 0 means that the rightest point is useless for this
418  // interpolation, and even it might not be defined if m1=xdim-1
419  // The same can be said for wy.
420  double wx_1 = (1-wx);
421  double wy_1 = (1-wy);
422  double aux2=wy_1* wx_1 ;
423  double tmp = aux2 * DIRECT_A2D_ELEM(V1, n1, m1);
424 
425  if ((wx != 0) && ((m2 < 0) || ((size_t)m2 < V1.xdim)))
426  tmp += (wy_1-aux2) * DIRECT_A2D_ELEM(V1, n1, m2);
427 
428  if ((wy != 0) && ((n2 < 0) || ((size_t)n2 < V1.ydim)))
429  {
430  aux2=wy * wx_1;
431  tmp += aux2 * DIRECT_A2D_ELEM(V1, n2, m1);
432 
433  if ((wx != 0) && ((m2 < 0) || ((size_t)m2 < V1.xdim)))
434  tmp += (wy-aux2) * DIRECT_A2D_ELEM(V1, n2, m2);
435  }
436 
437  dAij(V2, i, j) = (T) tmp;
438 
439 #ifdef DEBUG_APPYGEO
440  std::cout << " val= " << dAij(V2, i, j) << std::endl;
441 #endif
442 
443  // Compute new point inside input image
444  xp += Aref00;
445  yp += Aref10;
446  }
447  } /* wrap == false */
448 
449  y++;
450  }
451 }
#define YSIZE(v)
#define dAij(M, i, j)
static double * y
#define DIRECT_A2D_ELEM(v, i, j)
doublereal * x
#define i
#define MAT_ELEM(m, i, j)
Definition: matrix2d.h:116
double v1
#define XMIPP_EQUAL_ACCURACY
Definition: xmipp_macros.h:119
#define XSIZE(v)
#define j
bool getLoopRange(double value, double min, double max, double delta, int loopLimit, int &minIter, int &maxIter)
#define realWRAP(x, x0, xF)
Definition: xmipp_macros.h:304
#define XMIPP_RANGE_OUTSIDE_FAST(x, min, max)
Definition: xmipp_macros.h:128