34 #include <pcl/common/colors.h>
35 #include <pcl/filters/crop_box.h>
42 PointCloudSegmenter::PointCloudSegmenter() :
50 lastProcessedTimestamp = 0;
53 providerName = getProperty<std::string>(
"ProviderName").getValue();
58 segmentationMethod = getProperty<std::string>(
"segmentationMethod").getValue();
59 ARMARX_INFO <<
"Using the segmentation method " << segmentationMethod <<
flush;
61 offeringTopic(getProperty<std::string>(
"DebugDrawerTopicName").getValue());
63 enabled = getProperty<bool>(
"StartEnabled").getValue();
64 ARMARX_INFO <<
"Starting " << (enabled ?
"Enabled" :
"Disabled");
67 minSegSize = getProperty<int>(
"lccpMinimumSegmentSize").getValue();
68 voxelRes = getProperty<float>(
"lccpVoxelResolution").getValue();
69 seedRes = getProperty<float>(
"lccpSeedResolution").getValue();
70 colorImp = getProperty<float>(
"lccpColorImportance").getValue();
71 spatialImp = getProperty<float>(
"lccpSpatialImportance").getValue();
72 normalImp = getProperty<float>(
"lccpNormalImportance").getValue();
73 concavityThres = getProperty<float>(
"lccpConcavityThreshold").getValue();
74 smoothnessThes = getProperty<float>(
"lccpSmoothnessThreshold").getValue();
77 rgSmoothnessThes = getProperty<float>(
"rgSmoothnessThreshold").getValue();
78 rgCurvatureThres = getProperty<float>(
"rgCurvatureThreshold").getValue();
81 if (segmentationMethod ==
"LCCP")
84 pLCCP->
UpdateParameters(voxelRes, seedRes, colorImp, spatialImp, normalImp, concavityThres, smoothnessThes, minSegSize);
86 else if (segmentationMethod ==
"RG")
91 else if (segmentationMethod ==
"EC")
95 else if (segmentationMethod ==
"DS")
97 usingProxy(getProperty<std::string>(
"DeepSegmenterTopicName").getValue());
104 debugDrawerTopic = getTopic<armarx::DebugDrawerInterfacePrx>(getProperty<std::string>(
"DebugDrawerTopicName").getValue());
105 if (!debugDrawerTopic)
110 if (segmentationMethod ==
"DS")
112 deepSegmenterTopic = getProxy<armarx::DeepSegmenterInterfacePrx>(getProperty<std::string>(
"DeepSegmenterTopicName").getValue());
113 if (!deepSegmenterTopic)
119 enableResultPointClouds<PointRGBL>();
148 delete pDeepSegmenter;
155 std::unique_lock lock(enableMutex);
188 ARMARX_INFO <<
"Point cloud received (size: " << inputCloudPtr->points.size() <<
", providerName: " << providerName <<
")";
192 IceUtil::Int64 originalTimestamp = info->timeProvided;
194 IceUtil::Time ts = IceUtil::Time::microSeconds(originalTimestamp);
195 std::string timestampString = ts.toDateTime().substr(ts.toDateTime().find(
' ') + 1);
199 ARMARX_INFO <<
"Point cloud received (timestamp: " << timestampString <<
", size: " << inputCloudPtr->points.size() <<
", providerName: " << providerName <<
")";
200 if (inputCloudPtr->points.size() == 0)
205 if (segmentationMethod ==
"LCCP")
207 pcl::PointCloud< pcl::PointXYZL >::Ptr labeledPCPtr = pLCCP->
GetLabeledPointCloud(inputCloudPtr);
208 labeledColoredCloudPtr.reset(
new pcl::PointCloud<PointRGBL>());
210 if (inputCloudPtr->size() != labeledPCPtr->size())
212 ARMARX_WARNING <<
"Point cloud size mismatch (RGB: " << inputCloudPtr->size() <<
", XYZL: " << labeledPCPtr->size() <<
"), skipping current frame";
217 pcl::concatenateFields(*inputCloudPtr, *labeledPCPtr, *labeledColoredCloudPtr);
219 ARMARX_INFO <<
" computed labeledCloudPtr size: " << labeledColoredCloudPtr->points.size() ;
221 else if (segmentationMethod ==
"RG")
225 pcl::PointCloud< pcl::PointXYZL >::Ptr labeledPCPtr(
new pcl::PointCloud< pcl::PointXYZL >());
226 convertFromXYZRGBAtoXYZL(colorizedLabeledCloudPtr, labeledPCPtr);
227 labeledColoredCloudPtr.reset(
new pcl::PointCloud<PointRGBL>());
228 pcl::concatenateFields(*inputCloudPtr, *labeledPCPtr, *labeledColoredCloudPtr);
230 else if (segmentationMethod ==
"EC")
234 else if (segmentationMethod ==
"DS")
236 if (!deepSegmenterTopic)
242 if (!inputCloudPtr->isOrganized())
251 deepSegmenterTopic->setImageDimensions(inputCloudPtr->width, inputCloudPtr->height);
252 armarx::Blob deepSegmentImage = deepSegmenterTopic->segmentImage(rgbImage);
259 labeledColoredCloudPtr->header.stamp = originalTimestamp;
262 std::unique_lock lock(enableMutex);
270 std::unique_lock lock(timestampMutex);
271 lastProcessedTimestamp = originalTimestamp;
276 ARMARX_INFO <<
"Point cloud segmentation took " << (IceUtil::Time::now() - start_ts).toSecondsDouble() <<
" secs";
278 if (getProperty<bool>(
"SingleRun").getValue())
280 ARMARX_WARNING <<
"PointCloudSegmenter configured to run only once";
292 std::unique_lock lock(enableMutex);
300 std::unique_lock lock(enableMutex);
308 std::unique_lock lock(providerMutex);
310 ARMARX_INFO <<
"Changing point cloud provider to '" << providerName <<
"'";
315 this->providerName = providerName;
321 void PointCloudSegmenter::convertFromXYZRGBAtoXYZL(pcl::PointCloud<pcl::PointXYZRGBA>::Ptr& sourceCloudPtr, pcl::PointCloud<pcl::PointXYZL>::Ptr& targetCloudPtr)
323 targetCloudPtr->resize(sourceCloudPtr->points.size());
324 uint32_t newLabel = 1;
332 std::map<uint32_t, rgbValues > colorMap;
335 for (
size_t i = 0; i < sourceCloudPtr->points.size(); i++)
338 currRGB.rVal = (int) sourceCloudPtr->points[i].r;
339 currRGB.gVal = (
int) sourceCloudPtr->points[i].g;
340 currRGB.bVal = (int) sourceCloudPtr->points[i].b;
342 bool isFound =
false;
343 uint32_t foundLabel = 0;
346 std::map<uint32_t, rgbValues >::iterator iter_i;
348 for (iter_i = colorMap.begin(); iter_i != colorMap.end(); iter_i++)
350 if (currRGB.rVal == iter_i->second.rVal && currRGB.gVal == iter_i->second.gVal && currRGB.bVal == iter_i->second.bVal)
352 foundLabel = iter_i->first;
360 colorMap[newLabel] = currRGB;
361 foundLabel = newLabel;
365 targetCloudPtr->points[i].x = sourceCloudPtr->points[i].x;
366 targetCloudPtr->points[i].y = sourceCloudPtr->points[i].y;
367 targetCloudPtr->points[i].z = sourceCloudPtr->points[i].z;
368 targetCloudPtr->points[i].label = foundLabel;
374 std::unique_lock lock(enableMutex);
380 std::unique_lock lock(timestampMutex);
386 ARMARX_INFO <<
"Updating LCCP parameter setup (current segmentation method is " << segmentationMethod <<
")";
387 pLCCP->
UpdateParameters(parameters.voxelResolution, parameters.seedResolution, parameters.colorImportance,
388 parameters.spatialImportance, parameters.normalImportance, parameters.concavityThreshold,
389 parameters.smoothnessThreshold, parameters.minSegmentSize);
394 std::string absolute_filename;
395 ArmarXDataPath::getAbsolutePath(
filename, absolute_filename);
397 ARMARX_INFO <<
"Loading LCCP parameter setup from " << absolute_filename;
398 QSettings config(QString::fromStdString(absolute_filename), QSettings::IniFormat);
400 config.beginGroup(
"LCCP");
402 config.value(
"VoxelResolution", getProperty<float>(
"lccpVoxelResolution").getValue()).toFloat(),
403 config.value(
"SeedResolution", getProperty<float>(
"lccpSeedResolution").getValue()).toFloat(),
404 config.value(
"ColorImportance", getProperty<float>(
"lccpColorImportance").getValue()).toFloat(),
405 config.value(
"SpatialImportance", getProperty<float>(
"lccpSpatialImportance").getValue()).toFloat(),
406 config.value(
"NormalImportance", getProperty<float>(
"lccpNormalImportance").getValue()).toFloat(),
407 config.value(
"ConcavityThreshold", getProperty<float>(
"lccpConcavityThreshold").getValue()).toFloat(),
408 config.value(
"SmoothnessThreshold", getProperty<float>(
"lccpSmoothnessThreshold").getValue()).toFloat(),
409 config.value(
"MinSegmentSize", getProperty<int>(
"lccpMinimumSegmentSize").getValue()).toInt()
417 LccpParameters parameters;
419 parameters.voxelResolution = pLCCP->voxel_resolution;
420 parameters.seedResolution = pLCCP->seed_resolution;
421 parameters.colorImportance = pLCCP->color_importance;
422 parameters.spatialImportance = pLCCP->spatial_importance;
423 parameters.normalImportance = pLCCP->normal_importance;
424 parameters.concavityThreshold = pLCCP->concavity_tolerance_threshold;
425 parameters.smoothnessThreshold = pLCCP->smoothness_threshold;
426 parameters.minSegmentSize = pLCCP->min_segment_size;
440 std::string absolute_filename;
441 ArmarXDataPath::getAbsolutePath(
filename, absolute_filename);
443 ARMARX_INFO <<
"Loading RG parameter setup from " << absolute_filename;
444 QSettings config(QString::fromStdString(absolute_filename), QSettings::IniFormat);
446 config.beginGroup(
"RG");
448 config.value(
"SmoothnessThreshold", getProperty<double>(
"rgSmoothnessThreshold").getValue()).toDouble(),
449 config.value(
"CurvatureThreshold", getProperty<double>(
"rgCurvatureThreshold").getValue()).toDouble()
463 grid.
add(
Label(
"rgSmoothnessThreshold:"),
Pos{row, 0});
472 grid.
add(
Label(
"rgCurvatureThreshold:"),
Pos{row, 0});