Showing
8 changed files
with
516 additions
and
0 deletions
mesh_modeling/CMakeLists.txt
0 → 100644
| 1 | +cmake_minimum_required(VERSION 2.8 FATAL_ERROR) | ||
| 2 | + | ||
| 3 | +project(Capstone) | ||
| 4 | +set(CMAKE_BUILD_TYPE Release) | ||
| 5 | +add_compile_options(-std=c++11) | ||
| 6 | + | ||
| 7 | +find_package(PCL 1.7 REQUIRED) | ||
| 8 | +find_package(Eigen3 REQUIRED) | ||
| 9 | +find_package(OpenCV REQUIRED) | ||
| 10 | +find_package(Boost COMPONENTS program_options filesystem REQUIRED) | ||
| 11 | + | ||
| 12 | +include_directories( | ||
| 13 | + include | ||
| 14 | + ${Boost_INCLUDE_DIRS} | ||
| 15 | + ${PCL_INCLUDE_DIRS} | ||
| 16 | + ${EIGEN3_INCLUDE_DIR} | ||
| 17 | +) | ||
| 18 | + | ||
| 19 | +set(sources | ||
| 20 | +) | ||
| 21 | + | ||
| 22 | +link_directories(${PCL_LIBRARY_DIRS}) | ||
| 23 | +add_definitions(${PCL_DEFINITIONS}) | ||
| 24 | + | ||
| 25 | +add_executable(cloud src/pointcloud.cpp ${sources}) | ||
| 26 | +target_link_libraries(cloud ${PCL_LIBRARIES} ${OpenCV_LIBS} ${Boost_LIBRARIES}) | ||
| 27 | + | ||
| 28 | +add_executable(mesh src/mesh.cpp ${sources}) | ||
| 29 | +target_link_libraries(mesh ${PCL_LIBRARIES} ${OpenCV_LIBS}) | ||
| 30 | + | ||
| 31 | +add_executable(obj src/obj.cpp ${sources}) | ||
| 32 | +target_link_libraries(obj ${PCL_LIBRARIES} ${OpenCV_LIBS}) | ||
| 33 | + | ||
| 34 | +add_executable(densedepth src/densedepth.cpp ${sources}) | ||
| 35 | +target_link_libraries(densedepth ${PCL_LIBRARIES} ${OpenCV_LIBS}) |
mesh_modeling/include/common.h
0 → 100644
| 1 | +#pragma once | ||
| 2 | + | ||
| 3 | +//common | ||
| 4 | +#include <string> | ||
| 5 | +#include <fstream> | ||
| 6 | +#include <iostream> | ||
| 7 | +#include <vector> | ||
| 8 | +#include <ctime> | ||
| 9 | +#include <cstdio> | ||
| 10 | +#include <algorithm> | ||
| 11 | +#include <stdlib.h> | ||
| 12 | +#include <sstream> | ||
| 13 | +#include <iomanip> | ||
| 14 | + | ||
| 15 | +//eigen | ||
| 16 | +#include <Eigen/Dense> | ||
| 17 | + | ||
| 18 | +//boost | ||
| 19 | +#include <boost/format.hpp> | ||
| 20 | +#include <boost/filesystem.hpp> | ||
| 21 | +#include <boost/thread/thread.hpp> | ||
| 22 | +#include <boost/algorithm/string.hpp> | ||
| 23 | + | ||
| 24 | +//opencv | ||
| 25 | +#include <opencv2/core.hpp> | ||
| 26 | +#include <opencv2/highgui.hpp> | ||
| 27 | +#include <opencv2/imgproc.hpp> | ||
| 28 | + | ||
| 29 | +//pcl | ||
| 30 | +#include <pcl/point_types.h> | ||
| 31 | +#include <pcl/point_cloud.h> | ||
| 32 | +#include <pcl/io/io.h> | ||
| 33 | +#include <pcl/io/pcd_io.h> | ||
| 34 | +#include <pcl/io/vtk_io.h> | ||
| 35 | +#include <pcl/io/vtk_lib_io.h> | ||
| 36 | +#include <pcl/kdtree/kdtree_flann.h> | ||
| 37 | +#include <pcl/filters/filter.h> | ||
| 38 | +#include <pcl/filters/radius_outlier_removal.h> | ||
| 39 | +#include <pcl/filters/voxel_grid.h> | ||
| 40 | +#include <pcl/features/normal_3d.h> | ||
| 41 | +#include <pcl/surface/mls.h> | ||
| 42 | +#include <pcl/surface/poisson.h> | ||
| 43 | +#include <pcl/surface/marching_cubes_hoppe.h> | ||
| 44 | +#include <pcl/surface/gp3.h> | ||
| 45 | + | ||
| 46 | +using namespace boost::filesystem; | ||
| 47 | + | ||
| 48 | +struct camInfo | ||
| 49 | +{ | ||
| 50 | + double fx; | ||
| 51 | + double fy; | ||
| 52 | + double cx; | ||
| 53 | + double cy; | ||
| 54 | + double k1; | ||
| 55 | + double k2; | ||
| 56 | + double p1; | ||
| 57 | + double p2; | ||
| 58 | + int width; | ||
| 59 | + int height; | ||
| 60 | +}; | ||
| 61 | + | ||
| 62 | +void realsenseSetUp(camInfo& cam) | ||
| 63 | +{ | ||
| 64 | + cam.fx = 612.1810302745375; | ||
| 65 | + cam.fy = 612.27685546875; | ||
| 66 | + cam.cx = 323.64208984375; | ||
| 67 | + cam.cy = 234.55838012695312; | ||
| 68 | + cam.k1 = 0; | ||
| 69 | + cam.k2 = 0; | ||
| 70 | + cam.p1 = 0; | ||
| 71 | + cam.p2 = 0; | ||
| 72 | + cam.width = 640; | ||
| 73 | + cam.height = 480; | ||
| 74 | +} | ||
| 75 | + | ||
| 76 | +Eigen::Vector3d coordinateRotation(double x, double y, double z) | ||
| 77 | +{ | ||
| 78 | + Eigen::Vector3d coord; | ||
| 79 | + coord << x, y, z; | ||
| 80 | + | ||
| 81 | + Eigen::Matrix3d rot; | ||
| 82 | + rot << 1, 0, 0, 0, 0, 1, 0, -1, 0; | ||
| 83 | + | ||
| 84 | + coord = rot * coord; | ||
| 85 | + return coord; | ||
| 86 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
mesh_modeling/include/cv_func.h
0 → 100644
| 1 | +#pragma once | ||
| 2 | +#include "common.h" | ||
| 3 | + | ||
| 4 | +void readFolder(std::string folderPath, std::vector<cv::Mat>& depths) | ||
| 5 | +{ | ||
| 6 | + path p(folderPath); | ||
| 7 | + try | ||
| 8 | + { | ||
| 9 | + if(exists(p) && is_directory(p)) | ||
| 10 | + { | ||
| 11 | + std::vector<std::string> imgs; | ||
| 12 | + for(directory_entry& x : directory_iterator(p)) | ||
| 13 | + { | ||
| 14 | + std::string img = x.path().string(); | ||
| 15 | + imgs.push_back(img); | ||
| 16 | + } | ||
| 17 | + std::sort(imgs.begin(), imgs.end()); | ||
| 18 | + | ||
| 19 | + for(auto img : imgs) | ||
| 20 | + { | ||
| 21 | + cv::Mat depth = cv::imread(img, cv::IMREAD_ANYDEPTH); //16UC1 | ||
| 22 | + depths.push_back(depth); | ||
| 23 | + } | ||
| 24 | + } | ||
| 25 | + else | ||
| 26 | + { | ||
| 27 | + std::cout << "[Error] Check Depth Map Folder Path" << std::endl; | ||
| 28 | + exit(0); | ||
| 29 | + } | ||
| 30 | + } | ||
| 31 | + catch(const filesystem_error& ex) | ||
| 32 | + { | ||
| 33 | + std::cout << ex.what() << std::endl; | ||
| 34 | + } | ||
| 35 | +} | ||
| 36 | + | ||
| 37 | +std::string type2str(int type) | ||
| 38 | +{ | ||
| 39 | + std::string r; | ||
| 40 | + | ||
| 41 | + uchar depth = type & CV_MAT_DEPTH_MASK; | ||
| 42 | + uchar chans = 1 + (type >> CV_CN_SHIFT); | ||
| 43 | + | ||
| 44 | + switch ( depth ) | ||
| 45 | + { | ||
| 46 | + case CV_8U: r = "8U"; break; | ||
| 47 | + case CV_8S: r = "8S"; break; | ||
| 48 | + case CV_16U: r = "16U"; break; | ||
| 49 | + case CV_16S: r = "16S"; break; | ||
| 50 | + case CV_32S: r = "32S"; break; | ||
| 51 | + case CV_32F: r = "32F"; break; | ||
| 52 | + case CV_64F: r = "64F"; break; | ||
| 53 | + default: r = "User"; break; | ||
| 54 | + } | ||
| 55 | + | ||
| 56 | + r += "C"; | ||
| 57 | + r += (chans+'0'); | ||
| 58 | + | ||
| 59 | + return r; | ||
| 60 | +} | ||
| 61 | + | ||
| 62 | +cv::Mat getMeanImg(std::vector<cv::Mat> depths) | ||
| 63 | +{ | ||
| 64 | + if(depths.empty()) | ||
| 65 | + { | ||
| 66 | + std::cout << "[Error] no input images" << std::endl; | ||
| 67 | + exit(0); | ||
| 68 | + } | ||
| 69 | + | ||
| 70 | + cv::Mat m(depths[0].rows, depths[0].cols, CV_64FC1); | ||
| 71 | + m.setTo(0); | ||
| 72 | + | ||
| 73 | + cv::Mat tmp; | ||
| 74 | + for(auto depth : depths) | ||
| 75 | + { | ||
| 76 | + depth.convertTo(tmp, CV_64FC1); | ||
| 77 | + m += tmp; | ||
| 78 | + } | ||
| 79 | + | ||
| 80 | + m.convertTo(m, CV_16UC1, 1.0 / depths.size()); | ||
| 81 | + return m; | ||
| 82 | +} | ||
| 83 | + | ||
| 84 | +cv::Mat medianFilter(cv::Mat img) | ||
| 85 | +{ | ||
| 86 | + cv::Mat filtered; | ||
| 87 | + cv::medianBlur(img, filtered, 5); | ||
| 88 | + return filtered; | ||
| 89 | +} | ||
| 90 | + | ||
| 91 | +void reconstruction3D(camInfo cam, cv::Mat img, pcl::PointCloud<pcl::PointXYZ>::Ptr cloud) | ||
| 92 | +{ | ||
| 93 | + for(int i = 0; i < img.cols; i++) | ||
| 94 | + { | ||
| 95 | + for(int j = 0; j < img.rows; j++) | ||
| 96 | + { | ||
| 97 | + auto d = img.at<u_int16_t>(j, i) / 1000.0; | ||
| 98 | + if(d < 0.105 || d > 3.0) | ||
| 99 | + { //realsense min dist && max dist | ||
| 100 | + continue; | ||
| 101 | + } | ||
| 102 | + double x = (i - cam.cx) * d / cam.fx; | ||
| 103 | + double y = (j - cam.cy) * d / cam.fy; | ||
| 104 | + double z = d; | ||
| 105 | + | ||
| 106 | + pcl::PointXYZ pt; | ||
| 107 | + pt.x = x; | ||
| 108 | + pt.y = y; | ||
| 109 | + pt.z = z; | ||
| 110 | + cloud->push_back(pt); | ||
| 111 | + } | ||
| 112 | + } | ||
| 113 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
mesh_modeling/include/pcl_func.h
0 → 100644
This diff is collapsed. Click to expand it.
mesh_modeling/src/densedepth.cpp
0 → 100644
| 1 | +#include "common.h" | ||
| 2 | +#include "cv_func.h" | ||
| 3 | +#include "pcl_func.h" | ||
| 4 | + | ||
| 5 | +/* | ||
| 6 | +[input] | ||
| 7 | +argc = 2 | ||
| 8 | +argv[0] = program | ||
| 9 | +argv[1] = densedepth.png (320 x 240) | ||
| 10 | + | ||
| 11 | +[output] | ||
| 12 | +interpolated_densedepth.png (640 x 480) | ||
| 13 | +densedepth.pcd | ||
| 14 | +*/ | ||
| 15 | + | ||
| 16 | +int main(int argc, char** argv) | ||
| 17 | +{ | ||
| 18 | + if(argc != 2) | ||
| 19 | + { | ||
| 20 | + std::cout << "[Error] Program Usage: [./densedepth] [densedepth.png]" << std::endl; | ||
| 21 | + return -1; | ||
| 22 | + } | ||
| 23 | + | ||
| 24 | + //intrinsic setup | ||
| 25 | + camInfo cam; | ||
| 26 | + realsenseSetUp(cam); | ||
| 27 | + | ||
| 28 | + cv::Mat img, interpolated_img; | ||
| 29 | + img = cv::imread(argv[1], cv::IMREAD_ANYDEPTH); | ||
| 30 | + //std::cout << type2str(img.type()) << std::endl; -> 16UC1 | ||
| 31 | + | ||
| 32 | + //interpolation to (320, 240) -> (640, 480) | ||
| 33 | + cv::resize(img, interpolated_img, cv::Size(640, 480), cv::INTER_LINEAR); | ||
| 34 | + std::string inputPath = argv[1]; | ||
| 35 | + std::size_t div = inputPath.find_last_of("/\\"); | ||
| 36 | + std::string outputPath = inputPath.substr(0, div + 1); | ||
| 37 | + cv::imwrite(outputPath + "interpolated_densedepth.png", interpolated_img); | ||
| 38 | + | ||
| 39 | + pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>); | ||
| 40 | + | ||
| 41 | + for(int i = 0; i < interpolated_img.cols; i++) | ||
| 42 | + { | ||
| 43 | + for(int j = 0; j < interpolated_img.rows; j++) | ||
| 44 | + { | ||
| 45 | + auto d = (-interpolated_img.at<u_int16_t>(j, i)) / 1000.0; // closer - darker reversed | ||
| 46 | + double x = (i - cam.cx) * d / cam.fx; | ||
| 47 | + double y = (j - cam.cy) * d / cam.fy; | ||
| 48 | + double z = d; | ||
| 49 | + | ||
| 50 | + pcl::PointXYZ pt; | ||
| 51 | + pt.x = x; | ||
| 52 | + pt.y = y; | ||
| 53 | + pt.z = z; | ||
| 54 | + cloud->push_back(pt); | ||
| 55 | + } | ||
| 56 | + } | ||
| 57 | + pcl::io::savePCDFile(outputPath + "densedepth.pcd", *cloud); | ||
| 58 | + | ||
| 59 | + return 0; | ||
| 60 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
mesh_modeling/src/mesh.cpp
0 → 100644
| 1 | +#include "common.h" | ||
| 2 | +#include "cv_func.h" | ||
| 3 | +#include "pcl_func.h" | ||
| 4 | + | ||
| 5 | +/* | ||
| 6 | +[input] | ||
| 7 | +argc = 3 | ||
| 8 | +argv[0] = program | ||
| 9 | +argv[1] = original pointcloud | ||
| 10 | +argv[2] = filtered pointcloud | ||
| 11 | + | ||
| 12 | +[output] | ||
| 13 | +original mesh -> vtk format | ||
| 14 | +filtered mesh -> vtk format | ||
| 15 | +*/ | ||
| 16 | + | ||
| 17 | +int main(int argc, char** argv) | ||
| 18 | +{ | ||
| 19 | + if(argc != 3) | ||
| 20 | + { | ||
| 21 | + std::cout << "[Error] Program Usage: [./mesh] [original_cloud.pcd] [filtered_cloud.pcd]" << std::endl; | ||
| 22 | + return -1; | ||
| 23 | + } | ||
| 24 | + | ||
| 25 | + //save path | ||
| 26 | + std::string inputPath = argv[1]; | ||
| 27 | + std::size_t div = inputPath.find_last_of("/\\"); | ||
| 28 | + std::string outputPath = inputPath.substr(0, div + 1); | ||
| 29 | + | ||
| 30 | + //load pointcloud data | ||
| 31 | + pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_original(new pcl::PointCloud<pcl::PointXYZ>); | ||
| 32 | + pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>); | ||
| 33 | + pcl::io::loadPCDFile(argv[1], *cloud_original); | ||
| 34 | + pcl::io::loadPCDFile(argv[2], *cloud_filtered); | ||
| 35 | + std::cout << "[Processing] reading pointcloud done..." << std::endl; | ||
| 36 | + | ||
| 37 | + //origianl cloud needs upsampling | ||
| 38 | + //(triangulation process impossible for noisy normal estimation) | ||
| 39 | + //upsampling(cloud_original); | ||
| 40 | + //std::cout << "original cloud upsampling done..." << std::endl; | ||
| 41 | + | ||
| 42 | + //normal estimation | ||
| 43 | + pcl::PointCloud<pcl::PointNormal>::Ptr original_with_normals(new pcl::PointCloud<pcl::PointNormal>); | ||
| 44 | + normal_estimation(cloud_original, original_with_normals); | ||
| 45 | + | ||
| 46 | + pcl::PointCloud<pcl::PointNormal>::Ptr filtered_with_normals(new pcl::PointCloud<pcl::PointNormal>); | ||
| 47 | + normal_estimation(cloud_filtered, filtered_with_normals); | ||
| 48 | + std::cout << "[Processing] normal estimation done..." << std::endl; | ||
| 49 | + | ||
| 50 | + //triangulation | ||
| 51 | + pcl::PolygonMesh triangles_original, triangles_filtered; | ||
| 52 | + triangulation(original_with_normals, triangles_original); | ||
| 53 | + triangulation(filtered_with_normals, triangles_filtered); | ||
| 54 | + std::cout << "[Processing] triangulation done..." << std::endl; | ||
| 55 | + | ||
| 56 | + //save output | ||
| 57 | + pcl::io::saveVTKFile(outputPath + "original_mesh.vtk", triangles_original); | ||
| 58 | + pcl::io::saveVTKFile(outputPath + "filtered_mesh.vtk", triangles_filtered); | ||
| 59 | + | ||
| 60 | + return 0; | ||
| 61 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
mesh_modeling/src/obj.cpp
0 → 100644
| 1 | +#include "common.h" | ||
| 2 | +#include "cv_func.h" | ||
| 3 | +#include "pcl_func.h" | ||
| 4 | + | ||
| 5 | +/* | ||
| 6 | +[input] | ||
| 7 | +argc = 3 | ||
| 8 | +argv[0] = program | ||
| 9 | +argv[1] = vtk file | ||
| 10 | +artv[2] = color img | ||
| 11 | + | ||
| 12 | +[output] | ||
| 13 | +obj file | ||
| 14 | +mtl file | ||
| 15 | +*/ | ||
| 16 | + | ||
| 17 | +int main(int argc, char** argv) | ||
| 18 | +{ | ||
| 19 | + if(argc != 3) | ||
| 20 | + { | ||
| 21 | + std::cout << "[Error] Program Usage: [./obj] [mesh.vtk] [color_img.png]" << std::endl; | ||
| 22 | + return -1; | ||
| 23 | + } | ||
| 24 | + | ||
| 25 | + //read vtk file | ||
| 26 | + pcl::PolygonMesh vtk_mesh; | ||
| 27 | + pcl::io::loadPolygonFileVTK(argv[1], vtk_mesh); | ||
| 28 | + | ||
| 29 | + //copy pointcloud from vtk file (vertices) | ||
| 30 | + pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>); | ||
| 31 | + pcl::fromPCLPointCloud2(vtk_mesh.cloud, *cloud); | ||
| 32 | + | ||
| 33 | + //mesh initialization | ||
| 34 | + pcl::TextureMesh mesh; | ||
| 35 | + mesh.cloud = vtk_mesh.cloud; | ||
| 36 | + std::vector<pcl::Vertices> vertices; | ||
| 37 | + | ||
| 38 | + //copy faces from vtk file | ||
| 39 | + vertices.resize(vtk_mesh.polygons.size()); | ||
| 40 | + for(std::size_t i = 0; i < vtk_mesh.polygons.size(); i++) | ||
| 41 | + { | ||
| 42 | + vertices[i] = vtk_mesh.polygons[i]; | ||
| 43 | + } | ||
| 44 | + mesh.tex_polygons.push_back(vertices); | ||
| 45 | + PCL_INFO("Input mesh contains %zu faces and %zu vertices\n", | ||
| 46 | + mesh.tex_polygons[0].size(), | ||
| 47 | + static_cast<std::size_t>(cloud->size())); | ||
| 48 | + PCL_INFO("...Done.\n"); | ||
| 49 | + | ||
| 50 | + //intrinsic setup | ||
| 51 | + camInfo cam; | ||
| 52 | + realsenseSetUp(cam); | ||
| 53 | + | ||
| 54 | + //one material | ||
| 55 | + mesh.tex_materials.resize(1); | ||
| 56 | + | ||
| 57 | + pcl::TexMaterial mesh_material; | ||
| 58 | + mesh_material.tex_name = "texture image"; | ||
| 59 | + std::string color_img = argv[2]; | ||
| 60 | + color_img = color_img.substr(color_img.find_last_of("/\\") + 1); | ||
| 61 | + mesh_material.tex_file = color_img; | ||
| 62 | + | ||
| 63 | + mesh_material.tex_Ka.r = 0.2f; | ||
| 64 | + mesh_material.tex_Ka.g = 0.2f; | ||
| 65 | + mesh_material.tex_Ka.b = 0.2f; | ||
| 66 | + | ||
| 67 | + mesh_material.tex_Kd.r = 0.8f; | ||
| 68 | + mesh_material.tex_Kd.g = 0.8f; | ||
| 69 | + mesh_material.tex_Kd.b = 0.8f; | ||
| 70 | + | ||
| 71 | + mesh_material.tex_Ks.r = 1.0f; | ||
| 72 | + mesh_material.tex_Ks.g = 1.0f; | ||
| 73 | + mesh_material.tex_Ks.b = 1.0f; | ||
| 74 | + | ||
| 75 | + mesh_material.tex_d = 1.0f; | ||
| 76 | + mesh_material.tex_Ns = 75.0f; | ||
| 77 | + mesh_material.tex_illum = 2; | ||
| 78 | + | ||
| 79 | + mesh.tex_materials[0] = mesh_material; | ||
| 80 | + | ||
| 81 | + //normal estimation | ||
| 82 | + PCL_INFO ("\nEstimating normals...\n"); | ||
| 83 | + pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> n; | ||
| 84 | + pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>); | ||
| 85 | + pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>); | ||
| 86 | + tree->setInputCloud(cloud); | ||
| 87 | + n.setInputCloud(cloud); | ||
| 88 | + n.setSearchMethod(tree); | ||
| 89 | + n.setKSearch(20); | ||
| 90 | + n.compute(*normals); | ||
| 91 | + | ||
| 92 | + pcl::PointCloud<pcl::PointNormal>::Ptr cloud_with_normals(new pcl::PointCloud<pcl::PointNormal>); | ||
| 93 | + pcl::concatenateFields(*cloud, *normals, *cloud_with_normals); | ||
| 94 | + pcl::toPCLPointCloud2(*cloud_with_normals, mesh.cloud); | ||
| 95 | + PCL_INFO("...Done.\n"); | ||
| 96 | + | ||
| 97 | + //obj file creating | ||
| 98 | + PCL_INFO("\nSaving mesh to textured_mesh.obj\n"); | ||
| 99 | + saveOBJFile("mesh.obj", mesh, 5, cloud, cam); | ||
| 100 | + | ||
| 101 | + return 0; | ||
| 102 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
mesh_modeling/src/pointcloud.cpp
0 → 100644
| 1 | +#include "common.h" | ||
| 2 | +#include "cv_func.h" | ||
| 3 | +#include "pcl_func.h" | ||
| 4 | + | ||
| 5 | +/* | ||
| 6 | +[input] | ||
| 7 | +argc = 2 | ||
| 8 | +argv[0] = program | ||
| 9 | +argv[1] = depth folder (containing depth images) | ||
| 10 | + | ||
| 11 | +[output] | ||
| 12 | +single frame depth image & point cloud | ||
| 13 | +average depth image & point cloud | ||
| 14 | +*/ | ||
| 15 | + | ||
| 16 | +int main(int argc, char** argv) | ||
| 17 | +{ | ||
| 18 | + if(argc != 2) | ||
| 19 | + { | ||
| 20 | + std::cout << "[Error] Program Usage: [./cloud] [depth image folder]" << std::endl; | ||
| 21 | + return -1; | ||
| 22 | + } | ||
| 23 | + | ||
| 24 | + //intrinsic setup | ||
| 25 | + camInfo cam; | ||
| 26 | + realsenseSetUp(cam); | ||
| 27 | + std::cout << "[Processing] Intrinsic parameters for Realsense setting done..." << std::endl; | ||
| 28 | + | ||
| 29 | + //get raw, filtered img | ||
| 30 | + std::string folderPath = argv[1]; | ||
| 31 | + std::vector<cv::Mat> depths; | ||
| 32 | + readFolder(folderPath, depths); | ||
| 33 | + cv::Mat meanImg = getMeanImg(depths); | ||
| 34 | + cv::Mat filtered = medianFilter(meanImg); | ||
| 35 | + cv::Mat raw = depths[0]; | ||
| 36 | + std::cout << "[Processing] image filtering done..." << std::endl; | ||
| 37 | + | ||
| 38 | + //3D reconstruction | ||
| 39 | + pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_original(new pcl::PointCloud<pcl::PointXYZ>); | ||
| 40 | + pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>); | ||
| 41 | + | ||
| 42 | + reconstruction3D(cam, raw, cloud_original); | ||
| 43 | + reconstruction3D(cam, filtered, cloud_filtered); | ||
| 44 | + std::cout << "[Processing] 3d reconstruction done..." << std::endl; | ||
| 45 | + | ||
| 46 | + //create output folder | ||
| 47 | + std::size_t div = folderPath.find_last_of("/\\"); | ||
| 48 | + std::string outputPath = folderPath.substr(0, div + 1) + "result"; | ||
| 49 | + path p(outputPath); | ||
| 50 | + create_directory(p); | ||
| 51 | + | ||
| 52 | + //save output | ||
| 53 | + pcl::io::savePCDFile(outputPath + "/cloud_original.pcd", *cloud_original); | ||
| 54 | + pcl::io::savePCDFile(outputPath + "/cloud_filtered.pcd", *cloud_filtered); | ||
| 55 | + cv::imwrite(outputPath + "/img_original.png", raw); | ||
| 56 | + cv::imwrite(outputPath + "/img_filtered.png", filtered); | ||
| 57 | + | ||
| 58 | + return 0; | ||
| 59 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
-
Please register or login to post a comment