84 #include <DGtal/base/Common.h>
85 #include <DGtal/helpers/StdDefs.h>
86 #include <boost/program_options/options_description.hpp>
87 #include <boost/program_options/positional_options.hpp>
88 #include <boost/program_options/variables_map.hpp>
89 #include <boost/program_options/parsers.hpp>
90 #include <boost/program_options/errors.hpp>
91 #include <DGtal/images/ImageSelector.h>
92 #include <DGtal/io/readers/GenericReader.h>
96 #include "volSurfaceRegularization-details/surface_approx.h"
97 #include "volSurfaceRegularization-details/surface_extract.h"
98 #include "volSurfaceRegularization-details/shape.h"
104 std::string image_filename;
105 double normal_radius;
106 double regularization_position;
107 double regularization_center;
111 std::string regularized_obj_filename;
112 std::string cubical_obj_filename;
116 parse_options(
int argc,
char* argv[])
118 namespace po = boost::program_options;
124 po::options_description po_shape(
"File options");
125 po_shape.add_options()
126 (
"image-filename,i", po::value<std::string>(&options.image_filename)->default_value(
""),
"input vol filename for image shape (object voxels have values > 0) or input cvs filename for surfels and normals")
127 (
"regularized-obj-filename,o", po::value<std::string>(&options.regularized_obj_filename)->default_value(
""),
"output regularized obj")
128 (
"cubical-obj-filename,n", po::value<std::string>(&options.cubical_obj_filename)->default_value(
""),
"output cubical obj")
129 (
"shape-noise,k", po::value<double>(&options.noise_level)->default_value(0),
"noise shape parameter")
132 po::options_description po_normal(
"Normal field estimator options");
133 po_normal.add_options()
134 (
"normal-radius,r", po::value<double>(&options.normal_radius)->default_value(4),
"radius of normal estimator")
137 po::options_description po_approx(
"Surface approximation options");
138 po_approx.add_options()
139 (
"regularization-position,p", po::value<double>(&options.regularization_position)->default_value(1e-3,
"1e-3"),
"vertex position regularization coeff")
140 (
"regularization-center,c", po::value<double>(&options.regularization_center)->default_value(1e-2,
"1e-2"),
"face center regularization coeff")
141 (
"align,a", po::value<double>(&options.align)->default_value(1),
"normal alignment coeff")
142 (
"fairness,f", po::value<double>(&options.fairness)->default_value(0),
"face fairness coeff")
143 (
"barycenter,b", po::value<double>(&options.barycenter)->default_value(1e-1,
"1e-1"),
"barycenter fairness coeff")
146 po::options_description po_options(
"surfaceApprox [options]");
147 po_options.add(po_shape).add(po_normal).add(po_approx).add_options()
148 (
"help,h",
"display this message")
151 po::positional_options_description positional;
152 positional.add(
"image-filename",1);
153 positional.add(
"regularized-obj-filename",1);
157 po::variables_map vm;
158 po::store(po::command_line_parser(argc, argv).options(po_options).positional(positional).run(), vm);
161 if (vm.count(
"help"))
167 if (options.image_filename.empty())
throw po::validation_error(po::validation_error::invalid_option_value);
168 if (options.regularized_obj_filename.empty())
throw po::validation_error(po::validation_error::invalid_option_value);
170 catch (std::exception& ex)
181 int main(
int argc,
char* argv[])
188 const Options options = parse_options(argc, argv);
193 const FlatVector original_face_normals;
195 if (!ends_with(options.image_filename,
".csv"))
197 ASSERT( !options.image_filename.empty() );
200 trace.
info() <<
"image_filename=" << options.image_filename << endl;
202 const Domain domain = image_uchar.domain();
203 trace.
info() <<
"domain=" << domain << endl;
204 const Point center = (domain.upperBound()+domain.lowerBound())/2;
205 trace.
info() <<
"center=" << center << endl;
208 const_cast<KSpace&
>(kspace).init(domain.lowerBound()-center-Point::diagonal(1), domain.upperBound()-center+Point::diagonal(1),
true);
210 std::tie(const_cast<Calculus&>(calculus), const_cast<FlatVector&>(original_face_normals)) =
211 initCalculusAndNormalsWithNoise(kspace, shape, options.normal_radius, options.noise_level);
214 if (ends_with(options.image_filename,
".csv"))
216 ASSERT( !options.image_filename.empty() );
217 trace.
info() <<
"csv_filename=" << options.image_filename << endl;
218 std::tie(const_cast<Calculus&>(calculus), const_cast<FlatVector&>(original_face_normals)) =
219 initCalculusAndNormalsFromSurfelNormalsCSV(options.image_filename);
222 const FlatVector original_vertex_normals = vertexNormals(calculus, original_face_normals);
224 const FlatVector original_positions;
225 const FlatVector regularized_positions;
226 const FlatVector original_centers;
227 const FlatVector regularized_centers;
228 std::tie(const_cast<FlatVector&>(original_positions),
229 const_cast<FlatVector&>(regularized_positions),
230 const_cast<FlatVector&>(original_centers),
231 const_cast<FlatVector&>(regularized_centers)) =
232 approximateSurface(calculus, original_face_normals,
233 ApproxParams({options.regularization_position, options.regularization_center, options.align, options.fairness, options.barycenter}));
234 ASSERT( original_positions.size() == 3*calculus.
kFormLength(0, PRIMAL) );
235 ASSERT( regularized_positions.size() == 3*calculus.
kFormLength(0, PRIMAL) );
236 ASSERT( original_centers.size() == 3*calculus.
kFormLength(2, PRIMAL) );
237 ASSERT( regularized_centers.size() == 3*calculus.
kFormLength(2, PRIMAL) );
243 double position_energy = 0;
244 double align_energy = 0;
245 std::tie( position_energy, align_energy ) = approximateSurfaceEnergies(
246 calculus, original_face_normals, original_positions );
247 align_energy *= options.align;
248 position_energy *= options.regularization_position;
249 trace.
info() <<
"original_energies=" << position_energy <<
" "
250 << align_energy <<
" " << position_energy + align_energy
255 double position_energy = 0;
256 double align_energy = 0;
257 std::tie(position_energy, align_energy) = approximateSurfaceEnergies(calculus, original_face_normals, regularized_positions);
258 align_energy *= options.align;
259 position_energy *= options.regularization_position;
260 trace.
info() <<
"regularized_energies=" << position_energy <<
" " << align_energy <<
" " << position_energy+align_energy << endl;
267 ASSERT( !options.regularized_obj_filename.empty() );
268 trace.
info() <<
"regularized_obj_filename=" << options.regularized_obj_filename << endl;
269 exportOBJ(calculus, regularized_positions, options.regularized_obj_filename);
272 if (!options.cubical_obj_filename.empty())
274 ASSERT( !options.cubical_obj_filename.empty() );
275 trace.
info() <<
"cubical_obj_filename=" << options.cubical_obj_filename << endl;
276 exportOBJ(calculus, original_positions, options.cubical_obj_filename);
void beginBlock(const std::string &keyword="")
static TContainer import(const std::string &filename, std::vector< unsigned int > dimSpace=std::vector< unsigned int >())
Trace trace(traceWriterTerm)
typename Self::Point Point
Index kFormLength(const Order &order, const Duality &duality) const
typename Self::Domain Domain