int main(int argc, char** argv)
{
   if (argc != 9 )
   {
      std::cerr << "Usage: " << argv[0] << " rgb_image1 depth_image1 rgb_image2 depth_image2 fx fy cx cy.\n";
      return(1);
   }

   // loading images and depth information
   cv::Mat rgb1 = cv::imread( argv[1], CV_LOAD_IMAGE_GRAYSCALE );
   cv::Mat depth1 = cv::imread( argv[2], CV_LOAD_IMAGE_ANYDEPTH );

   cv::Mat rgb2 = cv::imread( argv[3], CV_LOAD_IMAGE_GRAYSCALE );
   cv::Mat depth2 = cv::imread( argv[4], CV_LOAD_IMAGE_ANYDEPTH );

   // intrinsics parameters
   float fx = atof(argv[5]);
   float fy = atof(argv[6]);
   float cx = atof(argv[7]);
   float cy = atof(argv[8]);

   // detect keypoint using rgb images
   cv::Ptr<cv::FeatureDetector> detector = cv::FeatureDetector::create( "STAR" );

   std::vector<cv::KeyPoint> keypoints1;
   detector->detect( rgb1, keypoints1 );
 
   std::vector<cv::KeyPoint> keypoints2;
   detector->detect( rgb2, keypoints2 );

   // create point cloud and compute normal
   cv::Mat cloud1, normals1;
   create_cloud( depth1, fx, fy, cx, cy, cloud1 );
   compute_normals( cloud1, normals1 );
   
   cv::Mat cloud2, normals2;
   create_cloud( depth2, fx, fy, cx, cy, cloud2 );
   compute_normals( cloud2, normals2 );

   // extract descriptors
   BrandDescriptorExtractor brand;

   cv::Mat desc1;
   brand.compute( rgb1, cloud1, normals1, keypoints1, desc1 );

   cv::Mat desc2;
   brand.compute( rgb2, cloud2, normals2, keypoints2, desc2 );

   // matching descriptors
   std::vector<cv::DMatch> matches; 
   crossCheckMatching(desc2, desc1, matches);

   cv::Mat outimg;
   cv::drawMatches(rgb2, keypoints2, rgb1, keypoints1, matches, outimg, cv::Scalar::all(-1), cv::Scalar::all(-1));
   cv::imshow("matches", outimg);
   cv::waitKey();

   return 0;
}
Пример #2
0
geometry_mesh make_lathed_geometry(const float3 & axis, const float3 & arm1, const float3 & arm2, int slices, std::initializer_list<float2> points)
{
    geometry_mesh mesh;
    for(int i=0; i<=slices; ++i)
    {
        const float angle = static_cast<float>(i%slices) * tau / slices, c = std::cos(angle), s = std::sin(angle);
        const float3x2 mat = {axis, arm1 * c + arm2 * s};
        float3 n = normalize(mat.y); // TODO: Proper normals for each segment
        for(auto & p : points) mesh.vertices.push_back({mul(mat,p), n});

        if(i > 0)
        {
            for(size_t j = 1; j < points.size(); ++j)
            {
                int i0 = (i-1)*points.size() + (j-1);
                int i1 = (i-0)*points.size() + (j-1);
                int i2 = (i-0)*points.size() + (j-0);
                int i3 = (i-1)*points.size() + (j-0);
                mesh.triangles.push_back({i0,i1,i2});
                mesh.triangles.push_back({i0,i2,i3});
            }
        }
    }
    compute_normals(mesh);
    return mesh;
}
Пример #3
0
bool Morkon_Manager<DeviceType, DIM, FACE_TYPE>::mortar_integrate(Tpetra::CrsMatrix<> *D_to_overwrite, Tpetra::CrsMatrix<> *M_to_overwrite)
{
  typedef Morkon_Manager<DeviceType, DIM, FACE_TYPE> mgr_t;

  // Using the internal SurfaceMesh, populate
  //   - m_fields.m_node_normals
  //   - m_fields.m_face_normals
  if (!compute_normals())
  {
    return false;
  }

  coarse_search_results_t coarse_contacts = find_possible_contact_face_pairs();

  if (!compute_boundary_node_support_sets(coarse_contacts))
  {
    return false;
  }

  // Will our integration scheme require node_support_sets the way the legacy version does?
  mortar_pallets_t pallets_for_integration = compute_contact_pallets(coarse_contacts);

  if (!integrate_pallets_into_onrank_D(pallets_for_integration))
  {
    return false;
  }

  if (!integrate_pallets_into_onrank_M(pallets_for_integration))
  {
    return false;
  }

  return true;
}
Пример #4
0
pcl_tools::icp_result alp_align(PointCloudT::Ptr object, PointCloudT::Ptr scene, PointCloudT::Ptr object_aligned,
    int max_iterations, int num_samples, float similarity_thresh, float max_corresp_dist, float inlier_frac, float leaf) {
  FeatureCloudT::Ptr object_features (new FeatureCloudT);
  FeatureCloudT::Ptr scene_features (new FeatureCloudT);

  // Downsample
  pcl::console::print_highlight ("Downsampling...\n");
  pcl::VoxelGrid<PointNT> grid;
  // const float leaf = 0.005f;
  // const float leaf = in_leaf;

  grid.setLeafSize (leaf, leaf, leaf);
  grid.setInputCloud (object);
  grid.filter (*object);
  grid.setInputCloud (scene);
  grid.filter (*scene);

  compute_normals(object);
  compute_normals(scene);

  compute_features(object, object_features);
  compute_features(scene, scene_features);

  // Perform alignment
  pcl::console::print_highlight ("Starting alignment...\n");
  pcl::SampleConsensusPrerejective<PointNT,PointNT,FeatureT> align;
  align.setInputSource (object);
  align.setSourceFeatures (object_features);
  align.setInputTarget (scene);
  align.setTargetFeatures (scene_features);
  align.setMaximumIterations (max_iterations); // Number of RANSAC iterations
  align.setNumberOfSamples (num_samples); // Number of points to sample for generating/prerejecting a pose
  align.setCorrespondenceRandomness (12); // Number of nearest features to use
  align.setSimilarityThreshold (similarity_thresh); // Polygonal edge length similarity threshold
  align.setMaxCorrespondenceDistance (max_corresp_dist); // Inlier threshold
  align.setInlierFraction (inlier_frac); // Required inlier fraction for accepting a pose hypothesis
  {
    pcl::ScopeTime t("Alignment");
    align.align (*object_aligned);
  }
  pcl_tools::icp_result result;
  result.affine = Eigen::Affine3d(align.getFinalTransformation().cast<double>());
  result.converged = align.hasConverged();
  result.inliers = align.getInliers ().size ();
  return result;
}
Пример #5
0
int
main(int argc, char *argv[])
{
  int i,j;
  char *s;
  char *progname;
  FILE *inFile = stdin;

  progname = argv[0];

  while (--argc > 0 && (*++argv)[0]=='-') {
    for (s = argv[0]+1; *s; s++)
      switch (*s) {
        case 'f':
          flip_sign = 1;
          break;
        case 'a':
          area_weight = 1;
          break;
        default:
          usage (progname);
          exit (-1);
          break;
      }
  }


   /* optional input file (if not, read stdin ) */
   if (argc > 0 && *argv[0] != '-') {
       inFile = fopen(argv[0], "r");
       if (inFile == NULL) {
           fprintf(stderr, "Error: Couldn't open input file %s\n", argv[0]);
           usage(progname);
	   exit(-1);
       }
       argc --;
       argv ++;
   } 

   /* Check no extra args */
   if (argc > 0) {
     fprintf(stderr, "Error: Unhandled arg: %s\n", argv[0]);
     usage(progname);
     exit(-1);
   }

  read_file(inFile);

  compute_normals();

  write_file();
}
Пример #6
0
Mesh marching_cubes(Grid& grid, double isovalue, SurfaceType surface_type)
{
    Mesh mesh;
    int offset[8];
    Vertex* vertices[12];
    unordered_set<Vertex*, vertex_hash, vertex_equals> vertex_set;
    
    compute_offset(grid, offset);

    for(int z = 0; z < grid.get_axis(2)-1; z++) {
        for(int y = 0; y < grid.get_axis(1)-1; y++) {
            for(int x = 0; x < grid.get_axis(0)-1; x++) {
                int ic = grid.index(x,y,z); 
                int table_index = get_index(grid, ic, offset, isovalue);

                for(int i = 0; i < 12; i++) {
                    if(edge_table[table_index] & (1 << i)) {
                        int v[3], u[3];
                        get_grid_edge(x, y, z, i, v, u);
                        double sv = grid[grid.index(v[0],v[1],v[2])];
                        double su = grid[grid.index(u[0],u[1],u[2])];
                        double vc[3] = {(v[0]-grid.get_axis(0)/2.0)*grid.get_spacing(0), 
                                        (v[1]-grid.get_axis(1)/2.0)*grid.get_spacing(1), 
                                        (v[2]-grid.get_axis(2)/2.0)*grid.get_spacing(2)};
                        double uc[3] = {(u[0]-grid.get_axis(0)/2.0)*grid.get_spacing(0),
                                        (u[1]-grid.get_axis(1)/2.0)*grid.get_spacing(1), 
                                        (u[2]-grid.get_axis(2)/2.0)*grid.get_spacing(2)};
                        if(surface_type == NO_SURFACE) {
                            vertices[i] = lerp(vc, sv, uc, su, isovalue);
                        } else {
                            vertices[i] = find_cut_point(vc, sv, uc, su, isovalue, surface_type);
                        }
                        vertices[i] = merge_vertex(vertices[i], vertex_set, mesh);
                    }
                }

                for(int i = 0; triangle_table[table_index][i] != -1; i += 3) {
                    Vertex *v0, *v1, *v2;

                    v0 = vertices[triangle_table[table_index][i]];
                    v1 = vertices[triangle_table[table_index][i+1]];
                    v2 = vertices[triangle_table[table_index][i+2]];

                    if(!is_degenerate(v0, v1, v2)) {
                        Face* f = new Face;
                        
                        f->v.push_back(v0);
                        f->v.push_back(v1);
                        f->v.push_back(v2);
                        v0->f.push_back(f);
                        v1->f.push_back(f);
                        v2->f.push_back(f);

                        Edge* e0 = create_edge(v0, v1, f, mesh);
                        Edge* e1 = create_edge(v1, v2, f, mesh);
                        Edge* e2 = create_edge(v2, v0, f, mesh);
                    
                        f->e.push_back(e0);
                        f->e.push_back(e1);
                        f->e.push_back(e2);
                        mesh.add(f);
                    }
                }
            }
        }
    }
    compute_normals(mesh);
    return mesh;
}
Пример #7
0
bool sampler::
load(const std::string& filename)
{
    typedef vcg::tri::io::Importer<MyMesh> Importer;

    vcg::tri::RequirePerFaceWedgeTexCoord(m);

    int mask = -1;

    std::cout << "loading... " << std::flush;
    int result = Importer::Open(m, filename.c_str(), mask);

    if (Importer::ErrorCritical(result)) {
        std::cerr << std::endl << "Unable to load file: \"" << filename 
                  << "\". " << Importer::ErrorMsg(result) << std::endl;
        return false;
    }
    std::cout << "DONE" << std::endl;

    if (result != 0)
        std::cout << "Warning: " << Importer::ErrorMsg(result) << std::endl;
    
    //if (!(mask & vcg::tri::io::Mask::IOM_VERTTEXCOORD))
    //    std::cerr << "Vertex texture coords are not available" << std::endl;
    
    if (!(mask & vcg::tri::io::Mask::IOM_WEDGTEXCOORD))
        std::cerr << "Wedge texture coords are not available. Sampling will fail!" << std::endl;

#ifdef USE_WEDGE_NORMALS
    if (!(mask & vcg::tri::io::Mask::IOM_WEDGNORMAL))
        std::cerr << "Wedge normals are not available. Sampling will fail!" << std::endl;
#else
    if (!(mask & vcg::tri::io::Mask::IOM_VERTNORMAL)) {
        std::cerr << "Vertex normals are not available. Recompute... " << std::flush;
        vcg::tri::UpdateNormal<MyMesh>::PerVertexClear(m);
        compute_normals();
        vcg::tri::UpdateNormal<MyMesh>::NormalizePerVertex(m);
        std::cout << "DONE" << std::endl;
    }
#endif

    std::cout << "Topology update... " << std::flush;
    vcg::tri::UpdateTopology<MyMesh>::VertexFace(m);
    std::cout << "DONE" << std::endl;

    //vcg::tri::RequirePerVertexNormal(m);
    std::cout << "Mesh: " << m.VN() << " vertices, " << m.FN() << " faces." << std::endl;

    textures = std::vector<texture>(m.textures.size());

    #pragma omp parallel for
    for (size_t i = 0; i < m.textures.size(); ++i) {
#if 1
        //for relative path in mtl:
        unsigned slashPos = std::string(filename).find_last_of("/\\");
        std::string textureFileName = std::string(filename).substr(0, slashPos+1) + m.textures[i];
#else
        //for absolute path in mtl:
        std::string textureFileName = m.textures[i];
#endif
        textures[i].load(textureFileName);
    }

    return true;
}
Пример #8
0
int main(int argc, char **argv)
{
    // parse command line arguments
    try {
        TCLAP::CmdLine cmd("Estimates normals using PCA, see also https://github.com/tudelft3d/masbcpp", ' ', "0.1");

        TCLAP::UnlabeledValueArg<std::string> inputArg( "input", "path to directory with inside it a 'coords.npy' file; a Nx3 float array where N is the number of input points.", true, "", "input dir", cmd);
        TCLAP::UnlabeledValueArg<std::string> outputArg( "output", "path to output directory. Estimated normals are written to the file 'normals.npy'.", false, "", "output dir", cmd);

        TCLAP::ValueArg<int> kArg("k","kneighbours","number of nearest neighbours to use for PCA",false,10,"int", cmd);

        TCLAP::SwitchArg reorder_kdtreeSwitch("N","no-kdtree-reorder","Don't reorder kd-tree points: slower computation but lower memory use", cmd, true);
        
        cmd.parse(argc,argv);
        
        normals_parameters input_parameters;
        input_parameters.k = kArg.getValue();

        input_parameters.kd_tree_reorder = reorder_kdtreeSwitch.getValue();

        std::string output_path = inputArg.getValue();
        if(outputArg.isSet())
            output_path = outputArg.getValue();
        std::replace(output_path.begin(), output_path.end(), '\\', '/');


        std::string input_coords_path = inputArg.getValue()+"/coords.npy";
        std::replace(input_coords_path.begin(), input_coords_path.end(), '\\', '/');

        output_path += "/normals.npy";
        // check for proper in-output arguments
        {
            std::ifstream infile(input_coords_path.c_str());
            if(!infile)
                throw TCLAP::ArgParseException("invalid filepath", inputArg.getValue());
        }
        {
            std::ofstream outfile(output_path.c_str());    
            if(!outfile)
                throw TCLAP::ArgParseException("invalid filepath", output_path);
        }

        std::cout << "Parameters: k="<<input_parameters.k<<"\n";
        
        ma_data madata = {};

        cnpy::NpyArray coords_npy = cnpy::npy_load( input_coords_path.c_str() );
        float* coords_carray = reinterpret_cast<float*>(coords_npy.data);

        madata.m = coords_npy.shape[0];
        unsigned int dim = coords_npy.shape[1];
        PointList coords(madata.m);
        for (unsigned int i=0; i<madata.m; i++) coords[i] = Point(&coords_carray[i*3]);
        coords_npy.destruct();

        VectorList normals(madata.m);
        madata.normals = &normals;
        madata.coords = &coords;

        // Perform the actual processing
        compute_normals(input_parameters, madata);

        // Output results
        Scalar* normals_carray = new Scalar[madata.m * 3];
        for (int i = 0; i < normals.size(); i++)
           for (int j = 0; j < 3; j++)
              normals_carray[i * 3 + j] = normals[i][j];

        const unsigned int c_size = (unsigned int) normals.size();
        const unsigned int shape[] = { c_size,3 };
        cnpy::npy_save(output_path.c_str(), normals_carray, shape, 2, "w");

        // Free memory
        delete[] normals_carray; normals_carray = NULL;
    } catch (TCLAP::ArgException &e) { std::cerr << "Error: " << e.error() << " for " << e.argId() << std::endl; }

    return 0;
}