29 #include <pcl/common/colors.h>
30 #include <pcl/filters/crop_box.h>
43 PointCloudSegmenter::PointCloudSegmenter() :
52 lastProcessedTimestamp = 0;
55 providerName = getProperty<std::string>(
"ProviderName").getValue();
60 segmentationMethod = getProperty<std::string>(
"segmentationMethod").getValue();
61 ARMARX_INFO <<
"Using the segmentation method " << segmentationMethod <<
flush;
63 offeringTopic(getProperty<std::string>(
"DebugDrawerTopicName").getValue());
65 enabled = getProperty<bool>(
"StartEnabled").getValue();
66 ARMARX_INFO <<
"Starting " << (enabled ?
"Enabled" :
"Disabled");
69 minSegSize = getProperty<int>(
"lccpMinimumSegmentSize").getValue();
70 voxelRes = getProperty<float>(
"lccpVoxelResolution").getValue();
71 seedRes = getProperty<float>(
"lccpSeedResolution").getValue();
72 colorImp = getProperty<float>(
"lccpColorImportance").getValue();
73 spatialImp = getProperty<float>(
"lccpSpatialImportance").getValue();
74 normalImp = getProperty<float>(
"lccpNormalImportance").getValue();
75 concavityThres = getProperty<float>(
"lccpConcavityThreshold").getValue();
76 smoothnessThes = getProperty<float>(
"lccpSmoothnessThreshold").getValue();
79 rgSmoothnessThes = getProperty<float>(
"rgSmoothnessThreshold").getValue();
80 rgCurvatureThres = getProperty<float>(
"rgCurvatureThreshold").getValue();
83 if (segmentationMethod ==
"LCCP")
95 else if (segmentationMethod ==
"RG")
101 else if (segmentationMethod ==
"EC")
105 else if (segmentationMethod ==
"DS")
107 usingProxy(getProperty<std::string>(
"DeepSegmenterTopicName").getValue());
115 debugDrawerTopic = getTopic<armarx::DebugDrawerInterfacePrx>(
116 getProperty<std::string>(
"DebugDrawerTopicName").getValue());
117 if (!debugDrawerTopic)
122 if (segmentationMethod ==
"DS")
124 deepSegmenterTopic = getProxy<armarx::DeepSegmenterInterfacePrx>(
125 getProperty<std::string>(
"DeepSegmenterTopicName").getValue());
126 if (!deepSegmenterTopic)
132 enableResultPointClouds<PointRGBL>();
163 delete pDeepSegmenter;
171 std::unique_lock lock(enableMutex);
181 ARMARX_WARNING <<
"Timeout or error while waiting for point cloud data"
205 ARMARX_INFO <<
"Point cloud received (size: " << inputCloudPtr->points.size()
206 <<
", providerName: " << providerName <<
")";
210 IceUtil::Int64 originalTimestamp = info->timeProvided;
212 IceUtil::Time ts = IceUtil::Time::microSeconds(originalTimestamp);
213 std::string timestampString = ts.toDateTime().substr(ts.toDateTime().find(
' ') + 1);
217 ARMARX_INFO <<
"Point cloud received (timestamp: " << timestampString
218 <<
", size: " << inputCloudPtr->points.size()
219 <<
", providerName: " << providerName <<
")";
220 if (inputCloudPtr->points.size() == 0)
225 if (segmentationMethod ==
"LCCP")
227 pcl::PointCloud<pcl::PointXYZL>::Ptr labeledPCPtr =
229 labeledColoredCloudPtr.reset(
230 new pcl::PointCloud<PointRGBL>());
232 if (inputCloudPtr->size() != labeledPCPtr->size())
234 ARMARX_WARNING <<
"Point cloud size mismatch (RGB: " << inputCloudPtr->size()
235 <<
", XYZL: " << labeledPCPtr->size() <<
"), skipping current frame";
240 pcl::concatenateFields(*inputCloudPtr, *labeledPCPtr, *labeledColoredCloudPtr);
241 ARMARX_INFO <<
" computed supervoxelcluster size: "
244 << labeledColoredCloudPtr->points.size();
246 else if (segmentationMethod ==
"RG")
252 pcl::PointCloud<pcl::PointXYZL>::Ptr labeledPCPtr(
253 new pcl::PointCloud<pcl::PointXYZL>());
254 convertFromXYZRGBAtoXYZL(
255 colorizedLabeledCloudPtr,
257 labeledColoredCloudPtr.reset(
new pcl::PointCloud<PointRGBL>());
258 pcl::concatenateFields(*inputCloudPtr, *labeledPCPtr, *labeledColoredCloudPtr);
260 else if (segmentationMethod ==
"EC")
264 else if (segmentationMethod ==
"DS")
266 if (!deepSegmenterTopic)
272 if (!inputCloudPtr->isOrganized())
281 deepSegmenterTopic->setImageDimensions(inputCloudPtr->width, inputCloudPtr->height);
282 armarx::Blob deepSegmentImage = deepSegmenterTopic->segmentImage(rgbImage);
284 labeledColoredCloudPtr =
289 labeledColoredCloudPtr->header.stamp = originalTimestamp;
292 std::unique_lock lock(enableMutex);
300 std::unique_lock lock(timestampMutex);
301 lastProcessedTimestamp = originalTimestamp;
307 << (IceUtil::Time::now() - start_ts).toSecondsDouble() <<
" secs";
309 if (getProperty<bool>(
"SingleRun").getValue())
311 ARMARX_WARNING <<
"PointCloudSegmenter configured to run only once";
326 std::unique_lock lock(enableMutex);
335 std::unique_lock lock(enableMutex);
343 const Ice::Current&
c)
345 std::unique_lock lock(providerMutex);
347 ARMARX_INFO <<
"Changing point cloud provider to '" << providerName <<
"'";
352 this->providerName = providerName;
359 PointCloudSegmenter::convertFromXYZRGBAtoXYZL(
360 pcl::PointCloud<pcl::PointXYZRGBA>::Ptr& sourceCloudPtr,
361 pcl::PointCloud<pcl::PointXYZL>::Ptr& targetCloudPtr)
363 targetCloudPtr->resize(sourceCloudPtr->points.size());
364 uint32_t newLabel = 1;
373 std::map<uint32_t, rgbValues> colorMap;
376 for (
size_t i = 0; i < sourceCloudPtr->points.size(); i++)
379 currRGB.rVal = (int)sourceCloudPtr->points[i].r;
380 currRGB.gVal = (
int)sourceCloudPtr->points[i].g;
381 currRGB.bVal = (int)sourceCloudPtr->points[i].b;
383 bool isFound =
false;
384 uint32_t foundLabel = 0;
387 std::map<uint32_t, rgbValues>::iterator iter_i;
389 for (iter_i = colorMap.begin(); iter_i != colorMap.end(); iter_i++)
391 if (currRGB.rVal == iter_i->second.rVal && currRGB.gVal == iter_i->second.gVal &&
392 currRGB.bVal == iter_i->second.bVal)
394 foundLabel = iter_i->first;
402 colorMap[newLabel] = currRGB;
403 foundLabel = newLabel;
407 targetCloudPtr->points[i].x = sourceCloudPtr->points[i].x;
408 targetCloudPtr->points[i].y = sourceCloudPtr->points[i].y;
409 targetCloudPtr->points[i].z = sourceCloudPtr->points[i].z;
410 targetCloudPtr->points[i].label = foundLabel;
417 std::unique_lock lock(enableMutex);
421 armarx::TimestampBasePtr
424 std::unique_lock lock(timestampMutex);
431 ARMARX_INFO <<
"Updating LCCP parameter setup (current segmentation method is "
432 << segmentationMethod <<
")";
434 parameters.seedResolution,
435 parameters.colorImportance,
436 parameters.spatialImportance,
437 parameters.normalImportance,
438 parameters.concavityThreshold,
439 parameters.smoothnessThreshold,
440 parameters.minSegmentSize);
445 const Ice::Current&
c)
447 std::string absolute_filename;
448 ArmarXDataPath::getAbsolutePath(
filename, absolute_filename);
450 ARMARX_INFO <<
"Loading LCCP parameter setup from " << absolute_filename;
451 QSettings config(QString::fromStdString(absolute_filename), QSettings::IniFormat);
453 config.beginGroup(
"LCCP");
455 config.value(
"VoxelResolution", getProperty<float>(
"lccpVoxelResolution").getValue())
457 config.value(
"SeedResolution", getProperty<float>(
"lccpSeedResolution").getValue())
459 config.value(
"ColorImportance", getProperty<float>(
"lccpColorImportance").getValue())
462 .value(
"SpatialImportance", getProperty<float>(
"lccpSpatialImportance").getValue())
464 config.value(
"NormalImportance", getProperty<float>(
"lccpNormalImportance").getValue())
467 .value(
"ConcavityThreshold",
468 getProperty<float>(
"lccpConcavityThreshold").getValue())
471 .value(
"SmoothnessThreshold",
472 getProperty<float>(
"lccpSmoothnessThreshold").getValue())
474 config.value(
"MinSegmentSize", getProperty<int>(
"lccpMinimumSegmentSize").getValue())
482 LccpParameters parameters;
484 parameters.voxelResolution = pLCCP->voxel_resolution;
485 parameters.seedResolution = pLCCP->seed_resolution;
486 parameters.colorImportance = pLCCP->color_importance;
487 parameters.spatialImportance = pLCCP->spatial_importance;
488 parameters.normalImportance = pLCCP->normal_importance;
489 parameters.concavityThreshold = pLCCP->concavity_tolerance_threshold;
490 parameters.smoothnessThreshold = pLCCP->smoothness_threshold;
491 parameters.minSegmentSize = pLCCP->min_segment_size;
499 float curvatureThreshold,
500 const Ice::Current&
c)
509 const Ice::Current&
c)
511 std::string absolute_filename;
512 ArmarXDataPath::getAbsolutePath(
filename, absolute_filename);
514 ARMARX_INFO <<
"Loading RG parameter setup from " << absolute_filename;
515 QSettings config(QString::fromStdString(absolute_filename), QSettings::IniFormat);
517 config.beginGroup(
"RG");
520 .
value(
"SmoothnessThreshold",
521 getProperty<double>(
"rgSmoothnessThreshold").getValue())
524 .
value(
"CurvatureThreshold", getProperty<double>(
"rgCurvatureThreshold").getValue())
539 grid.
add(
Label(
"rgSmoothnessThreshold:"),
Pos{row, 0});
548 grid.
add(
Label(
"rgCurvatureThreshold:"),
Pos{row, 0});