Points&Forces (survey)
Software tools facilitating the task of surveying architecture
h_remap.cxx
Go to the documentation of this file.
1 /*
2  Copyright 2008-2018 Pierre SMARS (smars@yuntech.edu.tw)
3  This program is free software: you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation, either version 2 of the License, or
6  (at your option) any later version.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16 #include "a_image_defo.h"
17 #include "SimpleOpt.h"
18 #include <iostream>
19 #include <sstream>
20 
21 #include <vnl/vnl_matrix.h>
22 #include <vnl/algo/vnl_matrix_inverse.h>
23 
25 
26 CSimpleOpt::SOption g_rgOptions[] = {
27  { OPT_H, _T("-H"), SO_REQ_SEP },
28  { OPT_BOX, _T("-xm"), SO_REQ_SEP },
29  { OPT_BOX, _T("-xM"), SO_REQ_SEP },
30  { OPT_BOX, _T("-ym"), SO_REQ_SEP },
31  { OPT_BOX, _T("-yM"), SO_REQ_SEP },
32  { OPT_GETBOX, _T("-b"), SO_NONE },
33  { OPT_GETBOX, _T("--get-box"), SO_NONE },
34  { OPT_HELP, _T("-?"), SO_NONE },
35  { OPT_HELP, _T("-h"), SO_NONE },
36  { OPT_HELP, _T("--help"), SO_NONE },
37  SO_END_OF_OPTIONS
38 };
39 
40 //----------------------------------------------------------------------------
41 class a_h_remap: public a_image_defo
42 {
43  public:
44  a_h_remap(const vnl_matrix<double>& H);
45  void new_coordinates(double xo, double yo, double& xn, double& yn);
46  bool old_coordinates(double xn, double yn, double& xo, double& yo);
47  protected:
48  vnl_matrix<double> H_;
49  vnl_matrix<double> Hinv_;
50 };
51 
52 //---------------------------------------------------------------------------
53 a_h_remap::a_h_remap(const vnl_matrix<double>& H)
54 {
55  H_ = H;
56  Hinv_ = vnl_matrix_inverse<double>(H).as_matrix();
57  /*
58  for (int i=0;i<3;i++)
59  {
60  for (int j=0;j<3;j++)
61  std::cerr << Hinv_(i,j) << " ";
62  std::cerr << std::endl;
63  }
64  */
65 }
66 //---------------------------------------------------------------------------
67 void a_h_remap::new_coordinates(double xo, double yo, double& xn, double& yn)
68 {
69  vnl_vector<double> po(3);
70  po(0) = xo;
71  po(1) = yo;
72  po(2) = 1.;
73  vnl_vector<double> pn = H_*po;
74  xn = pn(0)/pn(2);
75  yn = pn(1)/pn(2);
76  //std::cerr << xo << " " << yo << " - " << xn << " " << yn << std::endl;
77 }
78 //---------------------------------------------------------------------------
79 bool a_h_remap::old_coordinates(double xn, double yn, double& xo, double& yo)
80 {
81  vnl_vector<double> pn(3);
82  pn(0) = xn;
83  pn(1) = yn;
84  pn(2) = 1.;
85  vnl_vector<double> po = Hinv_*pn;
86  xo = po(0)/po(2);
87  yo = po(1)/po(2);
88  if (xo<(double)box_in_[0]) return false;
89  if (xo>(double)box_in_[1]) return false;
90  if (yo<(double)box_in_[2]) return false;
91  if (yo>(double)box_in_[3]) return false;
92  return true;
93 }
94 //---------------------------------------------------------------------------
95 int error(int val)
96 {
97 #include "h_remap.help"
98  return val;
99 }
100 //---------------------------------------------------------------------------
101 int main(int argc, char ** argv)
102 {
103  vnl_matrix<double> H(3,3);
104  vnl_matrix<double> Hinv(3,3);
105  bool given_h = false;
106  bool get_box_out = false;
107  int xm, xM, ym, yM;
108  int val_code = 1000000;
109  xm = xM = ym = yM = val_code;
110  CSimpleOpt args(argc, argv, g_rgOptions);
111  while (args.Next())
112  {
113  if (args.LastError() == SO_SUCCESS)
114  {
115  if (args.OptionId() == OPT_HELP)
116  return error(0);
117  else if (args.OptionId() == OPT_GETBOX)
118  get_box_out = true;
119  else if (args.OptionId() == OPT_H)
120  {
121  std::ifstream in(args.OptionArg());
122  if (!in)
123  {
124  std::cerr << "Cannot open file" << std::endl;
125  return error(-2);
126  }
127  int u,v;
128  in >> u >> v;
129  if ((u!=3)||(v!=3))
130  {
131  std::cerr << "Matrix H should be 3x3" << std::endl;
132  return error(-3);
133  }
134  for (int i=0;i<3;i++)
135  {
136  for (int j=0;j<3;j++)
137  {
138  in >> H(i,j);
139  //std::cerr << H(i,j) << " ";
140  }
141  //std::cerr << std::endl;
142  }
143  given_h = true;
144  }
145  else if (args.OptionId() == OPT_BOX)
146  {
147  std::ostringstream o;
148  o << args.OptionArg();
149  std::istringstream in(o.str().c_str());
150  int val;
151  in >> val;
152  if (args.OptionText() == std::string("-xm"))
153  xm = val;
154  else if (args.OptionText() == std::string("-xM"))
155  xM = val;
156  else if (args.OptionText() == std::string("-ym"))
157  ym = val;
158  else if (args.OptionText() == std::string("-yM"))
159  yM = val;
160  } else
161  return error(-1);
162  // handle option, using OptionId(), OptionText() and OptionArg()
163  } else {
164  std::cerr << "Invalid argument: " << args.OptionText() << std::endl;
165  return error(args.LastError());
166  // handle error, one of: SO_OPT_INVALID, SO_OPT_MULTIPLE,
167  // SO_ARG_INVALID, SO_ARG_INVALID_TYPE, SO_ARG_MISSING
168  }
169  }
170  if (get_box_out)
171  {
172  if (args.FileCount() != 1) return error(-4);
173  }
174  else
175  {
176  if (args.FileCount() != 2) return error(-4);
177  }
178  if (!given_h) return error(-5);
179 
180  a_h_remap remap(H);
181  remap.read(args.File(0));
182  if (xm != val_code) remap.xm(xm);
183  if (xM != val_code) remap.xM(xM);
184  if (ym != val_code) remap.ym(ym);
185  if (yM != val_code) remap.yM(yM);
186  remap.box_out();
187  if (get_box_out)
188  remap.get_box_out();
189  else
190  {
191  remap.deform();
192  remap.write(args.File(1));
193  }
194  return 0;
195 }
vnl_matrix< double > Hinv_
Definition: h_remap.cxx:49
a_h_remap(const vnl_matrix< double > &H)
Definition: h_remap.cxx:53
bool old_coordinates(double xn, double yn, double &xo, double &yo)
gives the pixel coordinates in the input image in function of the pixel coordinates in the output ima...
Definition: h_remap.cxx:79
void new_coordinates(double xo, double yo, double &xn, double &yn)
gives the pixel coordinates in the output image in function of the pixel coordinates in the input ima...
Definition: h_remap.cxx:67
vnl_matrix< double > H_
Definition: h_remap.cxx:48
a unit to deform an image. The transformation function needs to be defined in a children class.
Definition: a_image_defo.h:29
void yM(const int val)
impose the size of the output bounding box
Definition: a_image_defo.h:51
void xm(const int val)
impose the size of the output bounding box
Definition: a_image_defo.h:45
void get_box_out() const
Definition: a_image_defo.h:52
void write(const std::string &name)
write the processed image to a file
void deform()
deform the image
void xM(const int val)
impose the size of the output bounding box
Definition: a_image_defo.h:47
virtual void read(const std::string &name)
read the image to be processed
virtual void box_out()
compute the bounding box of the new image
void ym(const int val)
impose the size of the output bounding box
Definition: a_image_defo.h:49
int box_in_[6]
Definition: a_image_defo.h:61
double v(const uint32_t step, const uint32_t n)
Definition: generate.cxx:42
@ OPT_GETBOX
Definition: h_remap.cxx:24
@ OPT_HELP
Definition: h_remap.cxx:24
@ OPT_H
Definition: h_remap.cxx:24
@ OPT_BOX
Definition: h_remap.cxx:24
int error(int val)
Definition: h_remap.cxx:95
CSimpleOpt::SOption g_rgOptions[]
Definition: h_remap.cxx:26
int main(int argc, char **argv)
Definition: h_remap.cxx:101
int xm
Definition: pixelpos.cxx:73
int ym
Definition: pixelpos.cxx:74
int xM
Definition: pixelpos.cxx:75
int yM
Definition: pixelpos.cxx:76
std::istringstream in
Definition: ply2tri.cxx:32