39 #include <pcl/features/organized_edge_detection.h> 40 #include <pcl/features/integral_image_normal.h> 44 #include <std_msgs/ColorRGBA.h> 47 #include <opencv2/opencv.hpp> 48 #include <jsk_recognition_msgs/ClusterPointIndices.h> 54 ConnectionBasedNodelet::onInit();
59 srv_ = boost::make_shared <dynamic_reconfigure::Server<Config> > (*pnh_);
60 dynamic_reconfigure::Server<Config>::CallbackType
f =
62 srv_->setCallback (f);
67 = advertise<PCLIndicesMsg>(*
pnh_,
"output_nan_boundary_edge_indices", 1);
69 = advertise<PCLIndicesMsg>(*
pnh_,
"output_occluding_edge_indices", 1);
71 = advertise<PCLIndicesMsg>(*
pnh_,
"output_occluded_edge_indices", 1);
73 = advertise<PCLIndicesMsg>(*
pnh_,
"output_curvature_edge_indices", 1);
75 = advertise<PCLIndicesMsg>(*
pnh_,
"output_rgb_edge_indices", 1);
77 = advertise<PCLIndicesMsg>(*
pnh_,
"output_indices", 1);
79 = advertise<jsk_recognition_msgs::ClusterPointIndices>(*
pnh_,
80 "output_straight_edges_indices", 1);
84 pub_normal_ = advertise<sensor_msgs::PointCloud2>(*
pnh_,
"output_normal", 1);
86 = advertise<sensor_msgs::PointCloud2>(*
pnh_,
"output_nan_boundary_edge", 1);
88 = advertise<sensor_msgs::PointCloud2>(*
pnh_,
"output_occluding_edge", 1);
90 = advertise<sensor_msgs::PointCloud2>(*
pnh_,
"output_occluded_edge", 1);
92 = advertise<sensor_msgs::PointCloud2>(*
pnh_,
"output_curvature_edge", 1);
94 = advertise<sensor_msgs::PointCloud2>(*
pnh_,
"output_rgb_edge", 1);
96 = advertise<sensor_msgs::PointCloud2>(*
pnh_,
"output", 1);
117 const pcl::PointCloud<PointT>::Ptr& input,
118 pcl::PointCloud<pcl::Normal>::Ptr output,
119 const std_msgs::Header&
header)
121 pcl::IntegralImageNormalEstimation<PointT, pcl::Normal> ne;
123 ne.setNormalEstimationMethod (ne.AVERAGE_3D_GRADIENT);
126 ne.setNormalEstimationMethod (ne.COVARIANCE_MATRIX);
129 ne.setNormalEstimationMethod (ne.AVERAGE_DEPTH_CHANGE);
137 ne.setBorderPolicy(pcl::IntegralImageNormalEstimation<PointT, pcl::Normal>::BORDER_POLICY_IGNORE);
140 ne.setBorderPolicy(pcl::IntegralImageNormalEstimation<PointT, pcl::Normal>::BORDER_POLICY_MIRROR);
146 ne.setInputCloud(input);
149 sensor_msgs::PointCloud2 ros_output;
151 ros_output.header =
header;
182 const pcl::PointCloud<PointT>::Ptr& input,
183 const pcl::PointCloud<pcl::Normal>::Ptr& normal,
184 pcl::PointCloud<pcl::Label>::Ptr& output,
185 std::vector<pcl::PointIndices>& label_indices)
187 pcl::OrganizedEdgeFromRGBNormals<PointT, pcl::Normal, pcl::Label> oed;
192 flags |= oed.EDGELABEL_NAN_BOUNDARY;
195 flags |= oed.EDGELABEL_OCCLUDING;
198 flags |= oed.EDGELABEL_OCCLUDED;
201 flags |= oed.EDGELABEL_HIGH_CURVATURE;
204 flags |= oed.EDGELABEL_RGB_CANNY;
206 oed.setEdgeType (flags);
207 oed.setInputNormals(normal);
208 oed.setInputCloud(input);
209 oed.compute(*output, label_indices);
215 const pcl::PointCloud<PointT>::Ptr& cloud,
216 const std::vector<int>& indices,
217 const std_msgs::Header&
header)
224 msg.indices = indices;
230 pcl::PointCloud<PointT>::Ptr
output(
new pcl::PointCloud<PointT>);
231 pcl::copyPointCloud(*cloud, indices, *output);
232 sensor_msgs::PointCloud2 ros_output;
234 ros_output.header =
header;
239 const pcl::PointCloud<PointT>::Ptr& cloud,
240 const std_msgs::Header&
header,
241 const std::vector<std::vector<int> > indices)
244 jsk_recognition_msgs::ClusterPointIndices ros_msg;
246 ros_msg.cluster_indices.resize(indices.size());
247 for (
size_t i = 0; i < indices.size(); i++) {
249 ros_indices.header =
header;
250 ros_indices.indices = indices[i];
251 ros_msg.cluster_indices[i] = ros_indices;
257 const pcl::PointCloud<PointT>::Ptr& cloud,
258 const std::vector<int>& indices,
259 const std_msgs::Header&
header,
260 std::vector<std::vector<int> >& output_indices)
263 cv::Mat mat = cv::Mat(cloud->height, cloud->width, CV_8UC1) * 0;
264 for (
size_t i = 0; i < indices.size(); i++) {
265 int index = indices[i];
266 int index_height = index / cloud->width;
267 int index_width = index % cloud->width;
268 mat.data[index_height * mat.step + index_width * mat.elemSize()] = 255;
271 std::vector<cv::Vec4i>
lines;
272 cv::HoughLinesP(mat, lines,
rho_,
theta_ * CV_PI/180,
274 output_indices.resize(lines.size());
275 std::set<int> all_indices_set(indices.begin(), indices.end());
276 for (
size_t i_line = 0; i_line < lines.size(); i_line++) {
277 std::vector<int> pixels;
278 cv::LineIterator it(mat,
279 cv::Point(lines[i_line][0], lines[i_line][1]),
280 cv::Point(lines[i_line][2], lines[i_line][3]), 4);
281 for(
int i_pixel = 0; i_pixel < it.count; i_pixel++, ++it) {
282 cv::Point
point = it.pos();
283 int flatten_index = point.
x + point.y * cloud->width;
285 if (all_indices_set.find(flatten_index) != all_indices_set.end()) {
286 pixels.push_back(flatten_index);
289 output_indices[i_line] = pixels;
293 cv::cvtColor(mat, color_dst, CV_GRAY2BGR );
294 for(
size_t i = 0; i < lines.size(); i++ )
298 cv::Point(lines[i][0], lines[i][1]),
299 cv::Point(lines[i][2], lines[i][3]),
300 cv::Scalar((uint8_t)(c.b * 255), (uint8_t)(c.g * 255), (uint8_t)(c.r * 255)), 3, 8);
302 sensor_msgs::Image::Ptr ros_edge_image
307 sensor_msgs::Image::Ptr ros_hough_image
316 const sensor_msgs::PointCloud2::ConstPtr&
msg)
319 if (msg->height == 1) {
320 NODELET_ERROR(
"[OrganizedEdgeDetector] organized pointcloud is required");
323 pcl::PointCloud<PointT>::Ptr
cloud(
new pcl::PointCloud<PointT>);
324 pcl::PointCloud<pcl::Normal>::Ptr normal(
new pcl::PointCloud<pcl::Normal>);
325 pcl::PointCloud<pcl::Label>::Ptr
label(
new pcl::PointCloud<pcl::Label>);
326 std::vector<pcl::PointIndices> label_indices;
335 label_indices[1].indices);
337 label_indices[2].indices);
339 label_indices[3].indices);
341 label_indices[4].indices);
343 std::vector<std::vector<int> > straightline_indices;
353 label_indices[0].indices, msg->header);
356 label_indices[1].indices, msg->header);
359 label_indices[2].indices, msg->header);
362 label_indices[3].indices, msg->header);
365 label_indices[4].indices, msg->header);
ros::Publisher pub_occluding_edges_indices_
int max_search_neighbors_
ros::Publisher pub_all_edges_
PLUGINLIB_EXPORT_CLASS(jsk_pcl_ros::OrganizedEdgeDetector, nodelet::Nodelet)
#define NODELET_ERROR(...)
ros::Publisher pub_curvature_edges_indices_
void publish(const boost::shared_ptr< M > &message) const
image_transport::Publisher pub_hough_image_
bool use_straightline_detection_
virtual void estimateNormal(const pcl::PointCloud< PointT >::Ptr &input, pcl::PointCloud< pcl::Normal >::Ptr output, const std_msgs::Header &header)
ros::Publisher pub_occluded_edges_indices_
ros::Publisher pub_occluding_edges_
virtual void unsubscribe()
image_transport::Publisher pub_edge_image_
void fromROSMsg(const sensor_msgs::PointCloud2 &cloud, pcl::PointCloud< T > &pcl_cloud)
ros::Publisher pub_straight_edges_indices_
ros::Publisher pub_normal_
bool publish_debug_image_
ros::Publisher pub_rgb_edges_
ros::Publisher pub_nan_boundary_edges_
boost::shared_ptr< dynamic_reconfigure::Server< Config > > srv_
ros::Publisher pub_curvature_edges_
void output(int index, double value)
void publish(const sensor_msgs::Image &message) const
ros::Publisher pub_all_edges_indices_
ros::Publisher pub_rgb_edges_indices_
ros::Publisher pub_occluded_edges_
virtual void estimateEdge(const pcl::PointCloud< PointT >::Ptr &input, const pcl::PointCloud< pcl::Normal >::Ptr &normal, pcl::PointCloud< pcl::Label >::Ptr &output, std::vector< pcl::PointIndices > &label_indices)
std::vector< int > addIndices(const std::vector< int > &a, const std::vector< int > &b)
bool depth_dependent_smoothing_
virtual void configCallback(Config &config, uint32_t level)
void toROSMsg(const pcl::PointCloud< T > &pcl_cloud, sensor_msgs::PointCloud2 &cloud)
jsk_pcl_ros::OrganizedEdgeDetectorConfig Config
int straightline_threshold_
double depth_discontinuation_threshold_
bool border_policy_ignore_
#define NODELET_FATAL(...)
pcl::PointIndices PCLIndicesMsg
ros::Publisher pub_nan_boundary_edges_indices_
virtual void estimate(const sensor_msgs::PointCloud2::ConstPtr &msg)
virtual void publishStraightEdges(const pcl::PointCloud< PointT >::Ptr &cloud, const std_msgs::Header &header, const std::vector< std::vector< int > > indices)
virtual void publishIndices(ros::Publisher &pub, ros::Publisher &pub_indices, const pcl::PointCloud< PointT >::Ptr &cloud, const std::vector< int > &indices, const std_msgs::Header &header)
sensor_msgs::ImagePtr toImageMsg() const
virtual void estimateStraightEdges(const pcl::PointCloud< PointT >::Ptr &cloud, const std::vector< int > &indices, const std_msgs::Header &header, std::vector< std::vector< int > > &output_indices)
double max_depth_change_factor_
double normal_smoothing_size_