bool testRaySurface()
{
  typedef ImplicitBall<Z3i::Space> ImplicitShape;
  typedef GaussDigitizer<Z3i::Space, ImplicitShape> DigitalShape;
  typedef LightImplicitDigitalSurface<Z3i::KSpace,DigitalShape> Boundary;
  typedef DigitalSurface< Boundary > MyDigitalSurface;
  trace.beginBlock(" Ray shooting in digital surface");
  trace.beginBlock( "Shape initialisation ..." );
  ImplicitShape ishape( Z3i::RealPoint( 0, 0 ,0), 12 );
  DigitalShape dshape;
  dshape.attach( ishape );
  dshape.init( Z3i::RealPoint( -20.0, -20.0 ,-20.0 ), Z3i::RealPoint( 20.0, 20.0, 20.0  ), 1.0 );
  Z3i::KSpace K;
  if ( !K.init( dshape.getLowerBound(), dshape.getUpperBound(), true ) )
  {
    trace.error() << "Problem with Khalimsky space init" << std::endl;
    return false;
  }

  Z3i::KSpace::Surfel bel = Surfaces<Z3i::KSpace>::findABel( K, dshape, 10000 );
  Boundary boundary( K, dshape, SurfelAdjacency<Z3i::KSpace::dimension>( true ), bel );
  MyDigitalSurface surf ( boundary );
  trace.endBlock();


  trace.beginBlock(" Ray shooting the shape");
  
  RayIntersectionPredicate<Z3i::KSpace::Cell::Point> ray(Z3i::KSpace::Cell::Point(0,0,0),
                                                         Z3i::KSpace::Cell::Point(2,2,2));

  RayIntersectionPredicate<Z3i::KSpace::Cell::Point> ray2(Z3i::KSpace::Cell::Point(0,0,0),
                                                          Z3i::KSpace::Cell::Point(1,0,0));

  MyDigitalSurface::ConstIterator it = std::find_if(surf.begin(), surf.end(), ray); 
  trace.info() << "Ray shooting returns : "<< *it<<std::endl;

  MyDigitalSurface::ConstIterator it2 = std::find_if(surf.begin(), surf.end(), ray2); 
  trace.info() << "Ray shooting returns : "<< *it2<<std::endl;
  
  trace.endBlock();
  trace.endBlock();

  return true;
}
/**
 * Example of a test. To be completed.
 *
 */
