31#include <pcl/common/colors.h>
32#include <pcl/filters/crop_box.h>
54 lastProcessedTimestamp = 0;
63 ARMARX_INFO <<
"Using the segmentation method " << segmentationMethod <<
flush;
68 ARMARX_INFO <<
"Starting " << (enabled ?
"Enabled" :
"Disabled");
85 if (segmentationMethod ==
"LCCP")
88 pLCCP->UpdateParameters(voxelRes,
97 else if (segmentationMethod ==
"RG")
100 pRGSegmenter->UpdateRegionGrowingSegmentationParameters(rgSmoothnessThes,
103 else if (segmentationMethod ==
"EC")
107 else if (segmentationMethod ==
"DS")
119 if (!debugDrawerTopic)
124 if (segmentationMethod ==
"DS")
128 if (!deepSegmenterTopic)
165 delete pDeepSegmenter;
173 std::unique_lock lock(enableMutex);
183 ARMARX_WARNING <<
"Timeout or error while waiting for point cloud data"
207 ARMARX_INFO <<
"Point cloud received (size: " << inputCloudPtr->points.size()
208 <<
", providerName: " << providerName <<
")";
212 IceUtil::Int64 originalTimestamp = info->timeProvided;
214 IceUtil::Time ts = IceUtil::Time::microSeconds(originalTimestamp);
215 std::string timestampString = ts.toDateTime().substr(ts.toDateTime().find(
' ') + 1);
217 IceUtil::Time start_ts = IceUtil::Time::now();
219 ARMARX_INFO <<
"Point cloud received (timestamp: " << timestampString
220 <<
", size: " << inputCloudPtr->points.size()
221 <<
", providerName: " << providerName <<
")";
222 if (inputCloudPtr->points.size() == 0)
227 if (segmentationMethod ==
"LCCP")
229 pcl::PointCloud<pcl::PointXYZL>::Ptr labeledPCPtr =
230 pLCCP->GetLabeledPointCloud(inputCloudPtr);
231 labeledColoredCloudPtr.reset(
232 new pcl::PointCloud<PointRGBL>());
234 if (inputCloudPtr->size() != labeledPCPtr->size())
236 ARMARX_WARNING <<
"Point cloud size mismatch (RGB: " << inputCloudPtr->size()
237 <<
", XYZL: " << labeledPCPtr->size() <<
"), skipping current frame";
242 pcl::concatenateFields(*inputCloudPtr, *labeledPCPtr, *labeledColoredCloudPtr);
243 ARMARX_INFO <<
" computed supervoxelcluster size: "
244 << pLCCP->GetSuperVoxelClusterSize();
246 << labeledColoredCloudPtr->points.size();
248 else if (segmentationMethod ==
"RG")
250 pRGSegmenter->UpdateRegionGrowingSegmentationParameters(rgSmoothnessThes,
252 auto colorizedLabeledCloudPtr = pRGSegmenter->ApplyRegionGrowingSegmentation(
254 pcl::PointCloud<pcl::PointXYZL>::Ptr labeledPCPtr(
255 new pcl::PointCloud<pcl::PointXYZL>());
256 convertFromXYZRGBAtoXYZL(
257 colorizedLabeledCloudPtr,
259 labeledColoredCloudPtr.reset(
new pcl::PointCloud<PointRGBL>());
260 pcl::concatenateFields(*inputCloudPtr, *labeledPCPtr, *labeledColoredCloudPtr);
262 else if (segmentationMethod ==
"EC")
264 labeledColoredCloudPtr = pECSegmenter->GetLabeledPointCloud(inputCloudPtr);
266 else if (segmentationMethod ==
"DS")
268 if (!deepSegmenterTopic)
274 if (!inputCloudPtr->isOrganized())
281 rgbImage = pDeepSegmenter->GetImageFromPointCloud(inputCloudPtr);
283 deepSegmenterTopic->setImageDimensions(inputCloudPtr->width, inputCloudPtr->height);
284 armarx::Blob deepSegmentImage = deepSegmenterTopic->segmentImage(rgbImage);
286 labeledColoredCloudPtr =
287 pDeepSegmenter->GetLabeledPointCloud(inputCloudPtr, deepSegmentImage);
291 labeledColoredCloudPtr->header.stamp = originalTimestamp;
294 std::unique_lock lock(enableMutex);
302 std::unique_lock lock(timestampMutex);
303 lastProcessedTimestamp = originalTimestamp;
309 << (IceUtil::Time::now() - start_ts).toSecondsDouble() <<
" secs";
313 ARMARX_WARNING <<
"PointCloudSegmenter configured to run only once";
328 std::unique_lock lock(enableMutex);
337 std::unique_lock lock(enableMutex);
345 const Ice::Current&
c)
347 std::unique_lock lock(providerMutex);
349 ARMARX_INFO <<
"Changing point cloud provider to '" << providerName <<
"'";
354 this->providerName = providerName;
361 PointCloudSegmenter::convertFromXYZRGBAtoXYZL(
362 pcl::PointCloud<pcl::PointXYZRGBA>::Ptr& sourceCloudPtr,
363 pcl::PointCloud<pcl::PointXYZL>::Ptr& targetCloudPtr)
365 targetCloudPtr->resize(sourceCloudPtr->points.size());
366 uint32_t newLabel = 1;
375 std::map<uint32_t, rgbValues> colorMap;
378 for (
size_t i = 0; i < sourceCloudPtr->points.size(); i++)
381 currRGB.rVal = (int)sourceCloudPtr->points[i].r;
382 currRGB.gVal = (int)sourceCloudPtr->points[i].g;
383 currRGB.bVal = (int)sourceCloudPtr->points[i].b;
385 bool isFound =
false;
386 uint32_t foundLabel = 0;
389 std::map<uint32_t, rgbValues>::iterator iter_i;
391 for (iter_i = colorMap.begin(); iter_i != colorMap.end(); iter_i++)
393 if (currRGB.rVal == iter_i->second.rVal && currRGB.gVal == iter_i->second.gVal &&
394 currRGB.bVal == iter_i->second.bVal)
396 foundLabel = iter_i->first;
404 colorMap[newLabel] = currRGB;
405 foundLabel = newLabel;
409 targetCloudPtr->points[i].x = sourceCloudPtr->points[i].x;
410 targetCloudPtr->points[i].y = sourceCloudPtr->points[i].y;
411 targetCloudPtr->points[i].z = sourceCloudPtr->points[i].z;
412 targetCloudPtr->points[i].label = foundLabel;
419 std::unique_lock lock(enableMutex);
423 armarx::TimestampBasePtr
426 std::unique_lock lock(timestampMutex);
433 ARMARX_INFO <<
"Updating LCCP parameter setup (current segmentation method is "
434 << segmentationMethod <<
")";
435 pLCCP->UpdateParameters(parameters.voxelResolution,
436 parameters.seedResolution,
437 parameters.colorImportance,
438 parameters.spatialImportance,
439 parameters.normalImportance,
440 parameters.concavityThreshold,
441 parameters.smoothnessThreshold,
442 parameters.minSegmentSize);
447 const Ice::Current&
c)
449 std::string absolute_filename;
452 ARMARX_INFO <<
"Loading LCCP parameter setup from " << absolute_filename;
453 QSettings config(QString::fromStdString(absolute_filename), QSettings::IniFormat);
455 config.beginGroup(
"LCCP");
456 pLCCP->UpdateParameters(
466 config.value(
"NormalImportance",
getProperty<float>(
"lccpNormalImportance").getValue())
469 .value(
"ConcavityThreshold",
473 .value(
"SmoothnessThreshold",
476 config.value(
"MinSegmentSize",
getProperty<int>(
"lccpMinimumSegmentSize").getValue())
484 LccpParameters parameters;
486 parameters.voxelResolution = pLCCP->voxel_resolution;
487 parameters.seedResolution = pLCCP->seed_resolution;
488 parameters.colorImportance = pLCCP->color_importance;
489 parameters.spatialImportance = pLCCP->spatial_importance;
490 parameters.normalImportance = pLCCP->normal_importance;
491 parameters.concavityThreshold = pLCCP->concavity_tolerance_threshold;
492 parameters.smoothnessThreshold = pLCCP->smoothness_threshold;
493 parameters.minSegmentSize = pLCCP->min_segment_size;
501 float curvatureThreshold,
502 const Ice::Current&
c)
505 pRGSegmenter->UpdateRegionGrowingSegmentationParameters(smoothnessThreshold,
511 const Ice::Current&
c)
513 std::string absolute_filename;
516 ARMARX_INFO <<
"Loading RG parameter setup from " << absolute_filename;
517 QSettings config(QString::fromStdString(absolute_filename), QSettings::IniFormat);
519 config.beginGroup(
"RG");
520 pRGSegmenter->UpdateRegionGrowingSegmentationParameters(
522 .value(
"SmoothnessThreshold",
537 tab.rgSmoothnessThreshold.setRange(1.0, 20.0);
538 tab.rgSmoothnessThreshold.setSteps(200);
539 tab.rgSmoothnessThreshold.setValue(rgSmoothnessThes);
540 tab.rgSmoothnessThreshold.setDecimals(3);
541 grid.
add(
Label(
"rgSmoothnessThreshold:"),
Pos{row, 0});
542 grid.
add(tab.rgSmoothnessThreshold,
Pos{row, 1});
546 tab.rgCurvatureThreshold.setRange(1.0, 50.0);
547 tab.rgCurvatureThreshold.setSteps(200);
548 tab.rgCurvatureThreshold.setValue(rgCurvatureThres);
549 tab.rgCurvatureThreshold.setDecimals(3);
550 grid.
add(
Label(
"rgCurvatureThreshold:"),
Pos{row, 0});
551 grid.
add(tab.rgCurvatureThreshold,
Pos{row, 1});
561 rgSmoothnessThes = tab.rgSmoothnessThreshold.getValue();
562 rgCurvatureThres = tab.rgCurvatureThreshold.getValue();
569 return "PointCloudSegmenter";
int Label(int n[], int size, int *curLabel, MiscLib::Vector< std::pair< int, size_t > > *labels)
#define ARMARX_REGISTER_COMPONENT_EXECUTABLE(ComponentT, applicationName)
static bool getAbsolutePath(const std::string &relativeFilename, std::string &storeAbsoluteFilename, const std::vector< std::string > &additionalSearchPaths={}, bool verbose=true)
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Property< PropertyType > getProperty(const std::string &name)
void offeringTopic(const std::string &name)
Registers a topic for retrival after initialization.
TopicProxyType getTopic(const std::string &name)
Returns a proxy of the specified topic.
bool usingProxy(const std::string &name, const std::string &endpoints="")
Registers a proxy for retrieval after initialization and adds it to the dependency list.
Ice::ObjectPrx getProxy(long timeoutMs=0, bool waitForScheduler=true) const
Returns the proxy of this object (optionally it waits for the proxy)
Implements a Variant type for timestamps.
void releasePointCloudProvider(std::string providerName)
Removes topic subscription and provider proxy dependency to release a point cloud provider.
void enableResultPointClouds(std::string resultProviderName="")
Enables visualization.
virtual void onDisconnectComponent() override
int getPointClouds(const PointCloudPtrT &pointCloudPtr)
Poll PointClouds from provider.
MetaPointCloudFormatPtr getPointCloudFormat(std::string providerName)
void usingPointCloudProvider(std::string providerName)
Registers a delayed topic subscription and a delayed provider proxy retrieval which will be available...
virtual void onConnectComponent() override
bool waitForPointClouds(int milliseconds=1000)
Wait for new PointClouds.
void provideResultPointClouds(const PointCloudPtrT &pointClouds, std::string providerName="")
sends result PointClouds for visualization
void loadLccpParametersFromFile(const std::string &filename, const Ice::Current &c=Ice::emptyCurrent) override
void RemoteGui_update() override
void onExitPointCloudProcessor() override
LccpParameters getLccpParameters(const Ice::Current &c=Ice::emptyCurrent) override
void enablePipelineStep(const Ice::Current &c=Ice::emptyCurrent) override
void onConnectPointCloudProcessor() override
void disablePipelineStep(const Ice::Current &c=Ice::emptyCurrent) override
armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
void onDisconnectPointCloudProcessor() override
static std::string GetDefaultName()
void changePointCloudProvider(const std::string &providerName, const Ice::Current &c=Ice::emptyCurrent) override
void setRgParameters(float smoothnessThreshold, float curvatureThreshold, const Ice::Current &c=Ice::emptyCurrent) override
void setLccpParameters(const LccpParameters ¶meters, const Ice::Current &c=Ice::emptyCurrent) override
void loadRgParametersFromFile(const std::string &filename, const Ice::Current &c=Ice::emptyCurrent) override
void onInitPointCloudProcessor() override
void createRemoteGuiTab()
armarx::TimestampBasePtr getLastProcessedTimestamp(const Ice::Current &c=Ice::emptyCurrent) override
std::string getDefaultName() const override
Retrieve default name of component.
bool isPipelineStepEnabled(const Ice::Current &c=Ice::emptyCurrent) override
#define ARMARX_INFO
The normal logging level.
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
This file offers overloads of toIce() and fromIce() functions for STL container types.
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
const LogSender::manipulator flush
pcl::PointXYZRGBL PointRGBL
pcl::PointCloud< Point > PointCloud
void RemoteGui_startRunningTask()
void RemoteGui_createTab(std::string const &name, RemoteGui::Client::Widget const &rootWidget, RemoteGui::Client::Tab *tab)
GridLayout & add(Widget const &child, Pos pos, Span span=Span{1, 1})