39 #include <pcl/features/organized_edge_detection.h>
40 #include <pcl/features/integral_image_normal.h>
44 #include <std_msgs/ColorRGBA.h>
45 #include <jsk_topic_tools/color_utils.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;
235 pub.publish(ros_output);
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++) {
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();
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++ )
296 std_msgs::ColorRGBA
c = jsk_topic_tools::colorCategory20(
i);
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);