bool testLocalConvolutionNormalVectorEstimator ( int /*argc*/, char**/*argv*/ )
{
    unsigned int nbok = 0;
    unsigned int nb = 0;

    trace.beginBlock ( "Testing convolution neighborhood ..." );

    std::string filename = testPath + "samples/cat10.vol";

    typedef ImageSelector < Z3i::Domain, int>::Type Image;
    Image image = VolReader<Image>::importVol ( filename );
    trace.info() <<image<<std::endl;
    DigitalSet set3d ( image.domain() );
    SetFromImage<DigitalSet>::append<Image> ( set3d, image,
            0,256 );

    KSpace ks;
    bool space_ok = ks.init ( image.domain().lowerBound(),
                              image.domain().upperBound(), true );
    if ( !space_ok )
    {
        trace.error() << "Error in the Khamisky space construction."<<std::endl;
        return 2;
    }
    trace.endBlock();
    typedef SurfelAdjacency<KSpace::dimension> MySurfelAdjacency;
    MySurfelAdjacency surfAdj ( true ); // interior in all directions.

    trace.beginBlock ( "Set up digital surface." );
    typedef LightImplicitDigitalSurface<KSpace, DigitalSet >
      MyDigitalSurfaceContainer;
    typedef DigitalSurface<MyDigitalSurfaceContainer> MyDigitalSurface;
    SCell bel = Surfaces<KSpace>::findABel ( ks, set3d, 100000 );
    MyDigitalSurfaceContainer* ptrSurfContainer =
        new MyDigitalSurfaceContainer ( ks, set3d, surfAdj, bel );
    MyDigitalSurface digSurf ( ptrSurfContainer ); // acquired
    MyDigitalSurface::ConstIterator it = digSurf.begin();
    trace.endBlock();

    trace.beginBlock ( "Compute and output surface <cat10-constant.off> with trivial normals." );
    //Convolution kernel
    ConstantConvolutionWeights<MyDigitalSurface::Size> kernel;

    //Estimator definition
    typedef LocalConvolutionNormalVectorEstimator
    < MyDigitalSurface,
    ConstantConvolutionWeights<MyDigitalSurface::Size> > MyConstantEstimator;
    BOOST_CONCEPT_ASSERT ( ( CNormalVectorEstimator< MyConstantEstimator > ) );
    MyConstantEstimator myNormalEstimator ( digSurf, kernel );

    // Embedder definition
    typedef CanonicDigitalSurfaceEmbedder<MyDigitalSurface> SurfaceEmbedder;
    SurfaceEmbedder surfaceEmbedder ( digSurf );
    typedef DigitalSurfaceEmbedderWithNormalVectorEstimator
    < SurfaceEmbedder, MyConstantEstimator > SurfaceEmbedderWithTrivialNormal;
    SurfaceEmbedderWithTrivialNormal mySurfelEmbedder ( surfaceEmbedder,
            myNormalEstimator );

    // Compute normal vector field and displays it.
    myNormalEstimator.init ( 1.0, 2 );

    MyConstantEstimator::Quantity res = myNormalEstimator.eval ( it );
    trace.info() << "Normal vector at begin() : "<< res << std::endl;

    ofstream out ( "cat10-constant.off" );
    if ( out.good() )
        digSurf.exportAs3DNOFF ( out,mySurfelEmbedder );
    out.close();
    trace.endBlock();

    trace.beginBlock ( "Compute and output surface <cat10-gaussian.off> with gaussian convoluted normals." );

    //Convolution kernel
    GaussianConvolutionWeights < MyDigitalSurface::Size > Gkernel ( 4.0 );

    //Estimator definition
    typedef LocalConvolutionNormalVectorEstimator  < MyDigitalSurface,
            GaussianConvolutionWeights< MyDigitalSurface::Size>  > MyGaussianEstimator;
    BOOST_CONCEPT_ASSERT ( ( CNormalVectorEstimator< MyGaussianEstimator > ) );
    MyGaussianEstimator myNormalEstimatorG ( digSurf, Gkernel );

    // Embedder definition
    typedef DigitalSurfaceEmbedderWithNormalVectorEstimator<SurfaceEmbedder,MyGaussianEstimator> SurfaceEmbedderWithGaussianNormal;
    SurfaceEmbedderWithGaussianNormal mySurfelEmbedderG ( surfaceEmbedder, myNormalEstimatorG );

    // Compute normal vector field and displays it.
    myNormalEstimatorG.init ( 1.0, 5 );

    MyGaussianEstimator::Quantity res2 = myNormalEstimatorG.eval ( it );
    trace.info() << "Normal vector at begin() : "<< res2 << std::endl;
    std::vector<MyGaussianEstimator::Quantity> allNormals;
    myNormalEstimatorG.evalAll ( std::back_inserter ( allNormals ) );
    trace.info() << "Normal vector field of size "<< allNormals.size() << std::endl;

    ofstream out2 ( "cat10-gaussian.off" );
    if ( out2.good() )
        digSurf.exportAs3DNOFF ( out2 ,mySurfelEmbedderG );
    out2.close();

    nbok += true ? 1 : 0;
    nb++;
    trace.info() << "(" << nbok << "/" << nb << ") "
                 << "true == true" << std::endl;
    trace.endBlock();

    return true;
}
/**
 * Example of a test. To be completed.
 *
 */
