26 #include "CornerMatcher.hh"
33 template BIASMatcher2D_EXPORT int CornerMatcher::SSD<uctype>(const HomgPoint2D& p1, const HomgPoint2D& p2,\
34 const Image<uctype>& im1,\
35 const Image<uctype>& im2, const unsigned int halfwinsize, double& result)const ;\
36 template BIASMatcher2D_EXPORT int CornerMatcher::NCC<uctype>(const HomgPoint2D& p1, const HomgPoint2D& p2,\
37 const Image<uctype>& im1,\
38 const Image<uctype>& im2, const unsigned int halfwinsize, double& result)const ;\
39 template BIASMatcher2D_EXPORT int CornerMatcher::NCCSearch<uctype>(const HomgPoint2D& p1, const HomgPoint2D& p2,\
40 const Image<uctype>& im1, const Image<uctype>& im2, \
41 const unsigned int halfnccwinsize, const unsigned int halfsearchwinsize, \
42 HomgPoint2D& resultpoint,\
43 const double mincorrelation, \
45 template BIASMatcher2D_EXPORT int CornerMatcher::ParabolaNCC(const HomgPoint2D& p1, const HomgPoint2D& p2,\
46 const Image<uctype>& im1, const Image<uctype>& im2, const unsigned int halfwinsize,\
47 HomgPoint2D& result)const ;\
48 template BIASMatcher2D_EXPORT int CornerMatcher::ParabolaNCC5(const HomgPoint2D& p1, const HomgPoint2D& p2,\
49 const Image<uctype>& im1, const Image<uctype>& im2, const unsigned int halfwinsize,\
50 HomgPoint2D& result)const ;\
51 template BIASMatcher2D_EXPORT int CornerMatcher::RefinePyramideNCC<uctype>(\
52 std::vector<std::vector<HomgPoint2D> >& ps1, PyramidImage<uctype>& im1, \
53 PyramidImage<uctype>& im2, unsigned int halfnccwinsize, \
54 std::vector<std::vector<HomgPoint2D> >& matches, \
55 std::vector<std::vector<double> >& matchquality)
63 #ifdef BUILD_IMAGE_INT
66 #ifdef BUILD_IMAGE_CHAR
69 #ifdef BUILD_IMAGE_SHORT
72 #ifdef BUILD_IMAGE_USHORT
75 #ifdef BUILD_IMAGE_UINT
78 #ifdef BUILD_IMAGE_DOUBLE
90 template <
class StorageType>
94 const unsigned int halfwinsize,
double& result)
const
98 unsigned int uip1[2], uip2[2];
102 ip1[0]=(int)rint(p1[0]/p1[2]);
103 ip1[1]=(int)rint(p1[1]/p1[2]);
104 ip2[0]=(int)rint(p2[0]/p2[2]);
105 ip2[1]=(int)rint(p2[1]/p2[2]);
106 if (ip1[0]<(
int)halfwinsize ||
107 ip1[0]+(int)halfwinsize>=(
int)im1.
GetWidth() ||
108 ip1[1]<(int)halfwinsize ||
109 ip1[1]+(
int)halfwinsize>=(int)im1.
GetHeight() ||
110 ip2[0]<(int)halfwinsize ||
111 ip2[0]+(
int)halfwinsize>=(int)im2.
GetWidth() ||
112 ip2[1]<(int)halfwinsize ||
113 ip2[1]+(
int)halfwinsize>=(int)im2.
GetHeight())
116 uip1[0]=(
unsigned int)ip1[0];
117 uip1[1]=(
unsigned int)ip1[1];
118 uip2[0]=(
unsigned int)ip2[0];
119 uip2[1]=(
unsigned int)ip2[1];
127 template <
class StorageType>
131 const unsigned int halfwinsize,
double& result)
const
135 unsigned int uip1[2], uip2[2];
139 ip1[0]=(int)rint(p1[0]/p1[2]);
140 ip1[1]=(int)rint(p1[1]/p1[2]);
141 ip2[0]=(int)rint(p2[0]/p2[2]);
142 ip2[1]=(int)rint(p2[1]/p2[2]);
143 if (ip1[0]<(
int)halfwinsize ||
144 ip1[0]+(int)halfwinsize>=(
int)im1.
GetWidth() ||
145 ip1[1]<(int)halfwinsize ||
146 ip1[1]+(
int)halfwinsize>=(int)im1.
GetHeight() ||
147 ip2[0]<(int)halfwinsize ||
148 ip2[0]+(
int)halfwinsize>=(int)im2.
GetWidth() ||
149 ip2[1]<(int)halfwinsize ||
150 ip2[1]+(
int)halfwinsize>=(int)im2.
GetHeight())
153 uip1[0]=(
unsigned int)ip1[0];
154 uip1[1]=(
unsigned int)ip1[1];
155 uip2[0]=(
unsigned int)ip2[0];
156 uip2[1]=(
unsigned int)ip2[1];
165 template <
class StorageType>
169 const unsigned int halfnccwinsize,
170 const unsigned int halfsearchwinsize,
172 const double mincorrelation,
178 const double THRESHOLD=1e-8;
181 unsigned int uip1[2], uip2[2], resp[2];
182 int minedgedist = halfnccwinsize + halfsearchwinsize;
186 ip1[0]=(int)rint(p1[0]/p1[2]);
187 ip1[1]=(int)rint(p1[1]/p1[2]);
188 ip2[0]=(int)rint(p2[0]/p2[2]);
189 ip2[1]=(int)rint(p2[1]/p2[2]);
190 if (fabs(p2[0]/p2[2]-ip2[0])<THRESHOLD &&
191 fabs(p2[1]/p2[2]-ip2[1])<THRESHOLD )
193 if (ip1[0] <= minedgedist || ip1[0] + minedgedist>=(
int)im1.
GetWidth() ||
194 ip1[1] <= minedgedist || ip1[1] + minedgedist>=(int)im1.
GetHeight() ||
195 ip2[0] <= minedgedist || ip2[0] + minedgedist>=(int)im2.
GetWidth() ||
196 ip2[1] <= minedgedist || ip2[1] + minedgedist>=(int)im2.
GetHeight() ){
199 uip1[0]=(
unsigned int)ip1[0];
200 uip1[1]=(
unsigned int)ip1[1];
201 uip2[0]=(
unsigned int)ip2[0];
202 uip2[1]=(
unsigned int)ip2[1];
203 BIASDOUT(D_CORNER_MATCHER_SEARCH,
"p1 " << p1 <<
" " << uip1[0] <<
" "
204 << uip1[1] <<
"\tp2 " << p2 <<
" " << uip2[0]<<
" "<< uip2[1]);
205 BIASDOUT(D_CORNER_MATCHER_SEARCH,
"using NCCSearchOdd for " << p2
206 <<
" " << uip2[0] <<
" "<< uip2[1]);
209 halfsearchwinsize, resp, mincorrelation, result);
210 resultpoint.
Set((
double)resp[0], (
double)resp[1]);
211 BIASDOUT(D_CORNER_MATCHER_SEARCH,
"resultpoint " << resultpoint);
214 ip1[0]=(int)rint(p1[0]/p1[2]);
215 ip1[1]=(int)rint(p1[1]/p1[2]);
216 ip2[0]=(int)floor(p2[0]/p2[2]);
217 ip2[1]=(int)floor(p2[1]/p2[2]);
218 if (ip1[0] < minedgedist || ip1[0] + minedgedist>=(
int)im1.
GetWidth() ||
219 ip1[1] < minedgedist || ip1[1] + minedgedist>=(int)im1.
GetHeight() ||
220 ip2[0] < minedgedist || ip2[0] + minedgedist>=(int)im2.
GetWidth() ||
221 ip2[1] < minedgedist || ip2[1] + minedgedist>=(int)im2.
GetHeight() ){
224 uip1[0]=(
unsigned int)ip1[0];
225 uip1[1]=(
unsigned int)ip1[1];
226 uip2[0]=(
unsigned int)ip2[0];
227 uip2[1]=(
unsigned int)ip2[1];
228 BIASDOUT(D_CORNER_MATCHER_SEARCH,
"using NCCSearchEven for " << p2
229 <<
" " << uip2[0] <<
" "<< uip2[1]);
232 halfsearchwinsize, resp, mincorrelation, result);
233 resultpoint.
Set((
double)resp[0], (
double)resp[1]);
234 BIASDOUT(D_CORNER_MATCHER_SEARCH,
"resultpoint " << resultpoint);
500 template <
class StorageType>
504 const unsigned int halfwinsize,
HomgPoint2D& result)
const
508 unsigned int uip1[2], uip2[2];
511 int minedgedist = halfwinsize + 1;
515 ip1[0]=(int)rint(p1[0]/p1[2]);
516 ip1[1]=(int)rint(p1[1]/p1[2]);
517 ip2[0]=(int)rint(p2[0]/p2[2]);
518 ip2[1]=(int)rint(p2[1]/p2[2]);
519 if (ip1[0] < minedgedist || ip1[0] + minedgedist>=(
int)im1.
GetWidth() ||
520 ip1[1] < minedgedist || ip1[1] + minedgedist>=(int)im1.
GetHeight() ||
521 ip2[0] < minedgedist || ip2[0] + minedgedist>=(int)im2.
GetWidth() ||
522 ip2[1] < minedgedist || ip2[1] + minedgedist>=(int)im2.
GetHeight() ){
525 uip1[0]=(
unsigned int)ip1[0];
526 dp1x=p1[0]-(double)uip1[0];
527 uip1[1]=(
unsigned int)ip1[1];
528 dp1y=p1[1]-(double)uip1[1];
529 uip2[0]=(
unsigned int)ip2[0];
530 uip2[1]=(
unsigned int)ip2[1];
534 result.
Set(resu[0]+dp1x, resu[1]+dp1y);
535 BIASDOUT(D_CORNER_MATCHER_PARABOLA,
"\np1 "<<p1<<
"\tp2 "<<p2
536 <<
"\tuip1 "<<uip1[0]<<
" "<<uip1[1]<<
"\tuip2 "<<uip2[0]
537 <<
" "<<uip2[1]<<
"\tresu: "<<resu[0]<<
" "<<resu[1]
538 <<
"\tdp1x/y "<<dp1x<<
" "<<dp1y);
545 template <
class StorageType>
549 const unsigned int halfwinsize,
HomgPoint2D& result)
const
553 unsigned int uip1[2], uip2[2];
556 int minedgedist = halfwinsize + 2;
560 ip1[0]=(int)rint(p1[0]/p1[2]);
561 ip1[1]=(int)rint(p1[1]/p1[2]);
562 ip2[0]=(int)rint(p2[0]/p2[2]);
563 ip2[1]=(int)rint(p2[1]/p2[2]);
564 if (ip1[0] < minedgedist || ip1[0] + minedgedist>=(
int)im1.
GetWidth() ||
565 ip1[1] < minedgedist || ip1[1] + minedgedist>=(int)im1.
GetHeight() ||
566 ip2[0] < minedgedist || ip2[0] + minedgedist>=(int)im2.
GetWidth() ||
567 ip2[1] < minedgedist || ip2[1] + minedgedist>=(int)im2.
GetHeight() ){
570 uip1[0]=(
unsigned int)ip1[0];
571 dp1x=p1[0]-(double)uip1[0];
572 uip1[1]=(
unsigned int)ip1[1];
573 dp1y=p1[1]-(double)uip1[1];
574 uip2[0]=(
unsigned int)ip2[0];
575 uip2[1]=(
unsigned int)ip2[1];
579 result.
Set(resu[0]+dp1x, resu[1]+dp1y);
580 BIASDOUT(D_CORNER_MATCHER_PARABOLA,
"\np1 "<<p1<<
"\tp2 "<<p2
581 <<
"\tuip1 "<<uip1[0]<<
" "<<uip1[1]<<
"\tuip2 "<<uip2[0]
582 <<
" "<<uip2[1]<<
"\tresu: "<<resu[0]<<
" "<<resu[1]
583 <<
"\tdp1x/y "<<dp1x<<
" "<<dp1y);
590 template <
class StorageType>
595 unsigned int halfnccwinsize,
596 vector<vector<HomgPoint2D> >& matches,
597 vector<vector<double> >& matchquality)
600 unsigned p1[2], p2[2];
601 const StorageType **ida1, **ida2;
603 for (
int lev=im1.
size()-2; lev>=0; lev--){
604 matches[lev].resize(ps1[lev].size());
605 matchquality[lev].resize(ps1[lev].size());
606 ida1=(
const StorageType **)im1[lev]->GetImageDataArray();
607 ida2=(
const StorageType **)im2[lev]->GetImageDataArray();
608 unsigned maxx=im1[lev]->GetWidth()-halfnccwinsize-1;
609 unsigned maxy=im1[lev]->GetHeight()-halfnccwinsize-1;
610 for (
unsigned i=0; i<ps1[lev].size(); i++){
611 p1[0]=(
unsigned int)rint(ps1[lev][i][0]);
612 p1[1]=(
unsigned int)rint(ps1[lev][i][1]);
613 p2[0]=((
unsigned int)rint(matches[lev+1][i][0]))<<1;
614 p2[1]=((
unsigned int)rint(matches[lev+1][i][1]))<<1;
615 if (p1[0]>halfnccwinsize && p1[0]<maxx &&
616 p1[1]>halfnccwinsize && p1[1]<maxy &&
617 p2[0]>halfnccwinsize && p2[0]<maxx &&
618 p2[1]>halfnccwinsize && p2[1]<maxy &&
619 matchquality[lev+1][i] > -1.0){
621 1.0, matchquality[lev][i]);
623 matchquality[lev][i]=-5.0;
625 matches[lev][i].Set((
double)p2[0], (
double)p2[1]);
class HomgPoint2D describes a point with 2 degrees of freedom in projective coordinates.
int RefinePyramideNCC(std::vector< std::vector< HomgPoint2D > > &ps1, PyramidImage< StorageType > &im1, PyramidImage< StorageType > &im2, unsigned int halfnccwinsize, std::vector< std::vector< HomgPoint2D > > &matches, std::vector< std::vector< double > > &matchquality)
Assumes that ps1 is fully filled.
unsigned size() const
deprecated interface
int SSD(const HomgPoint2D &p1, const HomgPoint2D &p2, const Image< StorageType > &im1, const Image< StorageType > &im2, const unsigned int halfwinsize, double &result) const
wrapper for SSD from RegionMatcher, does boundary checks and casts uses rint to determine location of...
unsigned int GetWidth() const
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...
int NCC(const HomgPoint2D &p1, const HomgPoint2D &p2, const Image< StorageType > &im1, const Image< StorageType > &im2, const unsigned int halfwinsize, double &result) const
wrapper for NCC from RegionMatcher, does boundary checks and casts uses rint to determine location of...
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 > mincorrelati...
int NCCSearch(const HomgPoint2D &p1, const HomgPoint2D &p2, const Image< StorageType > &im1, const Image< StorageType > &im2, const unsigned int halfnccwinsizeconst, const unsigned int halfsearchwinsize, HomgPoint2D &resultpoint, const double mincorrelation, double &result)
wrapper for RegionMatcher::NCCSearchOdd/NCCSearchEven, does boundary checks and casts ...
bool IsAtInfinity() const
unsigned int GetHeight() const
void SSD(const unsigned int p1[2], const unsigned int p2[2], const StorageType **ida1, const StorageType **ida2, const unsigned int halfwinsize, double &result) const
fast sum of square differences (SSD) sim.
The image template class for specific storage types.
Basic functions for CornerMatcher.
enum EColorModel GetColorModel() const
int ParabolaNCC(const HomgPoint2D &p1, const HomgPoint2D &p2, const Image< StorageType > &im1, const Image< StorageType > &im2, const unsigned int halfwinsize, HomgPoint2D &result) const
wrapper with range checking for RegionMatcher::KLT for a description see RegionMatcher::KLT gradientb...
int ParabolaNCC5(const HomgPoint2D &p1, const HomgPoint2D &p2, const Image< StorageType > &im1, const Image< StorageType > &im2, const unsigned int halfwinsize, HomgPoint2D &result) const
wrapper for RegionMatcher::ParabolaNCC5
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 Set(const HOMGPOINT2D_TYPE &x, const HOMGPOINT2D_TYPE &y)
set elementwise with given 2 euclidean scalar values.
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...
const StorageType ** GetImageDataArray() const
overloaded GetImageDataArray() from ImageBase