Points&Forces (survey)
Software tools facilitating the task of surveying architecture
im2li.cxx
Go to the documentation of this file.
1 /*
2  Copyright 2008-2019 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 
17 #include <iostream>
18 #include <sstream>
19 #include <vil/vil_load.h>
20 #include <vil/vil_convert.h>
21 #include <vil/vil_image_view.h>
22 #include <vil1/vil1_vil.h>
23 #include <vil1/vil1_memory_image_of.h>
24 #include <osl/osl_canny_ox_params.h>
25 #include <osl/osl_canny_ox.h>
26 #include "vtkKochanekSpline.h"
27 
28 #include "SimpleOpt.h"
29 
31 
32 CSimpleOpt::SOption g_rgOptions[] = {
33  { OPT_SIGMA, _T("-s"), SO_REQ_SEP },
34  { OPT_SIGMA, _T("--sigma"), SO_REQ_SEP },
35  { OPT_SPLINE, _T("-r"), SO_REQ_SEP },
36  { OPT_SPLINE, _T("--regularize"), SO_REQ_SEP },
37  { OPT_VERBOSE, _T("-v"), SO_NONE },
38  { OPT_VERBOSE, _T("--verbose"), SO_NONE },
39  { OPT_HELP, _T("-?"), SO_NONE },
40  { OPT_HELP, _T("-h"), SO_NONE },
41  { OPT_HELP, _T("--help"), SO_NONE },
42  SO_END_OF_OPTIONS
43 };
44 //---------------------------------------------------------------------------
45 class a_line
46 {
47  public:
48  a_line(double * x0, double * x);
49  friend std::ostream& operator<< (std::ostream& o, const a_line& l);
50  protected:
51  double x0_[2];
52  double x_[2];
53 };
54 //---------------------------------------------------------------------------
55 a_line::a_line(double * x0, double * x)
56 {
57  for (int i=0; i<2; i++)
58  {
59  x0_[i] = x0[i];
60  x_[i] = x[i];
61  }
62 }
63 //---------------------------------------------------------------------------
64 std::ostream& operator<< (std::ostream& o, const a_line& l)
65 {
66  o << l.x0_[0] << " " << l.x0_[1] << " 0 " << l.x_[0] << " " << l.x_[1] << " 0" << std::endl;
67  return o;
68 }
69 //---------------------------------------------------------------------------
70 int error(int val)
71 {
72 #include "im2li.help"
73  return val;
74 }
75 //---------------------------------------------------------------------------
76 double round(double val)
77 {
78  return (int)(val*10+.5)/10.;
79 }
80 //---------------------------------------------------------------------------
81 int main(int argc, char **argv)
82 {
83  bool with_spline = false;
84  double step = 10.;
85  double tension = 0;
86  double bias = 0;
87  double continuity = 0;
88  bool verbose = false;
89  osl_canny_ox_params params;
90  CSimpleOpt args(argc, argv, g_rgOptions);
91  while (args.Next())
92  {
93  if (args.LastError() == SO_SUCCESS)
94  {
95  if (args.OptionId() == OPT_HELP)
96  return error(0);
97  else if (args.OptionId() == OPT_VERBOSE)
98  verbose=true;
99  else if (args.OptionId() == OPT_SIGMA)
100  {
101  std::ostringstream o;
102  o << args.OptionArg();
103  std::istringstream in(o.str().c_str());
104  in >> params.sigma;
105  }
106  else if (args.OptionId() == OPT_SPLINE)
107  {
108  std::ostringstream o;
109  o << args.OptionArg();
110  std::istringstream in(o.str().c_str());
111  in >> step;
112  if ((step <= 0.)||(step>1000.))
113  return error(-3);
114  with_spline = true;
115  }
116  else
117  return error(-1);
118  // handle option, using OptionId(), OptionText() and OptionArg()
119  } else {
120  std::cerr << "Invalid argument: " << args.OptionText() << std::endl;
121  return error(args.LastError());
122  // handle error, one of: SO_OPT_INVALID, SO_OPT_MULTIPLE,
123  // SO_ARG_INVALID, SO_ARG_INVALID_TYPE, SO_ARG_MISSING
124  }
125  }
126  if (args.FileCount() != 1) return error(-2);
127  std::string in_file = args.File(0);
128  params.verbose=verbose;
129  vil_image_view<vxl_byte> img;
130  img = vil_convert_stretch_range (vxl_byte(), vil_convert_to_component_order(
131  vil_convert_to_n_planes(1, vil_convert_cast(vxl_byte(), vil_load(in_file.c_str())))));
132  if (!img)
133  return 1;
134  if (verbose)
135  std::cerr << in_file << " : " << img << std::endl;
136  vil1_memory_image_of<vxl_byte> image = vil1_from_vil_image_view(img);
137  if (verbose)
138  std::cerr << "operates on : " << image << std::endl;
139  std::list<a_line> lines;
140  std::list<osl_edge*> edges;
141  //segment the image
142  osl_canny_ox filter(params);
143  filter.detect_edges(image, &edges);
144  //double dist = 0;
145  for(std::list<osl_edge*>::iterator i=edges.begin(); i != edges.end(); ++i)
146  {
147  //length of the polyline
148  double dist = 0.;
149  vtkKochanekSpline * s[2];
150  if (with_spline)
151  {
152  for (int j = 0; j < 2; j++)
153  {
154  s[j] = vtkKochanekSpline::New();
155  s[j]->SetDefaultTension(tension);
156  s[j]->SetDefaultBias(bias);
157  s[j]->SetDefaultContinuity(continuity);
158  }
159  }
160  double x0[2], x[2];
161  //origin of polyline
162  x0[0] = (*i)->GetX(0);
163  x0[1] = (*i)->GetY(0);
164  if (with_spline)
165  for (int j = 0; j < 2; j++) s[j]->AddPoint(0,x0[j]);
166  //add control point to the spline
167  for (int j=1; j<(*i)->size(); j++)
168  {
169  //point on polyline
170  x[0] = (*i)->GetX(j);
171  x[1] = (*i)->GetY(j);
172  if (with_spline)
173  {
174  //calculate length of polyline
175  dist += sqrt((x[0]-x0[0])*(x[0]-x0[0])+(x[1]-x0[1])*(x[1]-x0[1]));
176  //add control point to the spline
177  for (int k = 0; k < 2; k++) s[k]->AddPoint(dist,x[k]);
178  }
179  else
180  lines.push_back(a_line(x0,x));
181  //record line for later output
182  for (int k = 0; k < 2; k++) x0[k]=x[k];
183  }
184  if (with_spline)
185  {
186  //number of points on interpolated polyline
187  double n_pt = (int)dist/step;
188  if (n_pt != 0)
189  {
190  double t = 0.;
191  //evaluate the spline
192  for (int j=0; j<2; j++)
193  x0[j] = s[j]->Evaluate(0.);
194  for (int j=1; j<n_pt; j++)
195  {
196  t+= step;
197  //evaluate the spline
198  for (int k=0; k<2; k++)
199  x[k] = s[k]->Evaluate(t);
200  a_line test(x0,x0);
201  //record line for later output
202  lines.push_back(a_line(x0,x));
203  for (int k=0; k<2; k++)
204  x0[k] = x[k];
205  }
206  }
207  for (int j = 0; j < 2; j++) s[j]->Delete();
208  }
209  }
210  //output all the lines
211  std::cout << lines.size() << std::endl;
212  for(std::list<a_line>::iterator li=lines.begin(); li != lines.end(); ++li)
213  std::cout << (*li);
214  return 0;
215 }
Definition: im2li.cxx:46
friend std::ostream & operator<<(std::ostream &o, const a_line &l)
Definition: im2li.cxx:64
double x0_[2]
Definition: im2li.cxx:51
double x_[2]
Definition: im2li.cxx:52
a_line(double *x0, double *x)
Definition: im2li.cxx:55
bool verbose
Definition: h_compute.cxx:40
int error(int val)
Definition: im2li.cxx:70
double round(double val)
Definition: im2li.cxx:76
CSimpleOpt::SOption g_rgOptions[]
Definition: im2li.cxx:32
int main(int argc, char **argv)
Definition: im2li.cxx:81
std::ostream & operator<<(std::ostream &o, const a_line &l)
Definition: im2li.cxx:64
@ OPT_SPLINE
Definition: im2li.cxx:30
@ OPT_VERBOSE
Definition: im2li.cxx:30
@ OPT_HELP
Definition: im2li.cxx:30
@ OPT_SIGMA
Definition: im2li.cxx:30
int n_pt
Definition: ply2tri.cxx:33
std::istringstream in
Definition: ply2tri.cxx:32