Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
ExampleLineMatcher.cpp
1 /*
2 This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4 Copyright (C) 2003-2009 (see file CONTACT for details)
5 Multimediale Systeme der Informationsverarbeitung
6 Institut fuer Informatik
7 Christian-Albrechts-Universitaet Kiel
8 
9 
10 BIAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
14 
15 BIAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Lesser General Public License for more details.
19 
20 You should have received a copy of the GNU Lesser General Public License
21 along with BIAS; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24 
25 
26 /** @example ExampleLineMatcher.cpp
27  @brief This little example demonstrates the usage of line matching
28  @ingroup g_examples
29  @author woelk
30 */
31 
32 #include <Matcher2D/RegionMatcher.hh>
33 #include <Base/Image/Image.hh>
34 #include <Base/Image/ImageIO.hh>
35 #include <Base/Image/ImageConvert.hh>
36 
37 //#include <Filter/Gradient.hh>
38 //#include <Filter/GradientSimple.hh>
39 #include <Filter/GradientSobel3x3.hh>
40 
41 #include <Base/Math/Random.hh>
42 #include <Base/Debug/TimeMeasure.hh>
43 
44 #include <iostream>
45 #include <iomanip>
46 #include <math.h>
47 
48 using namespace BIAS;
49 using namespace std;
50 
51 
52 
53 // storage type(s) for filter and image templates
54 //#define InST char
55 #define InST float
56 //#define OutST char
57 #define OutST float
58 
59 
60 
61 int main(int argc, char*argv[])
62 {
63  Image<unsigned char> inputUC;
64  Image<InST> im1, im2;
65 
66  Image<OutST> grad1, grad2;
67  unsigned int p1[2], start[2], end[2];
68  unsigned int halfwinsize=7;
69  unsigned int epsilon=2;
70  double gradientscale=0.5;
71  unsigned int result[2];
72  double correlation=-1.0;
73  unsigned int offset=epsilon+halfwinsize;
74  int grad_threshold=2;
75  int res;
76  bool UseSAD=false;
77 
78  RegionMatcher matcher;
79  //matcher.SetDebugLevel(D_REGION_MATCHER_LINE);
80  //Gradient grad;
81  //GradientSimple<int, int> grad;
83 
84  Random rand;
85  double angle=rand.GetUniformDistributed(0.0, M_PI);
86  double length1, length2;
87  int count = 10000;
88  int maxlength, maxlength2;
89  bool debug=false;
90  int debuglevel=0;
91  TimeMeasure timerNCC, timerSAD;
92 
93  if (argc<2){
94  cerr << argv[0] << " : <image> ..."<< endl;
95  return -5;
96  }
97 
98  if (ImageIO::Load(argv[1], inputUC)!=0){
99  BIASERR("error loading image "<<argv[1]);
100  return -1;
101  }
102  //BIAS::ImageConvert::ConvertST(inputUC, im1, BIAS::ImageBase::ST_char);
104  im1=inputUC;
105  im2=im1;
106 
107  //grad.Sobel3Norm2(im1, grad1);
108  grad.Filter(im1,grad1);
109  grad2=grad1;
110 
111  //if (ImageIO::Save("grad", grad1)!=0){
112  if (ImageIO::Save("grad", grad1)!=0){
113  BIASERR("error writing image grad.mip");
114  return -1;
115  }
116 
117  for (int i=0; i< count; i++){
118 
119  do{
120  p1[0]=rand.GetUniformDistributedInt((int)offset,
121  (int)im1.GetWidth()-1-(int)offset);
122  p1[1]=rand.GetUniformDistributedInt((int)offset,
123  (int)im1.GetHeight()-1-(int)offset);
124  } while (grad1.GetImageDataArray()[p1[1]][p1[0]]<grad_threshold );
125 
126  if (debuglevel>=2)
127  cout << i<<":\tp1: "<<p1[0]<<" "<<p1[1]<<endl;
128  maxlength=
129  ((int)p1[0]-(int)offset>(int)im1.GetWidth()-(int)offset-(int)p1[0]-1) ?
130  (int)im1.GetWidth()-(int)offset-(int)p1[0]-1 : (int)p1[0]-(int)offset ;
131  maxlength2=
132  ((int)p1[1]-(int)offset>(int)im1.GetHeight()-(int)offset-(int)p1[1]-1) ?
133  (int)im1.GetHeight()-(int)offset-(int)p1[1]-1 : (int)p1[1]-(int)offset ;
134  maxlength=(maxlength>maxlength2)?maxlength2:maxlength;
135  if (debuglevel>=2)
136  cout << "p1: "<<p1[0]<<" "<<p1[1]<<"\tmaxlength: "<<maxlength<<endl;
137  length1=rand.GetUniformDistributedInt(0, maxlength);
138  start[0]=(unsigned int)rint((int)p1[0]+sin(angle)*length1);
139  start[1]=(unsigned int)rint((int)p1[1]+cos(angle)*length1);
140  length2=rand.GetUniformDistributedInt(0, maxlength);
141  end[0]=(unsigned int)rint((int)p1[0]-sin(angle)*length2);
142  end[1]=(unsigned int)rint((int)p1[1]-cos(angle)*length2);
143 
144  if (debuglevel>=2)
145  cout << "searching between "
146  <<start[0]<<" "<<start[1]<<" and "<<end[0]<<" "<<end[1]<<endl;
147 
148  int mycount=1;
149  //if (UseSAD){
150  timerSAD.Start();
151  for (int k=0; k<mycount; k++){
152  if (matcher.LineMatcherSAD<OutST>(
153  p1, start, end,
154  (const InST **)im1.GetImageDataArray(),
155  (const InST **)im2.GetImageDataArray(),
156  (const InST **)grad1.GetImageDataArray(),
157  (const InST **)grad2.GetImageDataArray(),
158  halfwinsize,
159  epsilon, gradientscale, result,
160  correlation)
161  !=0)
162  {
163  BIASERR("error in LineMatcherNCC");
164  return -2;
165  };
166  }
167  timerSAD.Stop();
168  cout << "SAD took "<<timerSAD.GetUserTime()/mycount<<" ms"<<endl;
169  // } else {
170  timerNCC.Start();
171  for (int k=0; k<mycount; k++){
172  if (matcher.LineMatcherNCC(p1, start, end,
173  (const InST **)im1.GetImageDataArray(),
174  (const InST **)im2.GetImageDataArray(),
175  (const InST **)grad1.GetImageDataArray(),
176  (const InST **)grad2.GetImageDataArray(), halfwinsize,
177  epsilon, gradientscale, result,
178  correlation)!=0){
179  BIASERR("error in LineMatcherNCC");
180  return -2;
181  };
182  }
183  timerNCC.Stop();
184  cout << "NCC took "<<timerNCC.GetUserTime()/mycount<<" ms"<<endl;
185  //}
186 
187  if (debuglevel>=1)
188  cout << "correspondence to "<<p1[0]<<" "<<p1[1]<<" searched between "
189  <<start[0]<<" "<<start[1]<<" and "<<end[0]<<" "<<end[1]<<" is at "
190  <<result[0]<<" "<<result[1]<<" with correlation "<<correlation
191  <<endl;
192 
193  if ((result[0]!=p1[0])||(result[1]!=p1[1])){
194  cerr << "\n\n***********\n\nerror, found wrong result\n\n***********\n\n"<<endl;
195  debug=true;
196  } else {
197  if (UseSAD){
198  if (correlation>0.1) debug=true;
199  else debug=false;
200  } else {
201  if (correlation<1.0) debug=true;
202  else debug = false;
203  }
204  }
205  if (debug){
206  cerr << "staring debug: "<<endl;
207  matcher.SetDebugLevel(D_REGION_MATCHER_LINE);
208  if (UseSAD){
209  if ((res =matcher.LineMatcherSAD(p1, start, end,
210  (const InST **)im1.GetImageDataArray(),
211  (const InST **)im2.GetImageDataArray(),
212  (const InST **)grad1.GetImageDataArray(),
213  (const InST **)grad2.GetImageDataArray(),
214  halfwinsize,
215  epsilon, gradientscale, result,
216  correlation))!=0){
217  BIASERR("error in LineMatcherSAD "<<res);
218  };
219  } else {
220  if ((res =matcher.LineMatcherNCC(p1, start, end,
221  (const InST **)im1.GetImageDataArray(),
222  (const InST **)im2.GetImageDataArray(),
223  (const InST **)grad1.GetImageDataArray(),
224  (const InST **)grad2.GetImageDataArray(),
225  halfwinsize,
226  epsilon, gradientscale, result,
227  correlation))!=0){
228  BIASERR("error in LineMatcherNCC "<<res);
229  };
230  }
231 
232  matcher.SetDebugLevel(0);
233  }
234 
235  }; // for
236  cout << "sum NCC took "<<timerNCC.GetUserTime()<<" ms"<<endl
237  << "sum SAD took "<<timerSAD.GetUserTime()<<" ms"<<endl;
238 
239  return 0;
240 }
241 
int LineMatcherSAD(const unsigned int p1[2], const unsigned int start2[2], const unsigned int end2[2], const StorageType **ida1, const StorageType **ida2, const StorageType **grad1, const StorageType **grad2, const unsigned int halfwinsize, const unsigned int epsilon, const double gradientscale, unsigned int result[2], double &sad) const
as above but uses SAD
float image storage type
Definition: ImageBase.hh:118
gradient calculation with sobel 3 by 3 masks
double GetUniformDistributed(const double min, const double max)
on succesive calls return uniform distributed random variable between min and max ...
Definition: Random.hh:84
unsigned int GetWidth() const
Definition: ImageBase.hh:312
int GetUniformDistributedInt(const int min, const int max)
get uniform distributed random variable including min/max
Definition: Random.cpp:139
static int ConvertST(const BIAS::ImageBase &source, BIAS::ImageBase &dest, ImageBase::EStorageType targetST)
Function to convert the storage type of images e.g.
void SetDebugLevel(const long int lv)
Definition: Debug.hh:318
unsigned int GetHeight() const
Definition: ImageBase.hh:319
static int Save(const std::string &filename, const ImageBase &img, const enum TFileFormat FileFormat=FF_auto, const bool sync=BIAS_DEFAULT_SYNC, const int c_jpeg_quality=BIAS_DEFAULT_IMAGE_QUALITY, const bool forceNewID=BIAS_DEFAULT_FORCENEWID, const bool &writeMetaData=true)
Export image as file using extrnal libs.
Definition: ImageIO.cpp:725
Basic functions for CornerMatcher.
int LineMatcherNCC(const unsigned int p1[2], const unsigned int start2[2], const unsigned int end2[2], const StorageType **ida1, const StorageType **ida2, const StorageType **grad1, const StorageType **grad2, const unsigned int halfwinsize, const unsigned int epsilon, const double gradientscale, unsigned int result[2], double &correlation) const
find correspondence to p1 from ida1 in ida2 at aproximate starting position p2 using KLT ...
static int Load(const std::string &FileName, ImageBase &img)
first tries a call to Read MIP image and if that fails, tries to Import Image with all other availabl...
Definition: ImageIO.cpp:141
virtual int Filter(const Image< InputStorageType > &src, Image< OutputStorageType > &grad)
returns a 2 channel image containing gx and gy
double GetUserTime() const
return user time (=system usage time) in msec JW For Win32: user-time is the sum over all processes o...
class for producing random numbers from different distributions
Definition: Random.hh:51
class TimeMeasure contains functions for timing real time and cpu time.
Definition: TimeMeasure.hh:111
const StorageType ** GetImageDataArray() const
overloaded GetImageDataArray() from ImageBase
Definition: Image.hh:153