Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
biasprojection.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 #include <Base/Common/BIASpragma.hh>
26 
27 #include <Base/Image/ImageBase.hh>
28 #include <Base/Image/ImageIO.hh>
29 #include <Base/ImageUtils/ImageDraw.hh>
30 #include <stdio.h>
31 #include <map>
32 #include <string>
33 #include "Geometry/PMatrix.hh"
34 #include "Image/Camera.hh"
35 
36 #include <Base/Common/BIASpragma.hh>
37 
38 using namespace BIAS;
39 using namespace std;
40 
41 /**
42  @file
43  @ingroup g_tools
44  @brief read images and pmatrices, projects 3d points and cuts out region, see biasprojection.cpp
45  @author koeser
46  */
47 void usage()
48 {
49  cout << "Usage: biasprojection -p file [options] files"<<endl;
50  cout <<" Options: "<< endl
51  <<" -s : search next smaller(string compare) PMatrix file"<<endl
52  <<" -b : assume bbc camera file format"<<endl
53  <<" -p file : file containing 3d points"<<endl
54  << endl;
55  cout <<"This program opens the image files given by the command line"
56  <<", e.g. image037.pgm, looks at the command line for a file "
57  <<" image037.pgm.mat and projects 3d points into the images."<<endl
58  <<" using the pmatrices."<<endl
59  <<" cutouts are written around the projection."<<endl
60  <<"Returns: 0 on success, 1 if errors occured."<<endl<<endl;
61 }
62 
63 int DetermineFiletype(const string &fn, ImageIO::TFileFormat &thetype)
64 {
65  int EndOfPrefix;
66  string suffix;
67 
68  EndOfPrefix = fn.rfind('.');
69 
70  suffix = fn.substr(EndOfPrefix+1,fn.length());
71  if (suffix == "pnm") thetype = ImageIO::FF_ppm;
72  else if (suffix == "ppm") thetype = ImageIO::FF_ppm;
73  else if (suffix == "pgm") thetype = ImageIO::FF_pgm;
74  else if (suffix == "mip") thetype = ImageIO::FF_mip;
75  else return -1;
76 
77  return 0;
78 }
79 
80 
81 int main (int argc, char *argv[])
82 {
83  bool Nearest = false, BBC = false;
84  vector<HomgPoint3D> Points;
85  int i = 1;
86  bool param = true;
87  while ((i<argc) && (param)) {
88  param = false;
89  if (!strcmp("-s",argv[i])) {
90  std::cout << "Using nearest P from command line also."<<endl;
91  Nearest = true;
92  i++;
93  param = true;
94  }
95  if (!strcmp("-b",argv[i])) {
96  std::cout << "Trying to load BBC camera data."<<endl;
97  BBC = true;
98  i++;
99  param = true;
100  }
101  if (!strcmp("-p",argv[i])) {
102  i++;
103  if (argc<=i) {
104  cerr<<"error, no point file given after -p"<<endl;
105  exit(-1);
106  }
107  std::cout << "loading points from "<< argv[i]<<endl;
108  ifstream infile(argv[i++], ios::in);
109  if (infile.eof() || !infile.good()){
110  cerr<<"error opening point file"<<endl;
111  exit(-1);
112  }
113  // reading points
114  HomgPoint3D thepoint(0,0,0);
115  while (!infile.eof()) {
116  infile >> thepoint[0];
117  infile >> thepoint[1];
118  infile >> thepoint[2];
119  if (infile.eof() || !infile.good()) break;
120  Points.push_back(thepoint);
121  cout<<"Read 3D point "<<thepoint<<endl;
122  }
123  param = true;
124  }
125 
126  }
127 
128  if (i>=argc || Points.size()==0) {
129  usage();
130  return -1;
131  }
132 
133  ImageIO::TFileFormat FileType;
134  bool ErrorFlag = false;
135  int IOResult = 0;
137 
138  PMatrix P;
139  map<string, PMatrix> mapP;
140  for (int j=i; j<argc; j++) {
141  if (strstr(argv[j], ".mat")!=NULL) {
142  cout<<"arg "<<j<<" is .mat";
143  PMatrix P;
144  P.SetZero();
145  if (!BBC) {
146  P.Load(argv[j]);
147  } else {
148  P.LoadBBC(argv[j]);
149  }
150  cout << "P is "<<P<<endl;
151  mapP[argv[j]] = P;
152  }
153  }
154  if (mapP.size()==0) {
155  BIASERR("No matrices found !");
156  return -1;
157  }
158 
159  const int cosize = 40;
160 
161 
162 
163  for (;i<argc;i++) {
164  if (strstr(argv[i], ".mat")!=NULL) continue;
165  cout<< "Trying "<<argv[i]<<endl;
166  if (DetermineFiletype(argv[i], FileType)!=0) {
167  BIASERR("Skipping current file because of unknown/unsuported format: "
168  <<argv[i]<<endl<<"PMatrix can be written to mip,pgm,ppm,pnm");
169  ErrorFlag = true;
170  continue;
171  }
172 
173  IOResult = ImageIO::Load(argv[i], CurImage);
174  if (IOResult!=0) {
175  ErrorFlag = true;
176  BIASERR("Error reading "<< argv[i]);
177  continue;
178  }
179 
180  stringstream ss;
181  ss << argv[i] <<".mat";
182  if (mapP.find(ss.str())!=mapP.end()) {
183  cout<<"Found a mat file for "<<argv[i]<<endl;
184  P = mapP[ss.str()];
185  } else {
186  if (!Nearest) {
187  cout <<"Found NO mat file for "<<argv[i]<<" !!!!! SKIPPING"<<endl;
188  continue;
189  }
190  map<string,PMatrix>::iterator it = mapP.lower_bound(ss.str());
191  if (it != mapP.begin()) it--;
192  else cout<<"First element, cant use smaller, must use larger !";
193  P = it->second;
194  cout <<"Found next mat file for "<<argv[i]<<": "<<it->first<<endl;
195  }
196  // just a dummy class to do the metadata job for us
198  c.SetP(P);
199  if (P.IsMetric()) {
200  c.SetK(P.GetK());
201  c.SetR(RMatrix(P.GetR()));
202  c.SetC(P.GetC());
203  }
204  c.UpdateMetaData();
205  CurImage.SetMetaData(*c.GetMetaData());
206  Camera<unsigned char> cutout;
207  cutout.Init(cosize*2+1, cosize*2+1, CurImage.GetChannelCount());
208  bool simplecopy = false;
209  for (unsigned int p=0; p<Points.size(); p++) {
210  KMatrix K = P.GetK();
211  HomgPoint2D x = P*Points[p];
212  x.Homogenize();
213  // find closest grid position
214  x[0] = rint(x[0]);
215  x[1] = rint(x[1]);
216 
217  if (x[0]<cosize || x[0]>= CurImage.GetWidth()-cosize ||
218  x[1]<cosize || x[1]>= CurImage.GetWidth()-cosize) continue;
219  if (simplecopy) {
220  CurImage.SetROI(int(x[0]-cosize), int(x[1]-cosize),
221  int(x[0]+cosize+1), int(x[1]+cosize+1));
222  CurImage.GetCopyOfROI(cutout);
223  K[0][2] += x[0]-cosize;
224  K[1][2] += x[1]-cosize;
225  } else {
226 
227  float dx = 0, dy = 0;
228  unsigned char** pData = cutout.GetImageDataArray();
229  for (int xx=-cosize; xx<=cosize; xx++) {
230  for (int yy=-cosize; yy<=cosize; yy++) {
231  dx = float(xx)/2.0;
232  dy = float(yy)/2.0;
233  for (unsigned int c=0; c<CurImage.GetChannelCount(); c++) {
234  double value = CurImage.BilinearInterpolation(x[0]+dx,x[1]+dy,c);
235  value = rint(value);
236  if (value<0.0) value = 0.0;
237  if (value>255.0) value = 255.0;
238  pData[yy+cosize][(xx+cosize)*CurImage.GetChannelCount()+c] =
239  (unsigned char) value;
240  }
241  }
242  }
243  }
244 
245  ImageDraw<unsigned char>::RectangleCorners(cutout, cosize-5, cosize-5,
246  cosize+5, cosize+5);
247  ImageDraw<unsigned char>::RectangleCorners(cutout, cosize-4, cosize-4,
248  cosize+4, cosize+4);
249 
250  string filename = argv[i];
251  unsigned int pos = filename.rfind("/");
252  if (pos!=string::npos) filename = filename.substr(pos+1);
253  stringstream filenamess;
254  filenamess<<filename<<"_"<<p;
255 
256  // set kmatrix to camera
257  PMatrix PNew(K, P.GetR(), P.GetC());
258  cutout.SetP(PNew);
259  /*
260  if (FileType==ImageIO::FF_mip) {
261  IOResult = ImageIO::Save(filenamess.str(), cutout, false, false );
262  } else {
263  IOResult = ImageIO::Save(filenamess.str(), cutout, FileType,
264  false, 0, false);
265  } */
266  IOResult = ImageIO::Save(filenamess.str(),
267  cutout,
268  FileType,
269  false,
270  0,
271  false);
272 
273  if (IOResult!=0) {
274  ErrorFlag = true;
275  BIASERR("Error writing "<< filenamess.str());
276  continue;
277  }
278  }
279 
280 
281  }
282  if (ErrorFlag) cout << "There were errors." <<endl;
283  if (ErrorFlag) return 1;
284  return 0;
285 }
286 
287 
int GetCopyOfROI(ImageBase &copy) const
returns a copy of ROI (a new image) lower right point excluded, only interleaved images ! ...
Definition: ImageBase.cpp:568
class HomgPoint2D describes a point with 2 degrees of freedom in projective coordinates.
Definition: HomgPoint2D.hh:67
double BilinearInterpolation(const double x, const double y, const unsigned short int channel=0) const
Generic bilinear interpolation.
Definition: Image.cpp:1341
bool Load(const std::string &filename)
overload Load because it has to invalidate decomposition! JW 09/2003
Definition: PMatrix.hh:348
HomgPoint2D & Homogenize()
homogenize class data member elements to W==1 by divison by W
Definition: HomgPoint2D.hh:215
MetaData * GetMetaData()
Definition: ImageBase.hh:456
int SetP(const PMatrix &matP)
Definition: Camera.hh:102
int GetR(Matrix3x3< double > &R)
Definition: PMatrix.cpp:204
unsigned int GetWidth() const
Definition: ImageBase.hh:312
static int RectangleCorners(Image< StorageType > &im, const int minx, const int miny, const int maxx, const int maxy, const StorageType value[])
rectangles
Definition: ImageDraw.cpp:94
3D rotation matrix
Definition: RMatrix.hh:49
int LoadBBC(const std::string &filename, const double &AddCenterPointShiftX=0.0, const double &AddCenterPointShiftY=0.0)
Load calibration data file from BBC-Free-D system.
Definition: PMatrix.cpp:905
void SetZero()
Sets all values to zero.
Definition: Matrix.hh:856
unsigned int GetChannelCount() const
returns the number of Color channels, e.g.
Definition: ImageBase.hh:382
TFileFormat
format specifier when writing an image to a file Do NOT change order or associated enum value because...
Definition: ImageIO.hh:76
void SetC(const Vector3< double > &C)
Definition: Camera.hh:167
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
int SetROI(unsigned int UpperLeftX, unsigned int UpperLeftY, unsigned int LowerRightX, unsigned int LowerRightY)
deprecated, use SetROICorners()
Definition: ImageBase.cpp:1033
class HomgPoint3D describes a point with 3 degrees of freedom in projective coordinates.
Definition: HomgPoint3D.hh:61
void Init(unsigned int Width, unsigned int Height, unsigned int channels=1, enum EStorageType storageType=ST_unsignedchar, const bool interleaved=true)
calls Init from ImageBase storageType is ignored, just dummy argument
Definition: Image.cpp:421
bool IsMetric()
Definition: PMatrix.hh:134
int UpdateMetaData()
copy P_ and co.
Definition: Camera.cpp:446
int GetC(Vector3< double > &C)
computes translation vector origin world coo -&gt; origin camera coo (center), uses decomposition, which is cached
Definition: PMatrix.cpp:165
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
K describes the mapping from world coordinates (wcs) to pixel coordinates (pcs).
Definition: KMatrix.hh:48
describes a projective 3D -&gt; 2D mapping in homogenous coordinates
Definition: PMatrix.hh:88
void SetK(const KMatrix &K)
Definition: Camera.hh:173
void SetMetaData(const MetaData &m)
Definition: ImageBase.hh:470
void SetR(const RMatrix &R)
Definition: Camera.hh:170
int GetK(KMatrix &K)
calibration matrix
Definition: PMatrix.cpp:220
const StorageType ** GetImageDataArray() const
overloaded GetImageDataArray() from ImageBase
Definition: Image.hh:153