diff --git a/README.md b/README.md index 63338744..a6ab0cc4 100644 --- a/README.md +++ b/README.md @@ -54,13 +54,14 @@ There are two main categories of samples: **Camera** and **Applications**. The s - **Visualization** - [**CaptureFromFileCameraVis3D**][CaptureFromFileCameraVis3D-url] - Capture point clouds, with color, from the virtual Zivid camera, and visualize it. Currently supported by Zivid One. - [**CaptureVis3D**][CaptureVis3D-url] - Capture point clouds, with color, from the Zivid camera, and visualize it. - - [**CaptureWritePCLVis3D**][CaptureWritePCLVis3D-url] - Capture point clouds, with color, from the Zivid camera, save it to PCD file format, and visualize it. + - [**CaptureWritePCLVis3D**][CaptureWritePCLVis3D-url] - Capture point clouds, with color and with/without normals, from the Zivid camera, convert it to + PCL format, save it to PCD file, and visualize it. - **Dependencies:** - [Point Cloud Library][point-cloud-library-url] version 1.2 or newer - [**CaptureHDRVisNormals**][CaptureHDRVisNormals-url] - Capture Zivid point clouds, with color and normals, and visualize it in 3D and as a normal map. - **Dependencies:** - [Point Cloud Library][point-cloud-library-url] version 1.2 or newer - - [**ReadPCLVis3D**][ReadPCLVis3D-url] - Read point cloud from PCL file and visualize it. + - [**ReadPCLVis3D**][ReadPCLVis3D-url] - Read point cloud, with color and with/without normals from PCD file and visualize it. - **Dependencies:** - [Point Cloud Library][point-cloud-library-url] version 1.2 or newer - **FileFormats** diff --git a/source/Applications/Advanced/MaskPointCloud/MaskPointCloud.cpp b/source/Applications/Advanced/MaskPointCloud/MaskPointCloud.cpp index 64db76f4..19435792 100644 --- a/source/Applications/Advanced/MaskPointCloud/MaskPointCloud.cpp +++ b/source/Applications/Advanced/MaskPointCloud/MaskPointCloud.cpp @@ -8,23 +8,28 @@ The ZDF file for this sample can be found under the main instructions for Zivid #include -#include +#include +#include #include +#include namespace { - void visualizePointCloud(const pcl::PointCloud &pointCloud) + void visualizePointCloud(const boost::shared_ptr> &pointCloud) { - pcl::PointCloud::Ptr cloudPTR(new pcl::PointCloud); - *cloudPTR = pointCloud; - std::cout << "Running PCL visualizer. Block until window closes" << std::endl; - pcl::visualization::CloudViewer viewer("Simple Cloud Viewer"); - viewer.showCloud(cloudPTR); + auto viewer = boost::make_shared("Viewer"); + + viewer->addPointCloud(pointCloud); + + viewer->setCameraPosition(0, 0, 100, 0, -1, 0); + std::cout << "Press r to centre and zoom the viewer so that the entire cloud is visible" << std::endl; std::cout << "Press q to exit the viewer application" << std::endl; - while(!viewer.wasStopped()) + while(!viewer->wasStopped()) { + viewer->spinOnce(100); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); } } @@ -82,7 +87,8 @@ namespace return zColorMap; } - pcl::PointCloud maskPointCloud(const Zivid::PointCloud &pointCloud, const cv::Mat &mask) + boost::shared_ptr> maskPointCloud(const Zivid::PointCloud &pointCloud, + const cv::Mat &mask) { const auto data = pointCloud.copyPointsXYZColorsRGBA(); const int height = data.height(); @@ -119,7 +125,7 @@ namespace } } - return maskedPointCloud; + return boost::make_shared>(maskedPointCloud); } void visualizeDepthMap(const pcl::PointCloud &pointCloud) @@ -132,7 +138,7 @@ namespace cv::waitKey(0); } - pcl::PointCloud convertToPCLPointCloud(const Zivid::PointCloud &pointCloud) + boost::shared_ptr> convertToPCLPointCloud(const Zivid::PointCloud &pointCloud) { const auto data = pointCloud.copyData(); @@ -153,7 +159,7 @@ namespace pointCloudPCL.points[i].g = data(i).color.g; // NOLINT(cppcoreguidelines-pro-type-union-access) pointCloudPCL.points[i].b = data(i).color.b; // NOLINT(cppcoreguidelines-pro-type-union-access) } - return pointCloudPCL; + return boost::make_shared>(pointCloudPCL); } } // namespace @@ -194,16 +200,17 @@ int main() visualizePointCloud(pointCloudPCL); std::cout << "Displaying depth map before masking" << std::endl; - visualizeDepthMap(pointCloudPCL); + visualizeDepthMap(*pointCloudPCL); std::cout << "Masking point cloud" << std::endl; - const pcl::PointCloud maskedPointCloudPCL = maskPointCloud(pointCloud, mask); + const boost::shared_ptr> maskedPointCloudPCL = + maskPointCloud(pointCloud, mask); std::cout << "Displaying point cloud after masking" << std::endl; visualizePointCloud(maskedPointCloudPCL); std::cout << "Displaying depth map after masking" << std::endl; - visualizeDepthMap(maskedPointCloudPCL); + visualizeDepthMap(*maskedPointCloudPCL); } catch(const std::exception &e) diff --git a/source/Applications/Advanced/MultiCamera/MultiCameraTutorial.md b/source/Applications/Advanced/MultiCamera/MultiCameraTutorial.md index 889952b6..6c75764d 100644 --- a/source/Applications/Advanced/MultiCamera/MultiCameraTutorial.md +++ b/source/Applications/Advanced/MultiCamera/MultiCameraTutorial.md @@ -309,14 +309,14 @@ stitchedPointCloud.points.resize(k); ```cpp //Simple Cloud Visualization -pcl::PointCloud::Ptr cloudPTR(new pcl::PointCloud); +boost::shared_ptr> cloudPTR(new pcl::PointCloud); *cloudPTR = stitchedPointCloud; std::cout << "Run the PCL visualizer. Block until window closes" << std::endl; pcl::visualization::CloudViewer viewer("Simple Cloud Viewer"); viewer.showCloud(cloudPTR); std::cout << "Press r to centre and zoom the viewer so that the entire cloud is visible" << std::endl; -std::cout << "Press q to me exit the viewer application" << std::endl; +std::cout << "Press q to exit the viewer application" << std::endl; while(!viewer.wasStopped()) { } diff --git a/source/Applications/Advanced/MultiCamera/StitchByTransformation/StitchByTransformation.cpp b/source/Applications/Advanced/MultiCamera/StitchByTransformation/StitchByTransformation.cpp index 282b2be0..58c9034a 100644 --- a/source/Applications/Advanced/MultiCamera/StitchByTransformation/StitchByTransformation.cpp +++ b/source/Applications/Advanced/MultiCamera/StitchByTransformation/StitchByTransformation.cpp @@ -197,14 +197,14 @@ int main(int argc, char **argv) std::cout << "Got " << validPoints << " out of " << maxNumberOfPoints << " points" << std::endl; // Simple Cloud Visualization - pcl::PointCloud::Ptr cloudPTR(new pcl::PointCloud); + boost::shared_ptr> cloudPTR(new pcl::PointCloud); *cloudPTR = stitchedPointCloud; std::cout << "Run the PCL visualizer. Block until window closes" << std::endl; pcl::visualization::CloudViewer viewer("Simple Cloud Viewer"); viewer.showCloud(cloudPTR); std::cout << "Press r to centre and zoom the viewer so that the entire cloud is visible" << std::endl; - std::cout << "Press q to me exit the viewer application" << std::endl; + std::cout << "Press q to exit the viewer application" << std::endl; while(!viewer.wasStopped()) { } diff --git a/source/Applications/Advanced/MultiCamera/StitchByTransformationFromZDF/StitchByTransformationFromZDF.cpp b/source/Applications/Advanced/MultiCamera/StitchByTransformationFromZDF/StitchByTransformationFromZDF.cpp index b300ede4..5d9a078c 100644 --- a/source/Applications/Advanced/MultiCamera/StitchByTransformationFromZDF/StitchByTransformationFromZDF.cpp +++ b/source/Applications/Advanced/MultiCamera/StitchByTransformationFromZDF/StitchByTransformationFromZDF.cpp @@ -182,14 +182,14 @@ int main(int argc, char **argv) std::cout << "Got " << validPoints << " out of " << maxNumberOfPoints << " points" << std::endl; // Simple Cloud Visualization - pcl::PointCloud::Ptr cloudPTR(new pcl::PointCloud); + boost::shared_ptr> cloudPTR(new pcl::PointCloud); *cloudPTR = stitchedPointCloud; std::cout << "Run the PCL visualizer. Block until window closes" << std::endl; pcl::visualization::CloudViewer viewer("Simple Cloud Viewer"); viewer.showCloud(cloudPTR); std::cout << "Press r to centre and zoom the viewer so that the entire cloud is visible" << std::endl; - std::cout << "Press q to me exit the viewer application" << std::endl; + std::cout << "Press q to exit the viewer application" << std::endl; while(!viewer.wasStopped()) { } diff --git a/source/Applications/Advanced/ROIBoxViaArucoMarker/ROIBoxViaArucoMarker.cpp b/source/Applications/Advanced/ROIBoxViaArucoMarker/ROIBoxViaArucoMarker.cpp index 527186e5..c2c2a8f4 100644 --- a/source/Applications/Advanced/ROIBoxViaArucoMarker/ROIBoxViaArucoMarker.cpp +++ b/source/Applications/Advanced/ROIBoxViaArucoMarker/ROIBoxViaArucoMarker.cpp @@ -16,7 +16,7 @@ This sample depends on ArUco libraries in OpenCV with extra modules (https://git #include #include -#include +#include #include @@ -237,13 +237,13 @@ namespace return gray; } - pcl::PointCloud::Ptr roiBoxPointCloud(const Zivid::PointCloud &pointCloud, - const float roiBoxBottomLeftCornerX, - const float roiBoxBottomLeftCornerY, - const float roiBoxBottomLeftCornerZ, - const float roiBoxLength, - const float roiBoxWidth, - const float roiBoxHeight) + boost::shared_ptr> roiBoxPointCloud(const Zivid::PointCloud &pointCloud, + const float roiBoxBottomLeftCornerX, + const float roiBoxBottomLeftCornerY, + const float roiBoxBottomLeftCornerZ, + const float roiBoxLength, + const float roiBoxWidth, + const float roiBoxHeight) { const auto data = pointCloud.copyPointsXYZColorsRGBA(); const int height = data.height(); @@ -341,10 +341,10 @@ namespace return zColorMap; } - void visualizeDepthMap(const boost::shared_ptr> &pointCloud) + void visualizeDepthMap(const pcl::PointCloud &pointCloud) { // Converting to Depth map in OpenCV format - cv::Mat zColorMap = pointCloudToCvZ(*pointCloud); + cv::Mat zColorMap = pointCloudToCvZ(pointCloud); // Visualizing Depth map cv::namedWindow("Depth map", cv::WINDOW_AUTOSIZE); cv::imshow("Depth map", zColorMap); @@ -361,7 +361,7 @@ namespace viewer->setCameraPosition(0, 0, -100, -1, 0, 0); std::cout << "Press r to centre and zoom the viewer so that the entire cloud is visible" << std::endl; - std::cout << "Press q to me exit the viewer application" << std::endl; + std::cout << "Press q to exit the viewer application" << std::endl; while(!viewer->wasStopped()) { viewer->spinOnce(100); @@ -442,19 +442,20 @@ int main() << "Height: " << roiBoxHeight << std::endl; std::cout << "Filtering the point cloud beased on ROI Box" << std::endl; - const pcl::PointCloud::Ptr roiPointCloudPCL = roiBoxPointCloud(pointCloud, - roiBoxBottomLeftCornerX, - roiBoxBottomLeftCornerY, - roiBoxBottomLeftCornerZ, - roiBoxLength, - roiBoxWidth, - roiBoxHeight); + const boost::shared_ptr> roiPointCloudPCL = + roiBoxPointCloud(pointCloud, + roiBoxBottomLeftCornerX, + roiBoxBottomLeftCornerY, + roiBoxBottomLeftCornerZ, + roiBoxLength, + roiBoxWidth, + roiBoxHeight); std::cout << "Displaying transformed point cloud after ROI Box filtering" << std::endl; visualizePointCloud(roiPointCloudPCL); std::cout << "Displaying depth map of the transformed point cloud after ROI Box filtering" << std::endl; - visualizeDepthMap(roiPointCloudPCL); + visualizeDepthMap(*roiPointCloudPCL); } catch(const std::exception &e) { diff --git a/source/Applications/Basic/Visualization/CaptureHDRVisNormals/CaptureHDRVisNormals.cpp b/source/Applications/Basic/Visualization/CaptureHDRVisNormals/CaptureHDRVisNormals.cpp index 417600b6..c4b661cb 100644 --- a/source/Applications/Basic/Visualization/CaptureHDRVisNormals/CaptureHDRVisNormals.cpp +++ b/source/Applications/Basic/Visualization/CaptureHDRVisNormals/CaptureHDRVisNormals.cpp @@ -15,15 +15,15 @@ map. For scenes with high dynamic range we combine multiple acquisitions to get namespace { void visualizePointCloudAndNormalsPCL( - const boost::shared_ptr> &pointCloudPCL, - const boost::shared_ptr> &pointCloudWithNormalsPCL) + const boost::shared_ptr> &pointCloud, + const boost::shared_ptr> &pointCloudWithNormals) { auto viewer = boost::make_shared("Viewer"); int viewRgb(0); viewer->createViewPort(0.0, 0.0, 0.5, 1.0, viewRgb); viewer->addText("Cloud RGB", 0, 0, "RGBText", viewRgb); - viewer->addPointCloud(pointCloudPCL, "cloud", viewRgb); + viewer->addPointCloud(pointCloud, "cloud", viewRgb); const int normalsSkipped = 10; std::cout << "Note! 1 out of " << normalsSkipped << " normals are visualized" << std::endl; @@ -31,9 +31,9 @@ namespace int viewNormals(0); viewer->createViewPort(0.5, 0.0, 1.0, 1.0, viewNormals); viewer->addText("Cloud Normals", 0, 0, "NormalsText", viewNormals); - viewer->addPointCloud(pointCloudWithNormalsPCL, "cloudNormals", viewNormals); - viewer->addPointCloudNormals(pointCloudWithNormalsPCL, - pointCloudWithNormalsPCL, + viewer->addPointCloud(pointCloudWithNormals, "cloudNormals", viewNormals); + viewer->addPointCloudNormals(pointCloudWithNormals, + pointCloudWithNormals, normalsSkipped, 1, "normals", @@ -42,7 +42,7 @@ namespace viewer->setCameraPosition(0, 0, -100, 0, -1, 0); std::cout << "Press r to centre and zoom the viewer so that the entire cloud is visible" << std::endl; - std::cout << "Press q to me exit the viewer application" << std::endl; + std::cout << "Press q to exit the viewer application" << std::endl; while(!viewer->wasStopped()) { viewer->spinOnce(100); @@ -50,26 +50,27 @@ namespace } } - pcl::PointCloud::Ptr zividToPclPoints(const Zivid::Array2D &data) + boost::shared_ptr> convertToPCLPointCloud( + const Zivid::Array2D &data) { - auto pointCloudPCL = boost::make_shared>(); - pointCloudPCL->width = data.width(); - pointCloudPCL->height = data.height(); - pointCloudPCL->is_dense = false; - pointCloudPCL->points.resize(data.size()); + auto pointCloud = boost::make_shared>(); + pointCloud->width = data.width(); + pointCloud->height = data.height(); + pointCloud->is_dense = false; + pointCloud->points.resize(data.size()); for(size_t i = 0; i < data.size(); ++i) { - pointCloudPCL->points[i].x = data(i).point.x; // NOLINT(cppcoreguidelines-pro-type-union-access) - pointCloudPCL->points[i].y = data(i).point.y; // NOLINT(cppcoreguidelines-pro-type-union-access) - pointCloudPCL->points[i].z = data(i).point.z; // NOLINT(cppcoreguidelines-pro-type-union-access) - pointCloudPCL->points[i].r = data(i).color.r; // NOLINT(cppcoreguidelines-pro-type-union-access) - pointCloudPCL->points[i].g = data(i).color.g; // NOLINT(cppcoreguidelines-pro-type-union-access) - pointCloudPCL->points[i].b = data(i).color.b; // NOLINT(cppcoreguidelines-pro-type-union-access) + pointCloud->points[i].x = data(i).point.x; // NOLINT(cppcoreguidelines-pro-type-union-access) + pointCloud->points[i].y = data(i).point.y; // NOLINT(cppcoreguidelines-pro-type-union-access) + pointCloud->points[i].z = data(i).point.z; // NOLINT(cppcoreguidelines-pro-type-union-access) + pointCloud->points[i].r = data(i).color.r; // NOLINT(cppcoreguidelines-pro-type-union-access) + pointCloud->points[i].g = data(i).color.g; // NOLINT(cppcoreguidelines-pro-type-union-access) + pointCloud->points[i].b = data(i).color.b; // NOLINT(cppcoreguidelines-pro-type-union-access) } - return pointCloudPCL; + return pointCloud; } - pcl::PointCloud::Ptr zividToPclVisualizationNormals( + boost::shared_ptr> convertToPCLVisualizationNormals( const Zivid::Array2D &data, const Zivid::Array2D &normals) { @@ -124,13 +125,13 @@ int main() std::cout << "Creating PCL point cloud structure" << std::endl; const auto data = pointCloud.copyData(); - const auto pointCloudPCL = zividToPclPoints(data); + const auto pointCloudPCL = convertToPCLPointCloud(data); std::cout << "Computing point cloud normals" << std::endl; const auto normals = pointCloud.copyData(); std::cout << "Creating PCL normals structure suited for visualization" << std::endl; - const auto pointCloudWithNormalsPCL = zividToPclVisualizationNormals(data, normals); + const auto pointCloudWithNormalsPCL = convertToPCLVisualizationNormals(data, normals); std::cout << "Visualizing normals" << std::endl; visualizePointCloudAndNormalsPCL(pointCloudPCL, pointCloudWithNormalsPCL); diff --git a/source/Applications/Basic/Visualization/CaptureWritePCLVis3D/CaptureWritePCLVis3D.cpp b/source/Applications/Basic/Visualization/CaptureWritePCLVis3D/CaptureWritePCLVis3D.cpp index 523e780b..2930f5b6 100644 --- a/source/Applications/Basic/Visualization/CaptureWritePCLVis3D/CaptureWritePCLVis3D.cpp +++ b/source/Applications/Basic/Visualization/CaptureWritePCLVis3D/CaptureWritePCLVis3D.cpp @@ -1,21 +1,120 @@ /* -This example shows how capture point clouds, with color, from the Zivid camera, -save it to PCD file format, and visualize it. +This example shows how capture point clouds, with color and with/without normals, from the Zivid camera, +convert it to PCL format, save it to PCD file, and visualize it. */ -#include #include #include #include -#include +#include #include +#include -int main() +namespace +{ + template + boost::shared_ptr> addDataToPCLPointCloud(const Zivid::Array2D &data) + { + auto pointCloud = boost::make_shared>(); + + pointCloud->width = data.width(); + pointCloud->height = data.height(); + pointCloud->is_dense = false; + pointCloud->points.resize(data.size()); + for(size_t i = 0; i < data.size(); ++i) + { + pointCloud->points[i].x = data(i).point.x; // NOLINT(cppcoreguidelines-pro-type-union-access) + pointCloud->points[i].y = data(i).point.y; // NOLINT(cppcoreguidelines-pro-type-union-access) + pointCloud->points[i].z = data(i).point.z; // NOLINT(cppcoreguidelines-pro-type-union-access) + pointCloud->points[i].r = data(i).color.r; // NOLINT(cppcoreguidelines-pro-type-union-access) + pointCloud->points[i].g = data(i).color.g; // NOLINT(cppcoreguidelines-pro-type-union-access) + pointCloud->points[i].b = data(i).color.b; // NOLINT(cppcoreguidelines-pro-type-union-access) + } + return pointCloud; + } + + boost::shared_ptr> convertToPCLPointCloud( + const Zivid::Array2D &data) + { + return addDataToPCLPointCloud(data); + } + + boost::shared_ptr> convertToPCLPointCloud( + const Zivid::Array2D &data, + const Zivid::Array2D &normals) + { + auto pointCloud = addDataToPCLPointCloud(data); + + for(size_t i = 0; i < data.size(); ++i) + { + pointCloud->points[i].normal_x = normals(i).x; // NOLINT(cppcoreguidelines-pro-type-union-access) + pointCloud->points[i].normal_y = normals(i).y; // NOLINT(cppcoreguidelines-pro-type-union-access) + pointCloud->points[i].normal_z = normals(i).z; // NOLINT(cppcoreguidelines-pro-type-union-access) + } + + return pointCloud; + } + + void addPointCloudToViewer(boost::shared_ptr &viewer, + const boost::shared_ptr> &pointCloud) + { + viewer->addPointCloud(pointCloud); + + const int normalsSkipped = 10; + std::cout << "Note! 1 out of " << normalsSkipped << " normals are visualized" << std::endl; + viewer->addPointCloudNormals(pointCloud, + pointCloud, + normalsSkipped, + 1, + "normals"); + } + + void addPointCloudToViewer(boost::shared_ptr &viewer, + const boost::shared_ptr> &pointCloud) + { + viewer->addPointCloud(pointCloud); + } + + template + void visualizePointCloudPCL(const boost::shared_ptr> &pointCloud) + { + auto viewer = boost::make_shared("Viewer"); + + addPointCloudToViewer(viewer, pointCloud); + + viewer->setCameraPosition(0, 0, -100, 0, -1, 0); + + std::cout << "Press r to centre and zoom the viewer so that the entire cloud is visible" << std::endl; + std::cout << "Press q to exit the viewer application" << std::endl; + while(!viewer->wasStopped()) + { + viewer->spinOnce(100); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + } + + template + void visualizeAndSavePointCloudPCL(const boost::shared_ptr> &pointCloud) + { + std::cout << "Visualizing PCL point cloud" << std::endl; + visualizePointCloudPCL(pointCloud); + + std::string pointCloudFile = "Zivid3D.pcd"; + std::cout << "Saving point cloud to file: " << pointCloudFile << std::endl; + pcl::io::savePCDFileBinary(pointCloudFile, *pointCloud); + std::cerr << "Saved " << pointCloud->points.size() << " points" << std::endl; + } + +} // namespace + +int main(int argc, char **argv) { try { + bool useNormals = argc >= 2 && std::string(argv[1]) == "normals"; + Zivid::Application zivid; std::cout << "Connecting to camera" << std::endl; @@ -27,57 +126,26 @@ int main() std::cout << "Capturing frame" << std::endl; const auto frame = camera.capture(settings); - - std::cout << "Setting up visualization" << std::endl; - Zivid::Visualization::Visualizer visualizer; - - std::cout << "Visualizing point cloud" << std::endl; - visualizer.showMaximized(); - visualizer.show(frame); - visualizer.resetToFit(); - - std::cout << "Running visualizer. Blocking until window closes" << std::endl; - visualizer.run(); - const auto pointCloud = frame.pointCloud(); const auto data = pointCloud.copyData(); - std::cout << "Creating PCL point cloud structure" << std::endl; - pcl::PointCloud pointCloudPCL; - - std::cout << "Filling in point cloud data" << std::endl; - pointCloudPCL.width = pointCloud.width(); - pointCloudPCL.height = pointCloud.height(); - pointCloudPCL.is_dense = false; - pointCloudPCL.points.resize(pointCloudPCL.width * pointCloudPCL.height); - - for(size_t i = 0; i < pointCloudPCL.points.size(); ++i) + if(useNormals) { - pointCloudPCL.points[i].x = data(i).point.x; // NOLINT(cppcoreguidelines-pro-type-union-access) - pointCloudPCL.points[i].y = data(i).point.y; // NOLINT(cppcoreguidelines-pro-type-union-access) - pointCloudPCL.points[i].z = data(i).point.z; // NOLINT(cppcoreguidelines-pro-type-union-access) - pointCloudPCL.points[i].r = data(i).color.r; // NOLINT(cppcoreguidelines-pro-type-union-access) - pointCloudPCL.points[i].g = data(i).color.g; // NOLINT(cppcoreguidelines-pro-type-union-access) - pointCloudPCL.points[i].b = data(i).color.b; // NOLINT(cppcoreguidelines-pro-type-union-access) - } + std::cout << "Computing point cloud normals" << std::endl; + const auto normals = pointCloud.copyData(); - pcl::PointCloud::Ptr cloudPtr(new pcl::PointCloud); - *cloudPtr = pointCloudPCL; + std::cout << "Converting Zivid point cloud with normals to PCL format" << std::endl; + const auto pointCloudWithNormalsPCL = convertToPCLPointCloud(data, normals); - std::cout << "Visualizing point cloud" << std::endl; - pcl::visualization::CloudViewer cloudViewer("Simple Cloud Viewer"); - std::cout << "Running visualizer. Blocking until window closes" << std::endl; - cloudViewer.showCloud(cloudPtr); - std::cout << "Press r to centre and zoom the viewer so that the entire cloud is visible" << std::endl; - std::cout << "Press q to me exit the viewer application" << std::endl; - while(!cloudViewer.wasStopped()) - { + visualizeAndSavePointCloudPCL(pointCloudWithNormalsPCL); } + else + { + std::cout << "Converting Zivid point cloud to PCL format" << std::endl; + const auto pointCloudPCL = convertToPCLPointCloud(data); - std::string pointCloudFile = "Zivid3D.pcd"; - std::cout << "Saving point cloud to file: " << pointCloudFile << std::endl; - pcl::io::savePCDFileBinary(pointCloudFile, pointCloudPCL); - std::cerr << "Saved " << pointCloudPCL.points.size() << " points" << std::endl; + visualizeAndSavePointCloudPCL(pointCloudPCL); + } } catch(const std::exception &e) { diff --git a/source/Applications/Basic/Visualization/ReadPCLVis3D/ReadPCLVis3D.cpp b/source/Applications/Basic/Visualization/ReadPCLVis3D/ReadPCLVis3D.cpp index b2dc38eb..6cd67f1c 100644 --- a/source/Applications/Basic/Visualization/ReadPCLVis3D/ReadPCLVis3D.cpp +++ b/source/Applications/Basic/Visualization/ReadPCLVis3D/ReadPCLVis3D.cpp @@ -1,5 +1,5 @@ /* -This example shows how to read point cloud from PCL file and visualize it. +This example shows how to read point cloud, with color and with/without normals from PCD file and visualize it. The PCD file for this sample can be found under the main instructions for Zivid samples. */ @@ -7,29 +7,80 @@ The PCD file for this sample can be found under the main instructions for Zivid #include #include -#include +#include #include +#include -int main() +namespace +{ + void addPointCloudToViewer(boost::shared_ptr &viewer, + const boost::shared_ptr> &pointCloud) + { + viewer->addPointCloud(pointCloud); + + const int normalsSkipped = 10; + std::cout << "Note! 1 out of " << normalsSkipped << " normals are visualized" << std::endl; + viewer->addPointCloudNormals(pointCloud, + pointCloud, + normalsSkipped, + 1, + "normals"); + } + + void addPointCloudToViewer(boost::shared_ptr &viewer, + const boost::shared_ptr> &pointCloud) + { + viewer->addPointCloud(pointCloud); + } + + template + void visualizePointCloudPCL(const boost::shared_ptr> &pointCloud) + { + auto viewer = boost::make_shared("Viewer"); + + addPointCloudToViewer(viewer, pointCloud); + + viewer->setCameraPosition(0, 0, -100, 0, -1, 0); + + std::cout << "Press r to centre and zoom the viewer so that the entire cloud is visible" << std::endl; + std::cout << "Press q to exit the viewer application" << std::endl; + while(!viewer->wasStopped()) + { + viewer->spinOnce(100); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + } + +} // namespace + +int main(int argc, char **argv) { try { - pcl::PointCloud::Ptr cloudPtr(new pcl::PointCloud); + bool useNormals = argc >= 2 && std::string(argv[1]) == "normals"; std::string pointCloudFile = std::string(ZIVID_SAMPLE_DATA_DIR) + "/Zivid3D.pcd"; std::cout << "Reading PCD point cloud from file: " << pointCloudFile << std::endl; - pcl::io::loadPCDFile(pointCloudFile, *cloudPtr); - std::cout << "Loaded " << cloudPtr->width * cloudPtr->height << " points" << std::endl; - std::cout << "Visualizing point cloud" << std::endl; - pcl::visualization::CloudViewer cloudViewer("Simple Cloud Viewer"); - std::cout << "Running visualizer. Blocking until window closes" << std::endl; - cloudViewer.showCloud(cloudPtr); - std::cout << "Press r to centre and zoom the viewer so that the entire cloud is visible" << std::endl; - std::cout << "Press q to me exit the viewer application" << std::endl; - while(!cloudViewer.wasStopped()) + if(useNormals) { + auto pointCloudWithNormalsPCL = boost::make_shared>(); + + pcl::io::loadPCDFile(pointCloudFile, *pointCloudWithNormalsPCL); + std::cout << "Loaded " << pointCloudWithNormalsPCL->width * pointCloudWithNormalsPCL->height << " points" + << std::endl; + + visualizePointCloudPCL(pointCloudWithNormalsPCL); + } + else + { + auto pointCloudPCL = boost::make_shared>(); + + pcl::io::loadPCDFile(pointCloudFile, *pointCloudPCL); + std::cout << "Loaded " << pointCloudPCL->width * pointCloudPCL->height << " points" << std::endl; + + visualizePointCloudPCL(pointCloudPCL); } return 0;