서동현

week16 source code upload

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})
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
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
This diff is collapsed. Click to expand it.
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
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
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
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