bool testLocalConvolutionNormalVectorEstimator ( int argc, char**argv )
{
    unsigned int nbok = 0;
    unsigned int nb = 0;

    trace.beginBlock ( "Testing convolution neighborhood ..." );

    QApplication application ( argc,argv );
    DGtal::Viewer3D<> viewer;

    std::string filename = testPath + "samples/cat10.vol";

    typedef ImageSelector < Z3i::Domain, int>::Type Image;
    Image image = VolReader<Image>::importVol ( filename );
    trace.info() <<image<<std::endl;
    DigitalSet set3d ( image.domain() );
    SetFromImage<DigitalSet>::append<Image> ( set3d, image,
            0,256 );

    KSpace ks;
    bool space_ok = ks.init ( image.domain().lowerBound(),
                              image.domain().upperBound(), true );
    if ( !space_ok )
    {
        trace.error() << "Error in the Khamisky space construction."<<std::endl;
        return true; //2; (return a bool !!!)
    }
    trace.endBlock();
    typedef SurfelAdjacency<KSpace::dimension> MySurfelAdjacency;
    MySurfelAdjacency surfAdj ( true ); // interior in all directions.

    trace.beginBlock ( "Set up digital surface." );
    typedef LightImplicitDigitalSurface<KSpace, DigitalSet >
      MyDigitalSurfaceContainer;
    typedef DigitalSurface<MyDigitalSurfaceContainer> MyDigitalSurface;
    SCell bel = Surfaces<KSpace>::findABel ( ks, set3d, 100000 );
    MyDigitalSurfaceContainer* ptrSurfContainer =
        new MyDigitalSurfaceContainer ( ks, set3d, surfAdj, bel );
    MyDigitalSurface digSurf ( ptrSurfContainer ); // acquired

    MyDigitalSurface::ConstIterator it = digSurf.begin();


    //Convolution kernel
    deprecated::ConstantConvolutionWeights< MyDigitalSurface::Size > kernel;

    //Estimator definition
    typedef deprecated::LocalConvolutionNormalVectorEstimator<MyDigitalSurface,
                                                  deprecated::ConstantConvolutionWeights< MyDigitalSurface::Size > > MyEstimator;
    MyEstimator myNormalEstimator ( digSurf, kernel );

    myNormalEstimator.init ( 1.0, 5 );

    MyEstimator::Quantity res = myNormalEstimator.eval ( it );
    trace.info() << "Normal vector at begin() : "<< res << std::endl;

    viewer.show();

    DGtal::Color lineColorSave = viewer.getLineColor();
    viewer.setLineColor( DGtal::Color ( 200,20,20 ));
    for ( MyDigitalSurface::ConstIterator itbis = digSurf.begin(),itend=digSurf.end();
            itbis!=itend; ++itbis )
    {
        viewer << ks.unsigns ( *itbis );

        Point center = ks.sCoords ( *itbis );
        MyEstimator::Quantity normal = myNormalEstimator.eval ( itbis );

        viewer.addLine ( center,
                         DGtal::Z3i::RealPoint(center[0]-3*normal[0],
					       center[1]-3*normal[1],
					       center[2]-3*normal[2]) );
    }
    viewer.setLineColor( lineColorSave);
    viewer<< Viewer3D<>::updateDisplay;

    //Convolution kernel
    deprecated::GaussianConvolutionWeights< MyDigitalSurface::Size > Gkernel ( 14.0 );

    //Estimator definition
    typedef deprecated::LocalConvolutionNormalVectorEstimator<MyDigitalSurface,
                                                              deprecated::GaussianConvolutionWeights< MyDigitalSurface::Size > > MyEstimatorGaussian;
    MyEstimatorGaussian myNormalEstimatorG ( digSurf, Gkernel );

    myNormalEstimatorG.init ( 1.0, 15 );

    MyEstimatorGaussian::Quantity res2 = myNormalEstimatorG.eval ( it );
    trace.info() << "Normal vector at begin() : "<< res2 << std::endl;

    viewer<< CustomColors3D ( Color ( 200, 0, 0 ),Color ( 200, 0,0 ) );
    lineColorSave = viewer.getLineColor();
    viewer.setLineColor( DGtal::Color ( 200,20,20 ));
    for ( MyDigitalSurface::ConstIterator itbis = digSurf.begin(),itend=digSurf.end();
            itbis!=itend; ++itbis )
    {
        viewer << ks.unsigns ( *itbis );

        Point center = ks.sCoords ( *itbis );
        MyEstimatorGaussian::Quantity normal = myNormalEstimatorG.eval ( itbis );
        viewer.addLine ( center,
                         DGtal::Z3i::RealPoint(center[0]-3*normal[0],
					       center[1]-3*normal[1],
					       center[2]-3*normal[2]) );
    }
    viewer.setLineColor( lineColorSave);
    viewer<< Viewer3D<>::updateDisplay;


    nbok += true ? 1 : 0;
    nb++;
    trace.info() << "(" << nbok << "/" << nb << ") "
                 << "true == true" << std::endl;
    trace.endBlock();

    return application.exec();
}
/**
 * Example of a test. To be completed.
 *
 */
