MEPP2 Project
just_noticeable_distortion.hpp
Go to the documentation of this file.
1 // Copyright (c) 2012-2019 University of Lyon and CNRS (France).
2 // All rights reserved.
3 //
4 // This file is part of MEPP2; you can redistribute it and/or modify
5 // it under the terms of the GNU Lesser General Public License as
6 // published by the Free Software Foundation; either version 3 of
7 // the License, or (at your option) any later version.
8 //
9 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
10 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
11 #pragma once
12 
13 #include <time.h>
14 #include <boost/foreach.hpp>
15 
23 
28 
29 //---------------------------------------------------------
30 // Filter definition
31 //---------------------------------------------------------
32 
33 namespace FEVV {
34 namespace Filters {
35 
40 template< typename HalfedgeGraph,
41  typename PointMap,
42  typename GeometryTraits,
43  typename FaceNormalMap,
44  typename HalfEdge,
45  typename CamType,
46  typename LightType,
47  typename DirType >
48 double
49 compute_visibility(const GeometryTraits &geom,
50  const PointMap &point_map,
51  const HalfedgeGraph &mesh,
52  const FaceNormalMap &f_nm,
53  const HalfEdge &halfedge,
54  const DirType &displacement,
55  const LightType &light,
56  const CamType &cam,
57  const ScreenParam &screen,
58  const UserParam &user,
59  const SceneParam &scene,
60  const NWHWD16_Threshold &threshold,
61  bool both_faces_move = true)
62 {
63  if(face(halfedge, mesh) ==
64  boost::graph_traits< HalfedgeGraph >::null_face() ||
65  face(opposite(halfedge, mesh), mesh) ==
66  boost::graph_traits< HalfedgeGraph >::null_face())
67  return 0.0;
68 
69  double init_contrast =
70  compute_flat_contrast(geom, light, mesh, f_nm, halfedge);
71  double init_frequency = compute_flat_frequency(
72  cam, point_map, mesh, geom, halfedge, screen, user, scene);
73 
74  double visibility = 0.0;
75  typename GeometryTraits::Vector n1;
76  typename GeometryTraits::Vector n2;
77  double new_contrast;
78  double new_frequency;
79  if(both_faces_move)
80  {
81  /*
82  3 - - 2
83  \ | \
84  \ | \
85  1 - - 4
86  1 is moving
87  */
88  auto v1 =
89  get(point_map, source(halfedge, mesh)); // the vertex that is moving
90  auto v2 = get(point_map, target(halfedge, mesh));
91  auto v3 = get(point_map, target(next(halfedge, mesh), mesh));
92  auto v4 =
93  get(point_map, target(next(opposite(halfedge, mesh), mesh), mesh));
94 
95  typename GeometryTraits::Point p1(
96  geom.get_x(v1), geom.get_y(v1), geom.get_z(v1));
97  typename GeometryTraits::Point p2(
98  geom.get_x(v2), geom.get_y(v2), geom.get_z(v2));
99  typename GeometryTraits::Point p3(
100  geom.get_x(v3), geom.get_y(v3), geom.get_z(v3));
101  typename GeometryTraits::Point p4(
102  geom.get_x(v4), geom.get_y(v4), geom.get_z(v4));
103  typename GeometryTraits::Vector _v3(
104  geom.get_x(v3), geom.get_y(v3), geom.get_z(v3));
105  typename GeometryTraits::Vector _v4(
106  geom.get_x(v4), geom.get_y(v4), geom.get_z(v4));
107 
108  n1 = geom.unit_normal(p1 + displacement, p2, p3);
109  n2 = geom.unit_normal(p1 + displacement, p4, p2);
110 
111  new_contrast = compute_flat_contrast(geom, n1, n2, light);
112  new_frequency =
113  compute_flat_frequency(cam, _v3, _v4, geom, screen, user, scene);
114  }
115  else
116  {
117  /*
118  1 - - 2
119  \ | \
120  \ | \
121  3 - - 4
122  1 is moving
123  */
124  auto v1 = get(point_map, target(next(halfedge, mesh), mesh));
125  auto v2 = get(point_map, source(halfedge, mesh));
126  auto v3 = get(point_map, target(halfedge, mesh));
127  auto v4 =
128  get(point_map, target(next(opposite(halfedge, mesh), mesh), mesh));
129 
130  typename GeometryTraits::Point p1(
131  geom.get_x(v1), geom.get_y(v1), geom.get_z(v1));
132  typename GeometryTraits::Point p2(
133  geom.get_x(v2), geom.get_y(v2), geom.get_z(v2));
134  typename GeometryTraits::Point p3(
135  geom.get_x(v3), geom.get_y(v3), geom.get_z(v3));
136  typename GeometryTraits::Point p4(
137  geom.get_x(v4), geom.get_y(v4), geom.get_z(v4));
138  typename GeometryTraits::Vector _v1(
139  geom.get_x(v1), geom.get_y(v1), geom.get_z(v1));
140  typename GeometryTraits::Vector _v4(
141  geom.get_x(v4), geom.get_y(v4), geom.get_z(v4));
142 
143  n1 = geom.unit_normal(p2, p3, p1 + displacement);
144  n2 = geom.unit_normal(p2, p4, p3);
145 
146  new_contrast = compute_flat_contrast(geom, n1, n2, light);
147  new_frequency = compute_flat_frequency(
148  cam, _v1 + displacement, _v4, geom, screen, user, scene);
149  }
150 
151 
152  double T1 = threshold(NWHWD16_Threshold::InputType(
153  init_contrast, std::max(.1, init_frequency)));
154  double T2 = threshold(
155  NWHWD16_Threshold::InputType(init_contrast, std::max(.1, new_frequency)));
156 
157  VisibilityModel visibility_m;
158 
159  bool is_ambigous = !(new_contrast < 0.) != !(init_contrast < 0.);
160 
161  double dc = is_ambigous ? fabs(init_contrast) + fabs(new_contrast)
162  : fabs(init_contrast - new_contrast);
163 
164  visibility = std::max(visibility_m(VisibilityModel::InputType(dc, T1)),
165  visibility_m(VisibilityModel::InputType(dc, T2)));
166 
167  return visibility;
168 }
169 
173 template< typename HalfedgeGraph,
174  typename PointMap,
175  typename GeometryTraits,
176  typename FaceNormalMap,
177  typename VertexType,
178  typename CamType,
179  typename LightType,
180  typename DirType >
181 double
182 compute_threshold(const GeometryTraits &geom,
183  const PointMap &point_map,
184  const HalfedgeGraph &mesh,
185  const FaceNormalMap &f_nm,
186  const VertexType &vertex,
187  const DirType &dir,
188  const LightType &light,
189  const CamType &cam,
190  const ScreenParam &screen,
191  const UserParam &user,
192  const SceneParam &scene,
193  const NWHWD16_Threshold &threshold,
194  double max_displacement)
195 {
196  double tolerence = 0.80;
197  double precision = 0.1;
198  double int_width = 1.e-8;
199 
200  double a = 0.0;
201  double b = max_displacement;
202 
203  double T = b;
204  double visibility = 0.0;
205 
206  auto h0 = next(halfedge(vertex, mesh), mesh);
207  auto h = h0;
208 
209  // Computation of visibility for the maximum displacement
210  do
211  {
212  double visibility_b = 0.0;
213  if(face(h, mesh) != boost::graph_traits< HalfedgeGraph >::null_face())
214  visibility_b = compute_visibility(geom,
215  point_map,
216  mesh,
217  f_nm,
218  h,
219  geom.scalar_mult(dir, T),
220  light,
221  cam,
222  screen,
223  user,
224  scene,
225  threshold,
226  true);
227  visibility = std::max(visibility, visibility_b);
228  if(visibility >= 1.0)
229  break;
230  if(face(next(h, mesh), mesh) !=
231  boost::graph_traits< HalfedgeGraph >::null_face())
232  visibility_b = compute_visibility(geom,
233  point_map,
234  mesh,
235  f_nm,
236  next(h, mesh),
237  geom.scalar_mult(dir, T),
238  light,
239  cam,
240  screen,
241  user,
242  scene,
243  threshold,
244  false);
245  visibility = std::max(visibility, visibility_b);
246  if(visibility >= 1.0)
247  break;
248  h = next(opposite(h, mesh), mesh);
249  } while(h0 != h);
250 
251  // Computation of the visibility until the tolerence is met
252  while(fabs(visibility - tolerence) > precision)
253  {
254  T = (b + a) * 0.5;
255  visibility = 0.0;
256  h = h0;
257  do
258  {
259  double visibility_b = 0.0;
260  if(face(h, mesh) != boost::graph_traits< HalfedgeGraph >::null_face())
261  visibility_b = compute_visibility(geom,
262  point_map,
263  mesh,
264  f_nm,
265  h,
266  geom.scalar_mult(dir, T),
267  light,
268  cam,
269  screen,
270  user,
271  scene,
272  threshold,
273  true);
274  visibility = std::max(visibility, visibility_b);
275  if(visibility >= 1.0)
276  break;
277  if(face(next(h, mesh), mesh) !=
278  boost::graph_traits< HalfedgeGraph >::null_face())
279  visibility_b = compute_visibility(geom,
280  point_map,
281  mesh,
282  f_nm,
283  next(h, mesh),
284  geom.scalar_mult(dir, T),
285  light,
286  cam,
287  screen,
288  user,
289  scene,
290  threshold,
291  false);
292  visibility = std::max(visibility, visibility_b);
293  if(visibility >= 1.0)
294  break;
295  h = next(opposite(h, mesh), mesh);
296  } while(h0 != h);
297 
298  if(visibility > tolerence)
299  b = T;
300  else
301  a = T;
302 
303  if((b - a) < int_width)
304  break;
305  }
306 
307  return T;
308 }
309 
310 
329 template< typename HalfedgeGraph,
330  typename PointMap,
331  typename VertexNormalMap,
332  typename GeometryTraits = FEVV::Geometry_traits< HalfedgeGraph >,
333  typename FaceNormalMap,
334  typename JNDMap >
335 void
336 just_noticeable_distortion_filter(const HalfedgeGraph &halfedge_graph,
337  PointMap &point_map,
338  const VertexNormalMap &vertex_normal_map,
339  const GeometryTraits &geometry_traits,
340  const FaceNormalMap &face_normal_map,
341  JNDMap &jnd_map,
342  const ScreenParam &screen,
343  const UserParam &user,
344  const SceneParam &scene,
345  const int nb_light_sources,
346  bool data_output = false,
347  bool use_random = true)
348 {
349  typedef boost::graph_traits< HalfedgeGraph > GraphTraits;
350  //typedef typename GraphTraits::vertex_iterator vertex_iterator;
352  //typedef typename GraphTraits::face_descriptor face_descriptor;
353  typedef typename GraphTraits::halfedge_descriptor halfedge_descriptor;
354  //typedef typename GraphTraits::face_iterator face_iterator;
355  typedef typename boost::property_traits< VertexNormalMap >::value_type Normal;
356  //typedef
357  // typename boost::property_traits< FaceNormalMap >::value_type FaceNormal;
358 
359  int counter = 0;
360 
361  // Preparation of the model defined in G. Nader thesis
362  SarkisonCSF csf(SarkisonCSF::ParameterType(-15.13, 0.0096, 0.64));
363  DalyMasking masking(DalyMasking::ParameterType(0.0078, 88.29, 1.0, 4.207));
364 
365  NWHWD16_Threshold threshold;
366  threshold.param().csf = csf;
367  threshold.param().masking = masking;
368 
369  // Computation of the bounding box of the mesh
370  typename boost::property_traits< PointMap >::value_type minAABB, maxAABB;
371  Filters::compute_mesh_bounding_box< HalfedgeGraph, PointMap, GeometryTraits >(
372  halfedge_graph, point_map, minAABB, maxAABB, geometry_traits);
373 
374  typename GeometryTraits::Vector minbb(geometry_traits.get_x(minAABB),
375  geometry_traits.get_y(minAABB),
376  geometry_traits.get_z(minAABB));
377  typename GeometryTraits::Vector maxbb(geometry_traits.get_x(maxAABB),
378  geometry_traits.get_y(maxAABB),
379  geometry_traits.get_z(maxAABB));
380 
381  typename GeometryTraits::Vector bbox_c = (maxbb + minbb) * 0.5;
382  double bbox_diag_len = geometry_traits.length(maxbb - minbb);
383 
384  // Creation of a camera position (should be externalized later)
385  typename GeometryTraits::Vector cam =
386  geometry_traits.add_v(bbox_c,
387  geometry_traits.scalar_mult(typename GeometryTraits::Vector(0., 0., 1.0),
388  bbox_diag_len)
389  ) ;
390 #ifndef FEVV_USE_AIF
391  if(data_output)
392  std::cout << "Cam:" << cam << std::endl;
393 #endif
394 
395  LightSampler lsampler;
396  Eigen::MatrixX3d lights;
397 
398  // preparation of some metrics for avancement
399  int avance = 0;
400  int mesh_size = static_cast< int >(size_of_vertices(halfedge_graph));
401  int step = mesh_size * nb_light_sources < 120000 ? 10 : 1;
402 
403  clock_t start = clock();
404 
405  BOOST_FOREACH(vertex_descriptor vi, vertices(halfedge_graph))
406  {
407  // Display of estimated computation time and advancement of computation
408  if(!data_output && (counter > (avance + step) * (mesh_size / 100)))
409  {
410  if(avance == 0)
411  {
412  double estimated_time =
413  static_cast< double >(clock() - start) /
414  (static_cast< double >(CLOCKS_PER_SEC * 100) / step);
415  std::cout << "Estimated time of computation : " << estimated_time
416  << " s for " << mesh_size << " vertices." << std::endl;
417  }
418  avance += step;
419  std::cout << "Progression: " << avance << "%\r" << std::flush;
420  }
421  counter++;
422 
423 
424  Normal n = get(vertex_normal_map, vi);
425 
426  halfedge_descriptor h0 = next(halfedge(vi, halfedge_graph), halfedge_graph);
427  halfedge_descriptor h = h0;
428 
429 #ifndef FEVV_USE_AIF
430  typedef typename boost::property_traits< PointMap >::value_type Point;
431 
432  if(data_output)
433  {
434  Point p = get(point_map, vi);
435  std::cout << "processing vertex #" << counter << " : "
436  << geometry_traits.get_x(p) << " " << geometry_traits.get_y(p)
437  << " " << geometry_traits.get_z(p) << std::endl;
438  std::cout << "\tnormal :" << n[0] << " " << n[1] << " " << n[2]
439  << std::endl;
440  }
441 #endif
442 
443  Eigen::Vector3d p_n(n[0], n[1], n[2]);
444  double jnd = 0.0;
445 
446  // Computation of average angle between vertex normal and adjacent faces
447  // normals
448  double avg_angle = 0.0;
449  double valence = 0.0;
450  do
451  {
452  if(face(h, halfedge_graph) !=
453  boost::graph_traits< HalfedgeGraph >::null_face())
454  {
455  auto face_normal = get(face_normal_map, face(h, halfedge_graph));
456  Eigen::Vector3d f_n(face_normal[0], face_normal[1], face_normal[2]);
457  valence += 1.0;
458  avg_angle += std::acos(p_n.normalized().dot(f_n.normalized()));
459  }
460  h = next(opposite(h, halfedge_graph), halfedge_graph);
461  } while(h0 != h);
462 
463  avg_angle = avg_angle / valence;
464  avg_angle =
465  (avg_angle != avg_angle)
466  ? M_PI_4 * 0.5
467  : M_PI_2 - avg_angle; // (avg_angle != avg_angle) instead of isnan
468 
469 #ifndef FEVV_USE_AIF
470  if(data_output)
471  std::cout << "\tMean angle: " << avg_angle << std::endl;
472 #endif
473  // Creation of random light sources around the vertex
474  lsampler.sample_to_global(lights,
475  nb_light_sources,
476  p_n,
477  0.80 * avg_angle,
478  0.85 * avg_angle,
479  use_random);
480 
481  // initialization of threshold at 10% of the bounding box size
482  VectorXd T;
483  T.resize(lights.rows());
484  T.setConstant(0.1 * bbox_diag_len);
485 
486  int count = 0;
487  for(unsigned int i = 0; i < lights.rows(); ++i)
488  {
489  typename GeometryTraits::Vector light(
490  lights.row(i)[0], lights.row(i)[1], lights.row(i)[2]);
491  if(geometry_traits.dot_product(light, n) > 0.)
492  {
493  count++;
494  T(i) = compute_threshold(geometry_traits,
495  point_map,
496  halfedge_graph,
497  face_normal_map,
498  vi,
499  n,
500  light,
501  cam,
502  screen,
503  user,
504  scene,
505  threshold,
506  0.1 * bbox_diag_len);
507 #ifndef FEVV_USE_AIF
508  if(data_output)
509  std::cout << "\t" << light << " -> " << T(i) << std::endl;
510 #endif
511  }
512  }
513 
514 #ifndef FEVV_USE_AIF
515  if(data_output)
516  std::cout << "\tUsed lights :" << count << std::endl;
517 #endif
518 
519  // if no lights were useable to compute the JND set it to 0
520  // in the other case keep the lowest threshold
521  if(count != 0)
522  jnd = T.minCoeff();
523 
524  if(jnd != jnd) // instead of isnan
525  jnd = 0.0;
526 
527  put(jnd_map, vi, jnd);
528  }
529  clock_t end = clock();
530  std::cout << "Average jnd computing time : "
531  << static_cast< double >(end - start) /
532  static_cast< double >(CLOCKS_PER_SEC * counter)
533  << " s/vertex" << std::endl;
534 }
535 
536 
551 template< typename HalfedgeGraph,
552  typename PointMap,
553  typename VertexNormalMap,
554  typename GeometryTraits = FEVV::Geometry_traits< HalfedgeGraph >,
555  typename FaceNormalMap,
556  typename JNDMap >
557 void
558 just_noticeable_distortion_filter(const HalfedgeGraph &g,
559  PointMap &pm,
560  const VertexNormalMap &v_nm,
561  const FaceNormalMap &f_nm,
562  JNDMap &jnd_m,
563  const ScreenParam &screen,
564  const UserParam &user,
565  const SceneParam &scene,
566  const int lights = 128,
567  bool data_output = false,
568  bool use_random = true)
569 {
570  GeometryTraits gt(g);
572  pm,
573  v_nm,
574  gt,
575  f_nm,
576  jnd_m,
577  screen,
578  user,
579  scene,
580  lights,
581  data_output,
582  use_random);
583 }
584 } // namespace Filters
585 } // namespace FEVV
flatcontrastcomputor.h
FEVV::DataStructures::AIF::vertices
std::pair< typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_iterator, typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_iterator > vertices(const FEVV::DataStructures::AIF::AIFMesh &sm)
Returns the iterator range of the vertices of the mesh.
Definition: Graph_traits_aif.h:172
FEVV::DataStructures::AIF::next
boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::halfedge_descriptor next(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::halfedge_descriptor h, const FEVV::DataStructures::AIF::AIFMesh &sm)
Returns the next halfedge around its face.
Definition: Graph_traits_aif.h:599
Vector
AIFMesh::Vector Vector
Definition: Graph_properties_aif.h:22
compute_flat_frequency
double compute_flat_frequency(const Cam_t &cam, const Point_t &p1, const Point_t &p2, const GeometryTraits &geom_t, const ScreenParam &screen, const UserParam &user, const SceneParam &scene)
Definition: flatfrequencycomputor.hpp:64
threshold.h
UserParam
The parameters of the user.
Definition: types.h:43
genericparametricmodel.h
types.h
LightType
Eigen::Vector3d LightType
Definition: types.h:18
visibility.h
GenericParametricModel< NWHWD16_Param, Eigen::Vector2d, double >::InputType
Eigen::Vector2d InputType
Definition: genericparametricmodel.h:24
ScreenParam
The parameters of the screen.
Definition: types.h:27
LightSampler
Definition: lightsampler.hpp:20
GenericParametricModel< Eigen::Vector3d, double, double >::ParameterType
Eigen::Vector3d ParameterType
Definition: genericparametricmodel.h:23
SceneParam
The parameters of the scene.
Definition: types.h:55
NWHWD16_Threshold
Definition: threshold.h:38
FEVV::Filters::compute_visibility
double compute_visibility(const GeometryTraits &geom, const PointMap &point_map, const HalfedgeGraph &mesh, const FaceNormalMap &f_nm, const HalfEdge &halfedge, const DirType &displacement, const LightType &light, const CamType &cam, const ScreenParam &screen, const UserParam &user, const SceneParam &scene, const NWHWD16_Threshold &threshold, bool both_faces_move=true)
Compute the visibility of the movement of an halfedge, given a light source and the displacement.
Definition: just_noticeable_distortion.hpp:49
FEVV::DataStructures::AIF::opposite
boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::halfedge_descriptor opposite(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::halfedge_descriptor h, const FEVV::DataStructures::AIF::AIFMesh &sm)
Returns the halfedge with source and target swapped.
Definition: Graph_traits_aif.h:625
FEVV::Geometry_traits< HalfedgeGraph >
Point
AIFMesh::Point Point
Definition: Graph_properties_aif.h:21
GenericParametricModel::param
const ParameterType & param() const
Definition: genericparametricmodel.h:44
contrastsensitivity.h
FEVV::DataStructures::AIF::source
boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_descriptor source(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::edge_descriptor e, const FEVV::DataStructures::AIF::AIFMesh &)
Returns the source vertex of e.
Definition: Graph_traits_aif.h:387
NWHWD16_Param::masking
DalyMasking masking
Definition: threshold.h:23
flatfrequencycomputor.hpp
SarkisonCSF
Definition: contrastsensitivity.h:27
lightsampler.hpp
FEVV::get
FEVV::PCLPointCloudPointMap::value_type get(const FEVV::PCLPointCloudPointMap &pm, FEVV::PCLPointCloudPointMap::key_type key)
Specialization of get(point_map, key) for PCLPointCloud.
Definition: Graph_properties_pcl_point_cloud.h:117
FEVV
Interfaces for plugins These interfaces will be used for different plugins.
Definition: Assert.h:16
VisibilityModel
Definition: visibility.h:32
compute_mesh_bounding_box.hpp
FEVV::DataStructures::AIF::halfedge
boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::halfedge_descriptor halfedge(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_descriptor v, const FEVV::DataStructures::AIF::AIFMesh &sm)
Returns a halfedge with target v.
Definition: Graph_traits_aif.h:296
FEVV::DataStructures::AIF::target
boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_descriptor target(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::edge_descriptor e, const FEVV::DataStructures::AIF::AIFMesh &)
Returns the target vertex of e.
Definition: Graph_traits_aif.h:400
FEVV::Operators::Geometry::acos
T acos(T cosine)
Safe call to the std::acos function.
Definition: AngleOperations.hpp:64
CamType
Eigen::Vector3d CamType
Definition: types.h:19
NWHWD16_Param::csf
SarkisonCSF csf
Definition: threshold.h:22
LightSampler::sample_to_global
void sample_to_global(MatrixX3d &samples, int n, const Vector3d &up=Vector3d::UnitZ(), double phi_min=0., double phi_max=M_PI, bool use_random=true, Method method=NAIVE) const
Definition: lightsampler.inl:32
msdm2::vertex_descriptor
boost::graph_traits< MeshT >::vertex_descriptor vertex_descriptor
Definition: msdm2_surfacemesh.h:33
FEVV::Filters::fabs
double fabs(const v_Curv< HalfedgeGraph > &input)
Definition: curvature.hpp:54
FEVV::put
void put(FEVV::PCLPointCloudPointMap &pm, FEVV::PCLPointCloudPointMap::key_type key, const FEVV::PCLPointCloudPointMap::value_type &value)
Specialization of put(point_map, key, value) for PCLPointCloud.
Definition: Graph_properties_pcl_point_cloud.h:126
FEVV::DataStructures::AIF::face
boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::face_descriptor face(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::halfedge_descriptor h, const FEVV::DataStructures::AIF::AIFMesh &)
Returns the face incident to halfedge h.
Definition: Graph_traits_aif.h:664
psychometricfunction.h
FEVV::Filters::just_noticeable_distortion_filter
void just_noticeable_distortion_filter(const HalfedgeGraph &halfedge_graph, PointMap &point_map, const VertexNormalMap &vertex_normal_map, const GeometryTraits &geometry_traits, const FaceNormalMap &face_normal_map, JNDMap &jnd_map, const ScreenParam &screen, const UserParam &user, const SceneParam &scene, const int nb_light_sources, bool data_output=false, bool use_random=true)
Computes the Just Noticeable Distortion metric.
Definition: just_noticeable_distortion.hpp:336
contrastmasking.h
FEVV::DataStructures::AIF::AIFVector::length
CoordinateType length(void) const
Definition: AIFProperties.h:208
FEVV::size_of_vertices
boost::graph_traits< MeshT >::vertices_size_type size_of_vertices(const MeshT &g)
Real current number of vertices of the mesh. Generic version.
Definition: Graph_traits_extension.h:29
FEVV::Filters::compute_threshold
double compute_threshold(const GeometryTraits &geom, const PointMap &point_map, const HalfedgeGraph &mesh, const FaceNormalMap &f_nm, const VertexType &vertex, const DirType &dir, const LightType &light, const CamType &cam, const ScreenParam &screen, const UserParam &user, const SceneParam &scene, const NWHWD16_Threshold &threshold, double max_displacement)
Compute the JND value for a vertex, using a given light.
Definition: just_noticeable_distortion.hpp:182
compute_flat_contrast
double compute_flat_contrast(const GeometryTraits &geom, const Vector_t &n1, const Vector_t &n2, const Vector_t &ldir)
Definition: flatcontrastcomputor.h:19
DalyMasking
Definition: contrastmasking.h:30
FEVV::DataStructures::AIF::AIFPoint
Definition: AIFProperties.h:31
FEVV::face_normal
@ face_normal
Definition: properties.h:77