MergedLabeledPointCloud.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * ArmarX is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * ArmarX is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * @package MA_RainerKartmann::ArmarXObjects::PointCloudMerger
17 * @author Rainer Kartmann ( rainer dot kartmann at kit dot edu )
18 * @date 2019
19 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20 * GNU General Public License
21 */
22
24
25#include <pcl/common/io.h>
26
28
30
31#include "segments.h"
32
33namespace visionx
34{
35
37
38 void
40 pcl::PointCloud<PointL>::ConstPtr inputCloud,
41 bool isLabeled)
42 {
43 // Todo: replace with real exception.
44 ARMARX_CHECK(inputCloud) << "Passed input cloud must not be null (name: " << name << ").";
45
46 if (isLabeled)
47 {
48 inputLabeledClouds[name] = inputCloud;
49 changed = true;
50 }
51 else
52 {
53 pcl::PointCloud<PointT>::Ptr unlabeled(new pcl::PointCloud<PointT>);
54 pcl::copyPointCloud(*inputCloud, *unlabeled);
55 setInputPointCloud(name, unlabeled);
56 }
57 }
58
59 void
61 pcl::PointCloud<PointL>::ConstPtr inputCloud,
62 visionx::PointContentType originalType)
63 {
64 setInputPointCloud(name, inputCloud, visionx::tools::isLabeled(originalType));
65 }
66
67 void
69 pcl::PointCloud<PointT>::ConstPtr inputCloud)
70 {
71 // Todo: replace with real exception.
72 ARMARX_CHECK(inputCloud) << "Passed input cloud must not be null (name: " << name << ").";
73
74 inputUnlabeledClouds[name] = inputCloud;
75 changed = true;
76 // Remove potential converted clouds.
77 inputLabeledClouds.erase(name);
78 }
79
80 auto
81 MergedLabeledPointCloud::getResultPointCloud() -> pcl::PointCloud<PointL>::Ptr
82 {
83 // Rebuild result cloud if necessary.
84 if (changed)
85 {
86 // Relabel unlabeled point clouds if necessary.
87 if (!inputUnlabeledClouds.empty())
88 {
89 // Get used labels and label unlabeled clouds.
90 labelUnlabeledClouds(getUsedLabels());
91 }
92
93 mergeLabeledClouds();
94 changed = false;
95 }
96
97 return resultCloud;
98 }
99
100 auto
101 MergedLabeledPointCloud::getUsedLabels() const -> std::set<Label>
102 {
103 // Get used labels.
104 std::set<Label> usedLabels;
105 for (const auto& [name, cloud] : inputLabeledClouds)
106 {
107 for (const auto& point : cloud->points)
108 {
109 usedLabels.insert(point.label);
110 }
111 }
112 return usedLabels;
113 }
114
115 void
116 MergedLabeledPointCloud::labelUnlabeledClouds(const std::set<Label>& usedLabels)
117 {
118 // Start assigning new labels.
119 Label label = 1;
120 for (const auto& [name, unlabeled] : inputUnlabeledClouds)
121 {
122 // Find unused label.
123 while (usedLabels.count(label) > 0)
124 {
125 ++label;
126 }
127
128 // Construct labelled cloud.
129 pcl::PointCloud<PointL>::Ptr labeled(new pcl::PointCloud<PointL>);
130 pcl::copyPointCloud(*unlabeled, *labeled);
131 for (auto& point : labeled->points)
132 {
133 point.label = label;
134 }
135
136 // Store labeled cloud (overwriting old relabeled clouds with the same name).
137 inputLabeledClouds[name] = labeled;
138 }
139 // Remove old unlabeled clouds.
140 inputUnlabeledClouds.clear();
141 }
142
143 void
144 MergedLabeledPointCloud::mergeLabeledClouds()
145 {
146 // Build result point cloud.
147 resultCloud->clear();
148 uint64_t timestamp = 0; // Use highest timestamp for result cloud.
149 for (const auto& [name, cloud] : inputLabeledClouds)
150 {
151 ARMARX_CHECK(cloud);
152 if (cloud)
153 {
154 (*resultCloud) += *cloud;
155 }
156 timestamp = std::max(timestamp, cloud->header.stamp);
157 }
158 resultCloud->header.stamp = timestamp;
159 }
160
161} // namespace visionx
std::string timestamp()
pcl::PointCloud< PointL >::Ptr getResultPointCloud()
Get the result point cloud.
void setInputPointCloud(const std::string &name, pcl::PointCloud< PointL >::ConstPtr inputCloud, bool isLabeled=true)
Set a (new) labeled or unlabeled input point cloud.
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
bool isLabeled(PointContentType type)
ArmarX headers.