12 #include <ros/console.h>
17 #include <sys/resource.h>
19 #include <opencv2/ml.hpp>
20 #include <pcl/point_types.h>
21 #include <pcl/point_cloud.h>
22 #include <pcl/segmentation/extract_clusters.h>
24 #include <Eigen/Dense>
27 #include <bmm/bayesian_mixture_model.hpp>
48 constexpr
double MIN_RETENTION_RATIO = 0.10;
56 DepthRenderer(cv::Mat& z_buffer_)
57 :
geo::RenderResult(z_buffer_.cols, z_buffer_.rows), z_buffer(z_buffer_)
63 float& old_depth = z_buffer.at<
float>(y, x);
64 if (old_depth == 0 || depth < old_depth)
78 const geo::Pose3D& sensor_pose,
double background_padding)
85 DepthRenderer res(depth_model);
89 if (!e->visual() || !e->has_pose())
93 opt.
setMesh(e->visual()->getMesh(), sensor_pose.
inverse() * e->pose());
101 for(
unsigned int i = 0; i < size; ++i)
104 float dm = depth_model.at<
float>(i);
105 if (dm > 0 && ds > 0 && ds > dm - background_padding)
119 min_buffer = cv::Mat(height, width, CV_32FC1, 0.0);
120 max_buffer = cv::Mat(height, width, CV_32FC1, 0.0);
134 if (d_min == 0 || depth < d_min)
148 const geo::Pose3D& shape_pose, cv::Mat& filtered_depth_image)
const
164 cam_model.
render(opt, res);
177 if (d_min > 0 && d_max > 0 && d >= d_min && d <= d_max)
178 filtered_depth_image.at<
float>(i) = d;
185 const cv::Mat& filtered_depth_image)
const
188 for (
int y = 0; y <
rgb_image.rows; ++y) {
189 const float* depth_row = filtered_depth_image.ptr<
float>(y);
190 cv::Vec3b* out_row = masked_rgb.ptr<cv::Vec3b>(y);
191 const cv::Vec3b* rgb_row =
rgb_image.ptr<cv::Vec3b>(y);
192 for (
int x = 0; x <
rgb_image.cols; ++x) {
193 if (depth_row[x] > 0.f) {
194 out_row[x] = rgb_row[x];
207 ROS_DEBUG(
"Cluster with depth image of size %i, %i", width, height);
210 ROS_DEBUG(
"Creating clusters");
217 #pragma omp parallel for schedule(dynamic)
218 for (
size_t i = 0; i < masks.
size(); ++i)
220 const cv::Mat& mask = masks[i];
224 for(
int y = 0; y < mask.rows; ++y) {
225 for(
int x = 0; x < mask.cols; ++x) {
226 if (mask.at<
unsigned char>(y, x) > 0) {
227 unsigned int pixel_idx = y * width + x;
231 cluster.pixel_indices.push_back(pixel_idx);
239 if (
cluster.pixel_indices.size() < MIN_CLUSTER_POINTS) {
251 MAPGMM gmm(2,
cluster.points, params);
252 gmm.fit(
cluster.points, sensor_pose);
255 int inlier_component = gmm.get_inlier_component();
261 for (
size_t j = 0; j < labels.
size(); j++)
263 if (labels[j] == inlier_component)
274 if (filtered_points.
size() > MIN_FILTERED_POINTS &&
275 filtered_points.
size() > MIN_RETENTION_RATIO *
cluster.points.size()) {
277 cluster.points = filtered_points;
280 cluster.outlier_points = outlier_points;
291 ROS_DEBUG(
"GMM filtering rejected: retained %zu/%zu points",
300 for(
unsigned int j = 0; j <
cluster.points.size(); ++j)
307 z_min = std::min<float>(z_min, p_map.
z);
308 z_max = std::max<float>(z_max, p_map.
z);
312 cluster.chull.complete =
false;
316 valid_cluster[i] =
true;
322 for (
size_t i = 0; i < temp_clusters.
size(); ++i) {
323 if (valid_cluster[i]) {
324 clusters.
push_back(std::move(temp_clusters[i]));