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; }
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; }
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; }
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; }
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(); }
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; }
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; }
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; }