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