Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
RegionMatcher.cpp
1 /* This file is part of the BIAS library (Basic ImageAlgorithmS).
2 
3  Copyright (C) 2003-2009 (see file CONTACT for details)
4  Multimediale Systeme der Informationsverarbeitung
5  Institut fuer Informatik
6  Christian-Albrechts-Universitaet Kiel
7 
8  BIAS is free software; you can redistribute it and/or modify
9  it under the terms of the GNU Lesser General Public License as published by
10  the Free Software Foundation; either version 2.1 of the License, or
11  (at your option) any later version.
12 
13  BIAS is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU Lesser General Public License for more details.
17 
18  You should have received a copy of the GNU Lesser General Public License
19  along with BIAS; if not, write to the Free Software
20  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/
21 #include <Base/Common/W32Compat.hh>
22 #include <math.h>
23 
24 #include "RegionMatcher.hh"
25 
26 using namespace BIAS;
27 using namespace std;
28 
29 #include "LineMatcher.cpp"
30 #include "SimilarityMeasure.cpp"
31 #include <Base/Image/Image.hh>
32 
34  Debug() {
36  _bl1_5.newsize(5, 5);
37  _bl2_5.newsize(5, 5);
38  _gx1_5.newsize(5, 5);
39  _gy1_5.newsize(5, 5);
40  _gx2_5.newsize(5, 5);
41  _gy2_5.newsize(5, 5);
42  _gsx_5.newsize(5, 5);
43  _gsy_5.newsize(5, 5);
44 }
45 
47 }
48 
49 template<class StorageType>
51  const double &x, const double &y, const unsigned hws,
52  Matrix<double>& res) {
53  if (im.GetChannelCount() == 3u)
54  return BilinearRegionColor3(im, x, y, hws, res);
55  else if (im.GetChannelCount() == 1u)
56  return BilinearRegion(im, x, y, hws, res);
57  else
58  BIASERR("unsupported number of channels: "<<im.GetChannelCount());
59  BIASABORT;
60  return false;
61  // const unsigned w=im.GetWidth(), h=im.GetHeight();
62  // const unsigned channel_count=im.GetChannelCount();
63  // if (channel_count!=1u){
64  // BIASASSERT(im.IsInterleaved());
65  // }
66  // const StorageType **ida = im.GetImageDataArray();
67  // const unsigned size = 2*hws+1;
68  // res.newsize(size, size*channel_count);
69  // unsigned x_floor = (unsigned)floor(x);
70  // unsigned y_floor = (unsigned)floor(y);
71  // unsigned x_floor_end = x_floor+hws+1;
72  // unsigned y_floor_end = y_floor+hws+1;
73  // if (x_floor<hws || y_floor<hws || x_floor_end>=w || y_floor_end>=h)
74  // return false;
75  // unsigned rf, rc, cf, cc, r, c, channel;
76  // double ul, ur, ll, lr;
77  // register const double dy = y - (double)y_floor;
78  // register const double dx = x - (double)x_floor;
79  // register const double dxy = dx*dy;
80  // for (rf=y_floor-hws, rc=rf+1, r=0; rf<y_floor_end; rf++, rc++, r++){
81  // for (cf=x_floor-hws, cc=cf+1, c=0; cf<x_floor_end; cf++, cc++, c++){
82  // for (channel=0; channel<channel_count; channel++){
83  // ul = (double)(ida[rf][cf*channel_count+channel]);
84  // ur = (double)(ida[rf][cc*channel_count+channel]);
85  // ll = (double)(ida[rc][cf*channel_count+channel]);
86  // lr = (double)(ida[rc][cc*channel_count+channel]);
87  // res[r][c*channel_count+channel] =
88  // ul + dy*(ll - ul) + dx*(ur - ul) + dxy*(ul + lr - ll - ur);
89  // }
90  // }
91  // }
92 
93  // // check color 3
94  // Matrix<double> res2;
95  // BIASASSERT(BilinearRegionColor3(im, x, y, hws, res2));
96  // for (int my=0; my<size; my++){
97  // for (int mx=0; mx<size*3; mx++){
98  // cout << "["<<my<<"]["<<mx<<"] = "<<res2[my][mx]<<", "<<res[my][mx]<<endl;
99  // BIASASSERT(Equal(res2[my][mx], res[my][mx]));
100  // }
101  // }
102 
103  return true;
104 }
105 
106 template<class StorageType>
108  const double &x, const double &y, const unsigned hws,
109  Matrix<double>& res) {
110  BIASASSERT(im.GetChannelCount()==3u);
111  BIASASSERT(im.IsInterleaved());
112  const int w = im.GetWidth(), h = im.GetHeight();
113  const StorageType **ida = im.GetImageDataArray();
114  const int size = 2 * hws + 1;
115  res.newsize(size, size * 3);
116  const int y_floor_start = (int) floor(y) - hws;
117  const int y_floor_end = y_floor_start + size;
118  const int x_floor_start = ((int) floor(x) - hws) * 3;
119  const int x_floor_end = x_floor_start + 3 * size;
120  if (x_floor_start < 0 || y_floor_start < 0 || x_floor_end + 3 > 3 * w
121  || y_floor_end >= h)
122  return false;
123  register const double dy = y - (double) floor(y);
124  register const double dx = x - (double) floor(x);
125  register const double dxy = dx * dy;
126  register int col_floor, col_ceil, row_floor, row_ceil, dst_row, dst_col;
127  register double ul, ur, ll, lr;
128  for (row_floor = y_floor_start; row_floor < y_floor_end; row_floor++) {
129  row_ceil = row_floor + 1;
130  dst_row = row_floor - y_floor_start;
131  for (col_floor = x_floor_start; col_floor < x_floor_end; col_floor++) {
132  dst_col = col_floor - x_floor_start;
133  col_ceil = col_floor + 3;
134  ul = (double) (ida[row_floor][col_floor]);
135  ur = (double) (ida[row_floor][col_ceil]);
136  ll = (double) (ida[row_ceil][col_floor]);
137  lr = (double) (ida[row_ceil][col_ceil]);
138  res[dst_row][dst_col] = ul + dy * (ll - ul) + dx * (ur - ul) + dxy
139  * (ul + lr - ll - ur);
140  }
141  }
142  return true;
143 }
144 
145 template<class StorageType>
147  const double &x, const double &y, const unsigned hws,
148  Matrix<double>& res) {
149  BIASASSERT(im.GetChannelCount()==1u);
150  const unsigned w = im.GetWidth(), h = im.GetHeight();
151  const StorageType **ida = im.GetImageDataArray();
152  const unsigned size = 2 * hws + 1;
153  res.newsize(size, size);
154  unsigned x_floor = (unsigned) floor(x);
155  unsigned y_floor = (unsigned) floor(y);
156  unsigned x_floor_end = x_floor + hws + 1;
157  unsigned y_floor_end = y_floor + hws + 1;
158  if (x_floor < hws || y_floor < hws || x_floor_end >= w || y_floor_end >= h)
159  return false;
160  unsigned rf, rc, cf, cc, r, c;
161  double ul, ur, ll, lr;
162  register double dy = y - (double) y_floor;
163  register double dx = x - (double) x_floor;
164  register double dxy = dx * dy;
165  for (rf = y_floor - hws, rc = rf + 1, r = 0; rf < y_floor_end; rf++, rc++, r++) {
166  for (cf = x_floor - hws, cc = cf + 1, c = 0; cf < x_floor_end; cf++, cc++, c++) {
167  ul = (double) (ida[rf][cf]);
168  ur = (double) (ida[rf][cc]);
169  ll = (double) (ida[rc][cf]);
170  lr = (double) (ida[rc][cc]);
171  res[r][c] = ul + dy * (ll - ul) + dx * (ur - ul) + dxy * (ul + lr
172  - ll - ur);
173  }
174  }
175  return true;
176 }
177 
178 template<class StorageType>
180  const double &x, const unsigned &y, const unsigned hws,
181  Matrix<double>& res) {
182  const unsigned w = im.GetWidth(), h = im.GetHeight();
183  //const StorageType **ida = im.GetImageDataArray();
184  const unsigned size = 2 * hws + 1;
185  res.newsize(size, size);
186  unsigned x_floor = (unsigned) floor(x);
187  unsigned x_floor_end = x_floor + hws + 1;
188  const unsigned maxy = y + hws;
189  if (x_floor < hws || y < hws || x_floor_end >= w || maxy >= h)
190  return false;
191  // const unsigned w=im.GetWidth(), h=im.GetHeight();
192  // const unsigned channel_count=im.GetChannelCount();
193  // if (channel_count!=1u){
194  // BIASASSERT(im.IsInterleaved());
195  // }
196  // const StorageType **ida = im.GetImageDataArray();
197  // const unsigned size = 2*hws+1;
198  // res.newsize(size, size*channel_count);
199  // unsigned x_floor = (unsigned)floor(x);
200  // unsigned y_floor = (unsigned)floor(y);
201  // unsigned x_floor_end = x_floor+hws+1;
202  // unsigned y_floor_end = y_floor+hws+1;
203  // if (x_floor<hws || y_floor<hws || x_floor_end>=w || y_floor_end>=h)
204  // return false;
205  // unsigned rf, rc, cf, cc, r, c, channel;
206  // double ul, ur, ll, lr;
207  // register const double dy = y - (double)y_floor;
208  // register const double dx = x - (double)x_floor;
209  // register const double dxy = dx*dy;
210  // for (rf=y_floor-hws, rc=rf+1, r=0; rf<y_floor_end; rf++, rc++, r++){
211  // for (cf=x_floor-hws, cc=cf+1, c=0; cf<x_floor_end; cf++, cc++, c++){
212  // for (channel=0; channel<channel_count; channel++){
213  // ul = (double)(ida[rf][cf*channel_count+channel]);
214  // ur = (double)(ida[rf][cc*channel_count+channel]);
215  // ll = (double)(ida[rc][cf*channel_count+channel]);
216  // lr = (double)(ida[rc][cc*channel_count+channel]);
217  // res[r][c*channel_count+channel] =
218  // ul + dy*(ll - ul) + dx*(ur - ul) + dxy*(ul + lr - ll - ur);
219  // }
220  // }
221  // }
222 
223  // // check color 3
224  // Matrix<double> res2;
225  // BIASASSERT(BilinearRegionColor3(im, x, y, hws, res2));
226  // for (int my=0; my<size; my++){
227  // for (int mx=0; mx<size*3; mx++){
228  // cout << "["<<my<<"]["<<mx<<"] = "<<res2[my][mx]<<", "<<res[my][mx]<<endl;
229  // BIASASSERT(Equal(res2[my][mx], res[my][mx]));
230  // }
231  // }
232 
233  return true;
234 }
235 
236 template<class StorageType>
237 int RegionMatcher::NCCSearchOdd(const unsigned int p1[2],
238  const unsigned int p2[2], const StorageType **ida1,
239  const StorageType **ida2, const unsigned int halfnccwinsize,
240  const unsigned int halfsearchwinsize, unsigned int resultpoint[2],
241  const double mincorrelation, double& result) const {
242  int res = 0; // return value
243  unsigned int p3[2], p4[2];
244  double tmpresult, maxresult;
245 
246  BIASDOUT(D_REGION_MATCHER_SEARCH_ODD, "\np1: "<<p1[0]<<" "<<p1[1]
247  <<"\tp2: "<<p2[0]<<" "<<p2[1]<<"\tida1: "<<&ida1[0]
248  <<" ida2: "<<&ida2[0]<<" halfnccwinsize: "<<halfnccwinsize);
249  // initialize maxresult and point
250  resultpoint[0] = p2[0];
251  resultpoint[1] = p2[1];
252  NCC(p1, p2, ida1, ida2, halfnccwinsize, maxresult);
253  BIASDOUT(D_REGION_MATCHER_SEARCH_ODD,"("<<p2[0]<<", "<<p2[1]<<") : "
254  <<maxresult);
255  if (maxresult > mincorrelation) {
256  result = maxresult;
257  BIASDOUT(D_REGION_MATCHER_SEARCHNCC, "first correlation succeeded "
258  <<result);
259  } else {
260  BIASDOUT(D_REGION_MATCHER_SEARCHNCC, "first correlation "<<maxresult);
261  for (register unsigned int sr = 1; sr <= halfsearchwinsize; sr++) {
262  BIASDOUT(D_REGION_MATCHER_SEARCHNCC, "search radius " << sr);
263  p3[1] = p2[1] - sr;
264  p4[1] = p2[1] + sr;
265  for (p3[0] = p2[0] - sr, p4[0] = p2[0] - sr; p3[0] <= p2[0] + sr; p3[0]++, p4[0]++) {
266  NCC(p1, p3, ida1, ida2, halfnccwinsize, tmpresult);
267  BIASDOUT(D_REGION_MATCHER_SEARCH_ODD,"("<<p3[0]<<", "<<p3[1]<<") : "
268  <<tmpresult);
269  if (tmpresult > maxresult) {
270  maxresult = tmpresult;
271  resultpoint[0] = p3[0];
272  resultpoint[1] = p3[1];
273  }
274  if (maxresult > mincorrelation)
275  break;
276 
277  NCC(p1, p4, ida1, ida2, halfnccwinsize, tmpresult);
278  BIASDOUT(D_REGION_MATCHER_SEARCH_ODD,"("<<p4[0]<<", "<<p4[1]<<") : "
279  <<tmpresult);
280  if (tmpresult > maxresult) {
281  maxresult = tmpresult;
282  resultpoint[0] = p4[0];
283  resultpoint[1] = p4[1];
284  }
285  if (maxresult > mincorrelation)
286  break;
287  }
288  if (maxresult < result) {
289  p3[0] = p2[0] - sr;
290  p4[0] = p2[0] + sr;
291  for (p3[1] = p2[1] - sr - 1, p4[1] = p2[1] - sr - 1; p3[1]
292  <= p2[1] + sr - 1; p3[1]++, p4[1]++) {
293  NCC(p1, p3, ida1, ida2, halfnccwinsize, tmpresult);
294  BIASDOUT(D_REGION_MATCHER_SEARCH_ODD,"("<<p3[0]<<", "<<p3[1]<<") : "
295  <<tmpresult);
296  if (tmpresult > maxresult) {
297  maxresult = tmpresult;
298  resultpoint[0] = p3[0];
299  resultpoint[1] = p3[1];
300  }
301  if (maxresult > mincorrelation)
302  break;
303 
304  NCC(p1, p4, ida1, ida2, halfnccwinsize, tmpresult);
305  BIASDOUT(D_REGION_MATCHER_SEARCH_ODD,"("<<p4[0]<<", "<<p4[1]<<") : "
306  <<tmpresult);
307  if (tmpresult > maxresult) {
308  maxresult = tmpresult;
309  resultpoint[0] = p4[0];
310  resultpoint[1] = p4[1];
311  }
312  if (maxresult > mincorrelation)
313  break;
314  }
315  }
316  if (maxresult > mincorrelation) {
317  result = maxresult;
318  BIASDOUT(D_REGION_MATCHER_SEARCHNCC, "succeeded at searchradius "<<sr
319  <<" with "<<result<<" correlation point: "<<resultpoint);
320  break;
321  }
322  } // for (sr=1; sr<=halfsearchwinsize; sr++)
323  result = maxresult;
324  if (mincorrelation < 1.0 && result < mincorrelation) {
325  BIASDOUT(D_REGION_MATCHER_SEARCHNCC, "no success within "<<p2[0] <<" "
326  << p2[1]
327  <<" +/- "<<halfsearchwinsize<<" max correlation "<<result
328  <<" at "<<resultpoint<< " still lower than "<<mincorrelation);
329  res = -3;
330  } else if (mincorrelation >= 1.0) {
331  BIASDOUT(D_REGION_MATCHER_SEARCHNCC, "searched within "<<p2[0]<<" "
332  <<p2[1]
333  <<" +/- "<<halfsearchwinsize<<" found max correlation "<<result
334  <<" at "<<resultpoint[0]<<", "<<resultpoint[1]);
335  }
336  } // if (maxresult > result)
337 
338  return res;
339 }
340 
341 template<class StorageType>
342 int RegionMatcher::NCCSearchEven(const unsigned int p1[2],
343  const unsigned int p2[2], const StorageType **ida1,
344  const StorageType **ida2, const unsigned int halfnccwinsize,
345  const unsigned int halfsearchwinsize, unsigned int resultpoint[2],
346  const double mincorrelation, double& result) const {
347  int res = 0; // return value
348  unsigned int p3[2], p4[2];
349  double tmpresult, maxresult = -1.0;
350 
351  /*
352  // initialize maxresult and point
353  resultpoint[0]=p2[0];
354  resultpoint[1]=p2[1];
355  NCC(p1, p2, ida1, ida2, halfnccwinsize, maxresult);
356  BIASDOUT(D_REGION_MATCHER_SEARCH_EVEN,"("<<p2[0]<<", "<<p2[1]<<") : "
357  <<maxresult);
358  if (maxresult > mincorrelation){
359  result = maxresult;
360  BIASDOUT(D_REGION_MATCHER_SEARCHNCC,"first correlation succeeded "
361  <<result);
362  } else {
363  BIASDOUT(D_REGION_MATCHER_SEARCHNCC, "first correlation = "<<maxresult
364  <<" at "<<p2[0]<<" "<<p2[1]);
365  */
366  BIASDOUT(D_REGION_MATCHER_SEARCHNCC, "\np1: "<<p1[0]<<" "<<p1[1]
367  <<"\tp2: "<<p2[0]<<" "<<p2[1]<<"\tida1: "<<&ida1[0]
368  <<" ida2: "<<&ida2[0]<<" halfnccwinsize: "<<halfnccwinsize);
369  for (register unsigned int sr = 1; sr <= halfsearchwinsize; sr++) {
370  BIASDOUT(D_REGION_MATCHER_SEARCHNCC, "search radius " << sr);
371  // top and bottom side of quadrate
372  p3[1] = p2[1] - sr + 1;
373  p4[1] = p2[1] + sr;
374  for (p3[0] = p2[0] - sr + 1, p4[0] = p2[0] - sr + 1; p3[0] <= p2[0]
375  + sr; p3[0]++, p4[0]++) {
376  NCC(p1, p3, ida1, ida2, halfnccwinsize, tmpresult);
377  BIASDOUT(D_REGION_MATCHER_SEARCH_EVEN,"("<<p3[0]<<", "<<p3[1]<<") : "
378  <<tmpresult);
379  if (tmpresult > maxresult) {
380  maxresult = tmpresult;
381  resultpoint[0] = p3[0];
382  resultpoint[1] = p3[1];
383  }
384  if (maxresult > mincorrelation)
385  break;
386 
387  NCC(p1, p4, ida1, ida2, halfnccwinsize, tmpresult);
388  BIASDOUT(D_REGION_MATCHER_SEARCH_EVEN,"("<<p4[0]<<", "<<p4[1]<<") : "
389  <<tmpresult);
390  if (tmpresult > maxresult) {
391  maxresult = tmpresult;
392  resultpoint[0] = p4[0];
393  resultpoint[1] = p4[1];
394  }
395  if (maxresult > mincorrelation)
396  break;
397  }
398  if (maxresult < mincorrelation) {
399  p3[0] = p2[0] - sr + 1;
400  p4[0] = p2[0] + sr;
401  for (p3[1] = p2[1] - sr + 2, p4[1] = p2[1] - sr + 2; p3[1] <= p2[1]
402  + sr - 1; p3[1]++, p4[1]++) {
403  NCC(p1, p3, ida1, ida2, halfnccwinsize, tmpresult);
404  BIASDOUT(D_REGION_MATCHER_SEARCH_EVEN,"("<<p3[0]<<", "<<p3[1]<<") : "
405  <<tmpresult);
406  if (tmpresult > maxresult) {
407  maxresult = tmpresult;
408  resultpoint[0] = p3[0];
409  resultpoint[1] = p3[1];
410  }
411  if (maxresult > mincorrelation)
412  break;
413 
414  NCC(p1, p4, ida1, ida2, halfnccwinsize, tmpresult);
415  BIASDOUT(D_REGION_MATCHER_SEARCH_EVEN,"("<<p4[0]<<", "<<p4[1]<<") : "
416  <<tmpresult);
417  if (tmpresult > maxresult) {
418  maxresult = tmpresult;
419  resultpoint[0] = p4[0];
420  resultpoint[1] = p4[1];
421  }
422  if (maxresult > mincorrelation)
423  break;
424  }
425  }
426  if (maxresult > mincorrelation) {
427  result = maxresult;
428  BIASDOUT(D_REGION_MATCHER_SEARCHNCC, "succeeded at searchradius "<<sr
429  <<" with "<<result<<" correlation point: "<<resultpoint);
430  break;
431  }
432  } // for (sr=1; sr<=halfsearchwinsize; sr++)
433  result = maxresult;
434  if (mincorrelation < 1.0 && result < mincorrelation) {
435  BIASDOUT(D_REGION_MATCHER_SEARCHNCC,"no success within "<<p2[0]<<" "
436  <<p2[1]
437  <<" +/- "<<halfsearchwinsize<<" max correlation "<<result
438  <<" at "<<resultpoint<< " still lower than "<<mincorrelation);
439  res = -3;
440  } else if (mincorrelation >= 1.0) {
441  BIASDOUT(D_REGION_MATCHER_SEARCHNCC,"searched within "<<p2[0]<<" "<<p2[1]
442  <<" +/- "<<halfsearchwinsize<<" found max correlation "<<result
443  <<" at "<<resultpoint[0]<<", "<<resultpoint[1]);
444  }
445  // } // if (maxresult > result)
446 
447  return res;
448 }
449 
450 template<class StorageType>
451 KLT_TYPE RegionMatcher::_Bilinear(const StorageType **ida, const KLT_TYPE x,
452  const KLT_TYPE y) const {
453  unsigned int x_floor = (unsigned int) floor(x);
454  unsigned int y_floor = (unsigned int) floor(y);
455  unsigned int x_ceil = (unsigned int) ceil(x);
456  unsigned int y_ceil = (unsigned int) ceil(y);
457  StorageType ul = ida[y_floor][x_floor];
458  StorageType ur = ida[y_floor][x_ceil];
459  StorageType ll = ida[y_ceil][x_floor];
460  StorageType lr = ida[y_ceil][x_ceil];
461  KLT_TYPE dy = y - y_floor;
462  KLT_TYPE dx = x - x_floor;
463 
464  return ul + dy * (ll - ul) + dx * (ur - ul) + dy * dx * (ul + lr - ll - ur);
465 }
466 
467 KLT_TYPE RegionMatcher::_Bilinear(const unsigned char**ida, const KLT_TYPE x,
468  const KLT_TYPE y) const {
469  // unsigned int x_floor=(unsigned int)floor(x);
470  // unsigned int y_floor=(unsigned int)floor(y);
471  // unsigned int x_ceil=(unsigned int)ceil(x);
472  // unsigned int y_ceil=(unsigned int)ceil(y);
473  // int ul = (int)(ida[y_floor][x_floor]);
474  // int ur = (int)(ida[y_floor][x_ceil]);
475  // int ll = (int)(ida[y_ceil][x_floor]);
476  // int lr = (int)(ida[y_ceil][x_ceil]);
477  // KLT_TYPE dy = y - y_floor;
478  // KLT_TYPE dx = x - x_floor;
479 
480  // return ul + dy*(ll - ul) + dx*(ur - ul) + dy*dx*(ul + lr - ll - ur );
481  register unsigned int x_floor = (unsigned int) floor(x);
482  register unsigned int y_floor = (unsigned int) floor(y);
483  register unsigned int x_ceil = x_floor + 1;
484  register unsigned int y_ceil = y_floor + 1;
485  register unsigned int ul = (unsigned int) ida[y_floor][x_floor];
486  register unsigned int ur = (unsigned int) ida[y_floor][x_ceil];
487  register unsigned int ll = (unsigned int) ida[y_ceil][x_floor];
488  register unsigned int lr = (unsigned int) ida[y_ceil][x_ceil];
489  register unsigned int dy = (unsigned int) rint((y - y_floor) * 256);
490  register unsigned int dx = (unsigned int) rint((x - x_floor) * 256);
491 
492  return (unsigned char) (((ul << 16) + (dy << 8) * (ll - ul) + (dx << 8)
493  * (ur - ul) + dy * dx * (ul - ll - ur + lr)) >> 16);
494 }
495 
496 template<class StorageType>
497 void RegionMatcher::_BilinearRegion(const StorageType **ida, const KLT_TYPE x,
498  const KLT_TYPE y, const unsigned hws, Matrix<KLT_TYPE>& res) const {
499  unsigned x_floor = (unsigned int) floor(x);
500  unsigned y_floor = (unsigned int) floor(y);
501  unsigned x_floor_end = x_floor + hws + 1;
502  unsigned y_floor_end = y_floor + hws + 1;
503  unsigned rf, rc, cf, cc, r, c;
504  StorageType ul, ur, ll, lr;
505  register KLT_TYPE dy = (KLT_TYPE) (y - y_floor);
506  register KLT_TYPE dx = (KLT_TYPE) (x - x_floor);
507  register KLT_TYPE dxy = dx * dy;
508  for (rf = y_floor - hws, rc = rf + 1, r = 0; rf < y_floor_end; rf++, rc++, r++) {
509  for (cf = x_floor - hws, cc = cf + 1, c = 0; cf < x_floor_end; cf++, cc++, c++) {
510  ul = ida[rf][cf];
511  ur = ida[rf][cc];
512  ll = ida[rc][cf];
513  lr = ida[rc][cc];
514  res[r][c] = (KLT_TYPE) (ul + dy * (ll - ul) + dx * (ur - ul) + dxy
515  * (ul + lr - ll - ur));
516  }
517  }
518 }
519 
520 void RegionMatcher::_BilinearRegion(const unsigned char **ida,
521  const KLT_TYPE x, const KLT_TYPE y, const unsigned hws,
522  Matrix<KLT_TYPE>& res) const {
523  unsigned int x_floor = (unsigned int) floor(x);
524  unsigned int y_floor = (unsigned int) floor(y);
525  unsigned int x_floor_end = x_floor + hws + 1;
526  unsigned int y_floor_end = y_floor + hws + 1;
527  unsigned rf, rc, cf, cc, r, c;
528  unsigned ul, ur, ll, lr;
529  register unsigned int dy = (unsigned int) rint((y - y_floor) * 256);
530  register unsigned int dx = (unsigned int) rint((x - x_floor) * 256);
531  register unsigned int dxy = dx * dy;
532  for (rf = y_floor - hws, rc = rf + 1, r = 0; rf < y_floor_end; rf++, rc++, r++) {
533  for (cf = x_floor - hws, cc = cf + 1, c = 0; cf < x_floor_end; cf++, cc++, c++) {
534  ul = (unsigned) ida[rf][cf];
535  ur = (unsigned) ida[rf][cc];
536  ll = (unsigned) ida[rc][cf];
537  lr = (unsigned) ida[rc][cc];
538  res[r][c] = (unsigned char) (((ul << 16) + (dy << 8) * (ll - ul)
539  + (dx << 8) * (ur - ul) + dxy * (ul - ll - ur + lr)) >> 16);
540  }
541  }
542  //BIASERR("unfinished and untested");
543 }
544 
545 /*
546  template <class StorageType>
547  KLT_TYPE RegionMatcher::_BilinearGrad(StorageType **ida, KLT_TYPE x, KLT_TYPE y)
548  {
549  unsigned int x_floor=(unsigned int)floor(x);
550  unsigned int y_floor=(unsigned int)floor(y);
551  unsigned int x_ceil=(unsigned int)ceil(x);
552  unsigned int y_ceil=(unsigned int)ceil(y);
553  KLT_TYPE ul = (KLT_TYPE)(ida[y_floor][x_floor])-SOBEL_GRAD_UC_ZERO;
554  KLT_TYPE ur = (KLT_TYPE)(ida[y_floor][x_ceil])-SOBEL_GRAD_UC_ZERO;
555  KLT_TYPE ll = (KLT_TYPE)(ida[y_ceil][x_floor])-SOBEL_GRAD_UC_ZERO;
556  KLT_TYPE lr = (KLT_TYPE)(ida[y_ceil][x_ceil])-SOBEL_GRAD_UC_ZERO;
557  KLT_TYPE dy = y - y_floor;
558  KLT_TYPE dx = x - x_floor;
559 
560  return ul + dy*(ll - ul) + dx*(ur - ul) + dy*dx*(ul + lr - ll - ur );
561  }
562 
563  // also moves gradient in [-127, 127] befor interpolating
564 
565  template <>
566  KLT_TYPE RegionMatcher::_BilinearGrad<unsigned char>(unsigned char **ida, KLT_TYPE x, KLT_TYPE y)
567  {
568  unsigned int x_floor=(unsigned int)floor(x);
569  unsigned int y_floor=(unsigned int)floor(y);
570  unsigned int x_ceil=(unsigned int)ceil(x);
571  unsigned int y_ceil=(unsigned int)ceil(y);
572  int ul = (int)(ida[y_floor][x_floor])-SOBEL_GRAD_UC_ZERO;
573  int ur = (int)(ida[y_floor][x_ceil])-SOBEL_GRAD_UC_ZERO;
574  int ll = (int)(ida[y_ceil][x_floor])-SOBEL_GRAD_UC_ZERO;
575  int lr = (int)(ida[y_ceil][x_ceil])-SOBEL_GRAD_UC_ZERO;
576  KLT_TYPE dy = y - y_floor;
577  KLT_TYPE dx = x - x_floor;
578 
579  return ul + dy*(ll - ul) + dx*(ur - ul) + dy*dx*(ul + lr - ll - ur );
580  }
581 
582  template <class StorageType>
583  void RegionMatcher::_BilinearRegionGrad(StorageType **ida, KLT_TYPE x,
584  KLT_TYPE y, unsigned hws,
585  Matrix<KLT_TYPE>& res)
586  {
587  unsigned x_floor = (unsigned int)floor(x);
588  unsigned y_floor = (unsigned int)floor(y);
589  unsigned x_floor_end = x_floor+hws+1;
590  unsigned y_floor_end = y_floor+hws+1;
591  unsigned rf, rc, cf, cc, r, c;
592  KLT_TYPE ul, ur, ll, lr;
593  register KLT_TYPE dy = (KLT_TYPE)(y - y_floor);
594  register KLT_TYPE dx = (KLT_TYPE)(x - x_floor);
595  register KLT_TYPE dxy = dx*dy;
596  for (rf=y_floor-hws, rc=rf+1, r=0; rf<y_floor_end; rf++, rc++, r++){
597  for (cf=x_floor-hws, cc=cf+1, c=0; cf<x_floor_end; cf++, cc++, c++){
598  ul = (KLT_TYPE)ida[rf][cf]-(KLT_TYPE)SOBEL_GRAD_UC_ZERO;
599  ur = (KLT_TYPE)ida[rf][cc]-(KLT_TYPE)SOBEL_GRAD_UC_ZERO;
600  ll = (KLT_TYPE)ida[rc][cf]-(KLT_TYPE)SOBEL_GRAD_UC_ZERO;
601  lr = (KLT_TYPE)ida[rc][cc]-(KLT_TYPE)SOBEL_GRAD_UC_ZERO;
602  res[r][c]=(ul + dy*(ll - ul) + dx*(ur - ul) + dxy*(ul + lr - ll - ur));
603  }
604  }
605 
606  }
607  */
608 
609 template<class StorageType>
610 int RegionMatcher::ParabolaNCC(const unsigned int p1[2],
611  const unsigned int p2[2], const StorageType **ida1,
612  const StorageType **ida2, const unsigned int halfwinsize,
613  KLT_TYPE result[2]) const {
614  int res = 0;
615 
616  double x1, x2, x3, y1, y2, y3;
617  unsigned int p2tmp[2];
618  BIASDOUT(D_REGION_MATCHER_PARABOLA, "p1 ("<<p1[0]<<", "<<p1[1]<<")\tp2 ("
619  <<p2[0]<<", "<<p2[1]<<")\tida1: "<<&ida1[0]<<" ida2: "<<&ida2[0]
620  <<" halfwinsize: "<<halfwinsize);
621  NCC(p1, p2, ida1, ida2, halfwinsize, x2);
622  //cerr <<"x2: "<<x2<<endl;
623  y2 = x2;
624  p2tmp[0] = p2[0];
625  p2tmp[1] = p2[1] - 1;
626  NCC(p1, p2tmp, ida1, ida2, halfwinsize, y1);
627  p2tmp[1] = p2[1] + 1;
628  NCC(p1, p2tmp, ida1, ida2, halfwinsize, y3);
629  p2tmp[0] = p2[0] - 1;
630  p2tmp[1] = p2[1];
631  NCC(p1, p2tmp, ida1, ida2, halfwinsize, x1);
632  p2tmp[0] = p2[0] + 1;
633  NCC(p1, p2tmp, ida1, ida2, halfwinsize, x3);
634 
635  if (x3 >= x2 || x1 >= x2) {
636  BIASERR("invalid correlation data "<<x1<<" "<<x2
637  <<" "<<x3<<"\n\tcorrelation between ("
638  <<p1[0]<<", "<<p1[1]<<") and ("<<p2[0]
639  <<", "<<p2[1]<<") is not a local maximum");
640  return -1;
641  }
642  if (y3 >= y2 || y1 >= y2) {
643  BIASERR("invalid correlation data "<<y1<<" "<<y2
644  <<" "<<y3<<"\n\tcorrelation between ("
645  <<p1[0]<<", "<<p1[1]<<") and ("<<p2[0]
646  <<", "<<p2[1]<<") is not a local maximum");
647  return -1;
648  }
649 
650  result[0] = p2[0] + _ParabolaApprox(x1, x2, x3);
651  result[1] = p2[1] + _ParabolaApprox(y1, y2, y3);
652  BIASDOUT(D_REGION_MATCHER_PARABOLA, "\n(x1 x2 x3) : res\t("<<x1<<" "<<x2<<" "
653  <<x3<<") : "<<result[0]-p2[0]<<"\n(y1 y2 y3) : res\t("
654  <<y1<<" "<<y2<<" "<<y3<<") : "<<result[1]-p2[1]);
655  return res;
656 }
657 
658 template<class StorageType>
659 int RegionMatcher::ParabolaNCC5(const unsigned int p1[2],
660  const unsigned int p2[2], const StorageType **ida1,
661  const StorageType **ida2, const unsigned int halfwinsize,
662  KLT_TYPE result[2]) const {
663  int res = 0;
664 
665  double x1, x2, x3, x4, x5, y1, y2, y3, y4, y5;
666  unsigned int p2tmp[2];
667  BIASDOUT(D_REGION_MATCHER_PARABOLA, "p1 ("<<p1[0]<<", "<<p1[1]<<")\tp2 ("
668  <<p2[0]<<", "<<p2[1]<<")\tida1: "<<&ida1[0]<<" ida2: "<<&ida2[0]
669  <<" halfwinsize: "<<halfwinsize);
670  NCC(p1, p2, ida1, ida2, halfwinsize, x3);
671  //cerr <<"x2: "<<x2<<endl;
672  y3 = x3;
673  p2tmp[0] = p2[0];
674  p2tmp[1] = p2[1] - 1;
675  NCC(p1, p2tmp, ida1, ida2, halfwinsize, y2);
676  p2tmp[1] = p2[1] - 2;
677  NCC(p1, p2tmp, ida1, ida2, halfwinsize, y1);
678  p2tmp[1] = p2[1] + 1;
679  NCC(p1, p2tmp, ida1, ida2, halfwinsize, y4);
680  p2tmp[1] = p2[1] + 2;
681  NCC(p1, p2tmp, ida1, ida2, halfwinsize, y5);
682  p2tmp[0] = p2[0] - 1;
683  p2tmp[1] = p2[1];
684  NCC(p1, p2tmp, ida1, ida2, halfwinsize, x2);
685  p2tmp[0] = p2[0] - 2;
686  NCC(p1, p2tmp, ida1, ida2, halfwinsize, x1);
687  p2tmp[0] = p2[0] + 1;
688  NCC(p1, p2tmp, ida1, ida2, halfwinsize, x4);
689  p2tmp[0] = p2[0] + 2;
690  NCC(p1, p2tmp, ida1, ida2, halfwinsize, x5);
691 
692  if (x1 >= x3 || x2 >= x3 || x4 >= x3 || x5 >= x3) {
693  BIASERR("invalid correlation data "<<x1<<" "<<x2
694  <<" "<<x3<<" "<<x4<<" "<<x5<<"\n\tcorrelation between ("
695  <<p1[0]<<", "<<p1[1]<<") and ("<<p2[0]
696  <<", "<<p2[1]<<") is not a local maximum");
697  return -1;
698  }
699  if (y1 >= y3 || y2 >= y3 || y4 >= y3 || y5 >= y3) {
700  BIASERR("invalid correlation data "<<y1<<" "<<y2
701  <<" "<<y3<<" "<<y4<<" "<<y5<<"\n\tcorrelation between ("
702  <<p1[0]<<", "<<p1[1]<<") and ("<<p2[0]
703  <<", "<<p2[1]<<") is not a local maximum");
704  return -1;
705  }
706 
707  result[0] = p2[0] + _ParabolaApprox(x1, x2, x3, x4, x5);
708  result[1] = p2[1] + _ParabolaApprox(y1, y2, y3, y4, y5);
709  BIASDOUT(D_REGION_MATCHER_PARABOLA,
710  "\n(x1 x2 x3 x4 x5) : res\t("<<x1<<" "<<x2<<" "<<x3<<" "<<x4
711  <<" "<<x5<<") : "<<result[0]-p2[0]<<"\n(y1 y2 y3 y4 y5) : res\t("
712  <<y1<<" "<<y2<<" "<<y3<<" "<<y4<<" "<<y5<<") : "<<result[1]-p2[1]);
713  return res;
714 }
715 
716 template<class StorageType>
717 float RegionMatcher::AD(const unsigned int x1, const unsigned int y1, Image<
718  StorageType>& img1, const unsigned int x2, const unsigned int y2,
719  Image<StorageType>& img2) {
720  float res = 0;
721 
722  for (unsigned int ch = 0; ch < img1.GetChannelCount(); ch++) {
723  res += fabs((float) img1.PixelValue(x1, y1,
724  static_cast<unsigned short int> (ch))
725  - (float) img2.PixelValue(x2, y2,
726  static_cast<unsigned short int> (ch)));
727  }
728 
729  return res;
730 }
731 
732 ///////////////////////////////////////////////////////////////////////////
733 // instantiation
734 ///////////////////////////////////////////////////////////////////////////
735 
736 
737 #define INSTUC(uctype)\
738 template BIASMatcher2D_EXPORT void RegionMatcher::NCC<uctype>(const double p1[2],\
739  const double p2[2], const uctype **ida1, const uctype **ida2, const unsigned halfwinsize,\
740  double& result);\
741 template BIASMatcher2D_EXPORT void RegionMatcher::NCC<uctype>(\
742  const unsigned int p1[2], const unsigned int p2[2], const uctype **ida1, const uctype **roi1,\
743  const uctype **ida2, const uctype **roi2, const unsigned hww, const unsigned hwh, double& result)const ;\
744 template BIASMatcher2D_EXPORT int RegionMatcher::NCCSearchOdd<uctype>(\
745  const unsigned int p1[2], const unsigned int p2[2], const uctype **ida1, const uctype **ida2,\
746  const unsigned int halfnccwinsize, const unsigned int halfsearchwinsize,\
747  unsigned int resultpoint[2], const double mincorrelation, double& result)const ;\
748 template BIASMatcher2D_EXPORT int RegionMatcher::NCCSearchEven<uctype>(\
749  const unsigned int p1[2], const unsigned int p2[2],const uctype **ida1, const uctype **ida2,\
750  const unsigned int halfnccwinsize, const unsigned int halfsearchwinsize,\
751  unsigned int resultpoint[2], const double mincorrelation, double& result)const ;\
752 template BIASMatcher2D_EXPORT int RegionMatcher::LineMatcherNCC<uctype>(\
753  const unsigned int p1[2], const unsigned int start2[2], const unsigned int end2[2],\
754  const uctype **ida1, const uctype **ida2, const uctype **grad1, const uctype **grad2,\
755  const unsigned int halfwinsize, const unsigned int epsilon, const double gradientscale,\
756  unsigned int result[2], double& correlation)const ;\
757 template BIASMatcher2D_EXPORT int RegionMatcher::LineMatcherSAD<uctype>(\
758  const unsigned int p1[2], const unsigned int start2[2], const unsigned int end2[2],\
759  const uctype **ida1, const uctype **ida2, const uctype **grad1, const uctype **grad2,\
760  const unsigned int halfwinsize, const unsigned int epsilon, const double gradientscale,\
761  unsigned int result[2], double& sad)const ;\
762 template BIASMatcher2D_EXPORT int RegionMatcher::LineMatcherSSD<uctype>(\
763  const unsigned int p1[2], const unsigned int start2[2], const unsigned int end2[2],\
764  const uctype **ida1, const uctype **ida2, const uctype **grad1, const uctype **grad2,\
765  const unsigned int halfwinsize, const unsigned int epsilon, const double gradientscale,\
766  unsigned int result[2], double& ssd)const ;\
767 template BIASMatcher2D_EXPORT int RegionMatcher::ParabolaNCC(\
768  const unsigned int p1[2], const unsigned int p2[2], const uctype **ida1, const uctype **ida2,\
769  const unsigned int halfwinsize, KLT_TYPE result[2])const ;\
770 template BIASMatcher2D_EXPORT int RegionMatcher::ParabolaNCC5(\
771  const unsigned int p1[2], const unsigned int p2[2], const uctype **ida1, const uctype **ida2,\
772  const unsigned int halfwinsize, KLT_TYPE result[2])const ;\
773 template BIASMatcher2D_EXPORT void RegionMatcher::ColorNCC<uctype>(\
774  const unsigned int p1[2], const unsigned int p2[2], const uctype **ida1, const uctype **ida2,\
775  const unsigned int halfwinsize, double& result)const ;\
776 template BIASMatcher2D_EXPORT void RegionMatcher::CNCC<uctype>(\
777  const unsigned int p1[2], const unsigned int p2[2], const uctype **ida1, const uctype **ida2,\
778  const unsigned int halfwinsize, double& result) const;
779 /*
780  template BIASMatcher2D_EXPORT void RegionMatcher::HammingDistance<uctype>(\
781  const unsigned int p1[2], const unsigned int p2[2], const uctype **ida1, const uctype **ida2,\
782  const unsigned int halfwinsize, const unsigned int censussize, double& result) const;*/
783 
784 #define INST(itype)\
785 template BIASMatcher2D_EXPORT void RegionMatcher::SSD<itype>(const unsigned int p1[2]\
786  , const unsigned int p2[2], const itype **ida1, const itype **ida2, const unsigned int halfwinsize,\
787  double& result) const;\
788 template BIASMatcher2D_EXPORT void RegionMatcher::NCC<itype>(const unsigned int p1[2]\
789  , const unsigned int p2[2], const itype **ida1, const itype **ida2, const unsigned int halfwinsize,\
790  double& result) const;\
791  template BIASMatcher2D_EXPORT void RegionMatcher::SAD<itype>(const unsigned int p1[2]\
792  , const unsigned int p2[2], const itype **ida1, const itype **ida2, const unsigned int halfwinsize,\
793  double& result) const;\
794 template BIASMatcher2D_EXPORT void RegionMatcher::SAD<itype>(const unsigned int p1[2]\
795  , const unsigned int p2[2], const itype **ida1, const itype **ida2, const unsigned int halfwinsize, const unsigned channel_count, double& result) const; \
796 template BIASMatcher2D_EXPORT void RegionMatcher::SADN<itype>(\
797  const unsigned int p1[2], const unsigned int p2[2], const itype **ida1, const itype **ida2,\
798  const unsigned int halfwinsize, double& result) const;
799 
800 #define INST_IM(itype)\
801 template BIASMatcher2D_EXPORT bool RegionMatcher::BilinearRegion<itype>(\
802  const Image<itype>& im, const double &x, const double &y, \
803  const unsigned hws, Matrix<double>& res); \
804 template BIASMatcher2D_EXPORT bool RegionMatcher::BilinearRegionColor<itype>(\
805  const Image<itype>& im, const double &x, const double &y, \
806  const unsigned hws, Matrix<double>& res); \
807 template BIASMatcher2D_EXPORT bool RegionMatcher::BilinearRegionColor3<itype>(\
808  const Image<itype>& im, const double &x, const double &y, \
809  const unsigned hws, Matrix<double>& res); \
810 template BIASMatcher2D_EXPORT bool RegionMatcher::LinearRegionX<itype>(\
811  const Image<itype>& im, const double &x, const unsigned &y, \
812  const unsigned hws, Matrix<double>& res);\
813 template BIASMatcher2D_EXPORT float RegionMatcher::AD<itype>(const unsigned int x1, const unsigned int y1,\
814  Image<itype>& img1, const unsigned int x2, const unsigned int y2, Image<itype>& img2);
815 
816 // You can't instantiate unsigned char if the
817 // instantiantion is already given in a specialised implemented function
818 //INST(unsigned char)
819 INSTUC(unsigned char)
820 INSTUC(float)
821 INSTUC(int)
822 INSTUC(char)
823 INSTUC(short)
824 INSTUC(unsigned short)
825 INSTUC(unsigned int)
826 INSTUC(double)
827 INST(float)
828 INST(int)
829 INST(char)
830 INST(short)
831 INST(unsigned short)
832 INST(unsigned int)
833 INST(double)
834 
835 INST_IM(unsigned char)
836 INST_IM(float)
837 // fill in instances as required
838 #ifdef BUILD_IMAGE_INT
839 INST_IM(int)
840 #endif
841 #ifdef BUILD_IMAGE_CHAR
842 INST_IM(char)
843 #endif
844 #ifdef BUILD_IMAGE_SHORT
845 INST_IM(short)
846 #endif
847 #ifdef BUILD_IMAGE_USHORT
848 INST_IM(unsigned short)
849 #endif
850 #ifdef BUILD_IMAGE_UINT
851 INST_IM(unsigned int)
852 #endif
853 #ifdef BUILD_IMAGE_DOUBLE
854 INST_IM(double)
855 #endif
Matrix< KLT_TYPE > _gx1_5
static bool BilinearRegionColor3(const Image< StorageType > &im, const double &x, const double &y, const unsigned hws, Matrix< double > &res)
Fast bilinear interpolation of a region in interleaved color image.
bool IsInterleaved() const
Definition: ImageBase.hh:491
Matrix< KLT_TYPE > _gx2_5
Matrix< T > & newsize(Subscript M, Subscript N)
Definition: cmat.h:269
static bool LinearRegionX(const Image< StorageType > &im, const double &x, const unsigned &y, const unsigned hws, Matrix< double > &res)
Fast linear interpolation of a region in the image, untested.
Matrix< KLT_TYPE > _bl1_5
Matrix< KLT_TYPE > _gsy_5
unsigned int GetWidth() const
Definition: ImageBase.hh:312
StorageType PixelValue(const unsigned int x, const unsigned int y, const unsigned short int channel=0) const
Returns value of pixel at specific position, using specific channel as offset.
Definition: Image.hh:91
int NCCSearchEven(const unsigned int p1[2], const unsigned int p2[2], const StorageType **ida1, const StorageType **ida2, const unsigned int halfnccwinsize, const unsigned int halfsearchwinsize, unsigned int resultpoint[2], const double mincorrelation, double &result) const
As above but middle point of searchwindow is p1[0]+0.5, p1[1]+0.5 Searchwindow is always even-sized f...
static float AD(const unsigned int x1, const unsigned int y1, BIAS::Image< StorageType > &img1, const unsigned int x2, const unsigned int y2, BIAS::Image< StorageType > &img2)
calculates absolute difference between pixel (x1,y1) in image img1 and (x2,y2) in img2 ...
int ParabolaNCC(const unsigned int p1[2], const unsigned int p2[2], const StorageType **ida1, const StorageType **ida2, const unsigned int halfwinsize, KLT_TYPE result[2]) const
function to achieve sub-pixel accuracy if p1 and p2 are corresponding image points from ida1 resp ida...
int NCCSearchOdd(const unsigned int p1[2], const unsigned int p2[2], const StorageType **ida1, const StorageType **ida2, const unsigned int halfnccwinsize, const unsigned int halfsearchwinsize, unsigned int resultpoint[2], const double mincorrelation, double &result) const
Searches in a window around p2 [p2[i]+-halfsearchwinsize] for a point with correlation &gt; mincorrelati...
Matrix< KLT_TYPE > _bl2_5
unsigned int GetChannelCount() const
returns the number of Color channels, e.g.
Definition: ImageBase.hh:382
Matrix< KLT_TYPE > _gy2_5
unsigned int GetHeight() const
Definition: ImageBase.hh:319
INST(unsigned char)
Matrix< KLT_TYPE > _gy1_5
static bool BilinearRegion(const Image< StorageType > &im, const double &x, const double &y, const unsigned hws, Matrix< double > &res)
Fast bilinear interpolation of a region in grey image.
The image template class for specific storage types.
Definition: Image.hh:78
Matrix< KLT_TYPE > _gsx_5
KLT_TYPE _ParabolaApprox(const KLT_TYPE x1, const KLT_TYPE x2, const KLT_TYPE x3) const
bilinear interpolation, also moved gradient image data from [0:255] to [-127, 128] before interpolati...
int ParabolaNCC5(const unsigned int p1[2], const unsigned int p2[2], const StorageType **ida1, const StorageType **ida2, const unsigned int halfwinsize, KLT_TYPE result[2]) const
function to achieve sub-pixel accuracy if p1 and p2 are corresponding image points from ida1 resp ida...
void NCC(const unsigned int p1[2], const unsigned int p2[2], const StorageType **ida1, const StorageType **ida2, const unsigned int halfwinsize, double &result) const
fast ncc between p1 and p2 without boundary checking Faster specialisation for unsigned char exists b...
void _BilinearRegion(const StorageType **ida, const KLT_TYPE x, const KLT_TYPE y, const unsigned hws, Matrix< KLT_TYPE > &res) const
bilinear interpolation, also moved gradient image data from [0:255] to [-127, 128] before interpolati...
KLT_TYPE _Bilinear(const StorageType **ida, const KLT_TYPE x, const KLT_TYPE y) const
static bool BilinearRegionColor(const Image< StorageType > &im, const double &x, const double &y, const unsigned hws, Matrix< double > &res)
Fast bilinear interpolation of a region in interleaved color image.
const StorageType ** GetImageDataArray() const
overloaded GetImageDataArray() from ImageBase
Definition: Image.hh:153