bool testEstimatorCache(double h)
{
  unsigned int nbok = 0;
  unsigned int nb = 0;
    
  typedef ImplicitBall<Z3i::Space> ImplicitShape;
  typedef GaussDigitizer<Z3i::Space, ImplicitShape> DigitalShape;
  typedef LightImplicitDigitalSurface<Z3i::KSpace,DigitalShape> Boundary;
  typedef DigitalSurface< Boundary > MyDigitalSurface;
  typedef DepthFirstVisitor< MyDigitalSurface > Visitor;
  typedef GraphVisitorRange< Visitor > VisitorRange;
  typedef VisitorRange::ConstIterator VisitorConstIterator;

  typedef functors::IIGaussianCurvature3DFunctor<Z3i::Space> MyIICurvatureFunctor;
  typedef IntegralInvariantCovarianceEstimator< Z3i::KSpace, DigitalShape, MyIICurvatureFunctor > MyIICurvatureEstimator;
//  typedef MyIICurvatureFunctor::Value Value;

  double re = 5.0;
  double radius = 5.0;

  trace.beginBlock( "Shape initialisation ..." );

  ImplicitShape ishape( Z3i::RealPoint( 0, 0, 0 ), radius );
  DigitalShape dshape;
  dshape.attach( ishape );
  dshape.init( Z3i::RealPoint( -10.0, -10.0, -10.0 ), Z3i::RealPoint( 10.0, 10.0, 10.0 ), h );

  Z3i::KSpace K;
  if ( !K.init( dshape.getLowerBound(), dshape.getUpperBound(), true ) )
  {
    trace.error() << "Problem with Khalimsky space" << std::endl;
    return false;
  }

  Z3i::KSpace::Surfel bel = Surfaces<Z3i::KSpace>::findABel( K, dshape, 10000 );
  Boundary boundary( K, dshape, SurfelAdjacency<Z3i::KSpace::dimension>( true ), bel );
  MyDigitalSurface surf ( boundary );

  trace.endBlock();

  trace.beginBlock( "Curvature estimator computation ...");
  
  VisitorRange range( new Visitor( surf, *surf.begin() ));
  VisitorConstIterator ibegin = range.begin();
  VisitorConstIterator iend = range.end();

  MyIICurvatureFunctor curvatureFunctor;
  curvatureFunctor.init( h, re );

  MyIICurvatureEstimator curvatureEstimator( curvatureFunctor );
  curvatureEstimator.attach( K, dshape );
  curvatureEstimator.setParams( re/h );
  curvatureEstimator.init( h, ibegin, iend );

  std::vector<MyIICurvatureEstimator::Quantity> results;
  std::back_insert_iterator< std::vector<MyIICurvatureEstimator::Quantity> > itback(results);

  curvatureEstimator.eval(ibegin,iend,itback);
  trace.info() << "Number of values = "<< results.size()<<std::endl;
  trace.endBlock();

  trace.beginBlock( "Caching values ...");
  VisitorRange range2( new Visitor( surf, *surf.begin() ));
  VisitorConstIterator ibegin2 = range2.begin();
  VisitorConstIterator iend2 = range2.end();
  
  typedef EstimatorCache<MyIICurvatureEstimator> GaussianCache;

  BOOST_CONCEPT_ASSERT(( concepts::CSurfelLocalEstimator<GaussianCache> ));
    
  GaussianCache cache( curvatureEstimator );
  cache.init( h, ibegin2, iend2 );
  trace.info() << "Number of cached values = "<< cache.size()<<std::endl;

  trace.info() << "Value at begin="<< cache.eval(surf.begin())<<"  expected = "<< curvatureEstimator.eval(surf.begin())<<std::endl;
  trace.endBlock();


  trace.beginBlock( "Complete test ...");
  bool ok=true;
  for(MyDigitalSurface::ConstIterator it = surf.begin(), itend=surf.end(); it != itend; ++it)
    {
      if (  cache.eval(it) != curvatureEstimator.eval(it) )
        {
          ok=false;
          trace.error() << "Incorrect values at "<<*it<<" read " <<cache.eval(it)<< " and expecting "<<curvatureEstimator.eval(it)<<std::endl;
        }
    }
  trace.endBlock();

  trace.beginBlock( "Timing cache access ...");
  for(MyDigitalSurface::ConstIterator it = surf.begin(), itend=surf.end(); it != itend; ++it)
    {
      if (  cache.eval(it) == 12345678 ) //making sure to visit
                                             //all surfels
        {
          ok=false;
          trace.error() << "Incorrect values at "<<*it<<std::endl;
        }
    }
  trace.endBlock();

  trace.beginBlock( "Copy construction and timing cache access ...");
  GaussianCache cache2(cache);
  trace.info() << "Number of cached values = "<< cache.size()<<std::endl;
  trace.info() << "Value at begin="<< cache2.eval(surf.begin())<<"  expected = "<< curvatureEstimator.eval(surf.begin())<<std::endl;
  for(MyDigitalSurface::ConstIterator it = surf.begin(), itend=surf.end(); it != itend; ++it)
    {
      if (  cache.eval(it) == 12345678 ) //making sure to visit
                                         //all surfels
        {
          ok=false;
          trace.error() << "Incorrect values at "<<*it<<std::endl;
        }
    }
  trace.endBlock();


  
  nbok += ok ? 1 : 0; 
  nb++;
  trace.info() << "(" << nbok << "/" << nb << ") "
	       << "cache == eval" << std::endl;
  
  return nbok == nb;
}
Beispiel #5
0
bool
processShape( const std::string & name,
              Shape & aShape,
              double border_min[],
              double border_max[],
              double h,
              const std::string & namePCLFile = "" )
{
  typedef typename Space::RealPoint RealPoint;
  typedef typename Space::Integer Integer;
  typedef GaussDigitizer< Space, Shape > Digitizer;
  typedef KhalimskySpaceND< Space::dimension, Integer > KSpace;
  typedef LightImplicitDigitalSurface< KSpace, Digitizer > LightImplicitDigSurface;
  typedef HyperRectDomain< Space > Domain;
  
  typedef DigitalSurface< LightImplicitDigSurface > MyDigitalSurface;
  typedef typename MyDigitalSurface::ConstIterator ConstIterator;
  typedef typename KSpace::Surfel Surfel;
  
  
  Digitizer dig;
  dig.attach( aShape );
  dig.init( RealPoint( border_min ), RealPoint( border_max ), h );
  Domain domain = dig.getDomain();
  
  typedef typename ImageSelector< Domain, unsigned int >::Type Image;
  Image image( domain );
  DGtal::imageFromRangeAndValue( domain.begin(), domain.end(), image );
  
  KSpace K;
  bool ok = K.init( domain.lowerBound(), domain.upperBound(), true );
  if ( ! ok )
  {
    std::cerr << "[compareShapeEstimators]" << " error in creating KSpace." << std::endl;
    return false;
  }
  
  try
  {
    // Extracts shape boundary
    SurfelAdjacency< KSpace::dimension > SAdj ( true );
    Surfel bel = Surfaces<KSpace>::findABel ( K, dig, 10000 );
    
    LightImplicitDigSurface LightImplDigSurf ( K, dig, SAdj, bel );
    MyDigitalSurface surf ( LightImplDigSurf );
    typedef typename MyDigitalSurface::ConstIterator SurfelConstIterator;

    std::ofstream PCL;
    trace.info() << "Filename = "<<namePCLFile<<std::endl;
    PCL.open( namePCLFile.c_str() );

      
    //Count the number of points
    long int cpt=0;
    for(SurfelConstIterator it = surf.begin(), itend=surf.end(); it != itend; ++it)
      cpt++;
    
    trace.info() << "Surface size = "<<cpt<<std::endl;
    
    PCL << "# range size = " << surf.size() << std::endl;
    PCL << "# h = " << h << std::endl;
    PCL << "# .PCD v.7 - Point Cloud Data file format"<< std::endl;
    PCL <<" VERSION .7"<<std::endl;
    PCL <<" FIELDS x y z"<<std::endl;
    PCL <<" SIZE 4 4 4 4"<<std::endl;
    PCL <<" TYPE I I I I"<<std::endl;
    PCL <<" COUNT 1 1 1 1"<<std::endl;
    PCL <<" WIDTH "<< cpt <<std::endl;
    PCL <<" HEIGHT 1"<<std::endl;
    PCL <<" VIEWPOINT 0 0 0 1 0 0 0"<<std::endl;
    PCL <<" POINTS "<< cpt <<std::endl;
    PCL <<" DATA ascii"<<std::endl;
    PCL <<std::endl;
   
    for(SurfelConstIterator it = surf.begin(), itend=surf.end(); it != itend; ++it)
      PCL << K.sCoord(*it , 0)  << " " << K.sCoord(*it , 1) <<" "<<  K.sCoord(*it , 2) <<std::endl;
    
    PCL.close();
   	
  }
  catch ( InputException e )
  {
    std::cerr << "[estimatorCurvatureComparator3D]"
    << " error."
    << e.what() << std::endl;
    return false;
  }
  return true;
}