|
@@ -44,6 +44,186 @@ void Cluster2D::traverse(Node *x)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+void Cluster2D::cluster(const float * category_pt_data,
|
|
|
|
+ const float *instance_pt_x_data,
|
|
|
|
+ const float *instance_pt_y_data,
|
|
|
|
+ const pcl::PointCloud<pcl::PointXYZI>::Ptr &pc_ptr,
|
|
|
|
+ const pcl::PointIndices &valid_indices,
|
|
|
|
+ float objectness_thresh, bool use_all_grids_for_clustering)
|
|
|
|
+{
|
|
|
|
+ pc_ptr_ = pc_ptr;
|
|
|
|
+ std::vector<std::vector<Node>> nodes(rows_,
|
|
|
|
+ std::vector<Node>(cols_, Node()));
|
|
|
|
+
|
|
|
|
+ // map points into grids
|
|
|
|
+ size_t tot_point_num = pc_ptr_->size();
|
|
|
|
+ valid_indices_in_pc_ = &(valid_indices.indices);
|
|
|
|
+ CHECK_LE(valid_indices_in_pc_->size(), tot_point_num);
|
|
|
|
+ point2grid_.assign(valid_indices_in_pc_->size(), -1);
|
|
|
|
+
|
|
|
|
+ int64 time1 = std::chrono::system_clock::now().time_since_epoch().count();
|
|
|
|
+ for (size_t i = 0; i < valid_indices_in_pc_->size(); ++i)
|
|
|
|
+ {
|
|
|
|
+ int point_id = valid_indices_in_pc_->at(i);
|
|
|
|
+ CHECK_GE(point_id, 0);
|
|
|
|
+ CHECK_LT(point_id, static_cast<int>(tot_point_num));
|
|
|
|
+ const auto &point = pc_ptr_->points[point_id];
|
|
|
|
+ // * the coordinates of x and y have been exchanged in feature generation
|
|
|
|
+ // step,
|
|
|
|
+ // so we swap them back here.
|
|
|
|
+ int pos_x = F2I(point.y, range_, inv_res_x_); // col
|
|
|
|
+ int pos_y = F2I(point.x, range_, inv_res_y_); // row
|
|
|
|
+ if (IsValidRowCol(pos_y, pos_x))
|
|
|
|
+ {
|
|
|
|
+ // get grid index and count point number for corresponding node
|
|
|
|
+ point2grid_[i] = RowCol2Grid(pos_y, pos_x);
|
|
|
|
+ nodes[pos_y][pos_x].point_num++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ int64 time2 = std::chrono::system_clock::now().time_since_epoch().count();
|
|
|
|
+ // construct graph with center offset prediction and objectness
|
|
|
|
+ for (int row = 0; row < rows_; ++row)
|
|
|
|
+ {
|
|
|
|
+ for (int col = 0; col < cols_; ++col)
|
|
|
|
+ {
|
|
|
|
+ int grid = RowCol2Grid(row, col);
|
|
|
|
+ Node *node = &nodes[row][col];
|
|
|
|
+ DisjointSetMakeSet(node);
|
|
|
|
+ node->is_object =
|
|
|
|
+ (use_all_grids_for_clustering || nodes[row][col].point_num > 0) &&
|
|
|
|
+ (*(category_pt_data + grid) >= objectness_thresh);
|
|
|
|
+ int center_row = std::round(row + instance_pt_x_data[grid] * scale_);
|
|
|
|
+ int center_col = std::round(col + instance_pt_y_data[grid] * scale_);
|
|
|
|
+ center_row = std::min(std::max(center_row, 0), rows_ - 1);
|
|
|
|
+ center_col = std::min(std::max(center_col, 0), cols_ - 1);
|
|
|
|
+ node->center_node = &nodes[center_row][center_col];
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ int64 time3 = std::chrono::system_clock::now().time_since_epoch().count();
|
|
|
|
+ // traverse nodes
|
|
|
|
+ for (int row = 0; row < rows_; ++row)
|
|
|
|
+ {
|
|
|
|
+ for (int col = 0; col < cols_; ++col)
|
|
|
|
+ {
|
|
|
|
+ Node *node = &nodes[row][col];
|
|
|
|
+ if (node->is_object && node->traversed == 0)
|
|
|
|
+ {
|
|
|
|
+ traverse(node);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ int64 time4 = std::chrono::system_clock::now().time_since_epoch().count();
|
|
|
|
+ for (int row = 0; row < rows_; ++row)
|
|
|
|
+ {
|
|
|
|
+ for (int col = 0; col < cols_; ++col)
|
|
|
|
+ {
|
|
|
|
+ Node *node = &nodes[row][col];
|
|
|
|
+ if (!node->is_center)
|
|
|
|
+ {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ for (int row2 = row - 1; row2 <= row + 1; ++row2)
|
|
|
|
+ {
|
|
|
|
+ for (int col2 = col - 1; col2 <= col + 1; ++col2)
|
|
|
|
+ {
|
|
|
|
+ if ((row2 == row || col2 == col) && IsValidRowCol(row2, col2))
|
|
|
|
+ {
|
|
|
|
+ Node *node2 = &nodes[row2][col2];
|
|
|
|
+ if (node2->is_center)
|
|
|
|
+ {
|
|
|
|
+ DisjointSetUnion(node, node2);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ int64 time5 = std::chrono::system_clock::now().time_since_epoch().count();
|
|
|
|
+ int count_obstacles = 0;
|
|
|
|
+ obstacles_.clear();
|
|
|
|
+ id_img_.assign(grids_, -1);
|
|
|
|
+ for (int row = 0; row < rows_; ++row)
|
|
|
|
+ {
|
|
|
|
+ for (int col = 0; col < cols_; ++col)
|
|
|
|
+ {
|
|
|
|
+ Node *node = &nodes[row][col];
|
|
|
|
+ if (!node->is_object)
|
|
|
|
+ {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ Node *root = DisjointSetFind(node);
|
|
|
|
+ if (root->obstacle_id < 0)
|
|
|
|
+ {
|
|
|
|
+ root->obstacle_id = count_obstacles++;
|
|
|
|
+ CHECK_EQ(static_cast<int>(obstacles_.size()), count_obstacles - 1);
|
|
|
|
+ obstacles_.push_back(Obstacle());
|
|
|
|
+ }
|
|
|
|
+ int grid = RowCol2Grid(row, col);
|
|
|
|
+ CHECK_GE(root->obstacle_id, 0);
|
|
|
|
+ id_img_[grid] = root->obstacle_id;
|
|
|
|
+ obstacles_[root->obstacle_id].grids.push_back(grid);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ CHECK_EQ(static_cast<size_t>(count_obstacles), obstacles_.size());
|
|
|
|
+ int64 time6 = std::chrono::system_clock::now().time_since_epoch().count();
|
|
|
|
+
|
|
|
|
+// std::cout<<" t1: "<<(time2 - time1)/1000<<" t2: "<<(time3 - time2)/1000<<" t3: "<<(time4 - time3)/1000
|
|
|
|
+// <<" t4: "<<(time5 - time4)/1000<<" t5: "<<(time6 - time5)/1000<<std::endl;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void Cluster2D::filter(const float *confidence_pt_data,
|
|
|
|
+ const float *height_pt_data)
|
|
|
|
+{
|
|
|
|
+ for (size_t obstacle_id = 0; obstacle_id < obstacles_.size();
|
|
|
|
+ obstacle_id++)
|
|
|
|
+ {
|
|
|
|
+ Obstacle *obs = &obstacles_[obstacle_id];
|
|
|
|
+ CHECK_GT(obs->grids.size(), 0);
|
|
|
|
+ double score = 0.0;
|
|
|
|
+ double height = 0.0;
|
|
|
|
+ for (int grid : obs->grids)
|
|
|
|
+ {
|
|
|
|
+ score += static_cast<double>(confidence_pt_data[grid]);
|
|
|
|
+ height += static_cast<double>(height_pt_data[grid]);
|
|
|
|
+ }
|
|
|
|
+ obs->score = score / static_cast<double>(obs->grids.size());
|
|
|
|
+ obs->height = height / static_cast<double>(obs->grids.size());
|
|
|
|
+ obs->cloud_ptr.reset(new pcl::PointCloud<pcl::PointXYZI>);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void Cluster2D::classify(const float *classify_pt_data,int num_classes )
|
|
|
|
+{
|
|
|
|
+ CHECK_EQ(num_classes, MAX_META_TYPE);
|
|
|
|
+ for (size_t obs_id = 0; obs_id < obstacles_.size(); obs_id++)
|
|
|
|
+ {
|
|
|
|
+ Obstacle *obs = &obstacles_[obs_id];
|
|
|
|
+ for (size_t grid_id = 0; grid_id < obs->grids.size(); grid_id++)
|
|
|
|
+ {
|
|
|
|
+ int grid = obs->grids[grid_id];
|
|
|
|
+ for (int k = 0; k < num_classes; k++)
|
|
|
|
+ {
|
|
|
|
+ obs->meta_type_probs[k] += classify_pt_data[k * grids_ + grid];
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ int meta_type_id = 0;
|
|
|
|
+ for (int k = 0; k < num_classes; k++)
|
|
|
|
+ {
|
|
|
|
+ obs->meta_type_probs[k] /= obs->grids.size();
|
|
|
|
+ if (obs->meta_type_probs[k] > obs->meta_type_probs[meta_type_id])
|
|
|
|
+ {
|
|
|
|
+ meta_type_id = k;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ obs->meta_type = static_cast<MetaType>(meta_type_id);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#include <chrono>
|
|
void Cluster2D::cluster(const caffe::Blob<float> &category_pt_blob,
|
|
void Cluster2D::cluster(const caffe::Blob<float> &category_pt_blob,
|
|
const caffe::Blob<float> &instance_pt_blob,
|
|
const caffe::Blob<float> &instance_pt_blob,
|
|
const pcl::PointCloud<pcl::PointXYZI>::Ptr &pc_ptr,
|
|
const pcl::PointCloud<pcl::PointXYZI>::Ptr &pc_ptr,
|
|
@@ -55,6 +235,7 @@ void Cluster2D::cluster(const caffe::Blob<float> &category_pt_blob,
|
|
const float *instance_pt_y_data =
|
|
const float *instance_pt_y_data =
|
|
instance_pt_blob.cpu_data() + instance_pt_blob.offset(0, 1);
|
|
instance_pt_blob.cpu_data() + instance_pt_blob.offset(0, 1);
|
|
|
|
|
|
|
|
+
|
|
pc_ptr_ = pc_ptr;
|
|
pc_ptr_ = pc_ptr;
|
|
std::vector<std::vector<Node>> nodes(rows_,
|
|
std::vector<std::vector<Node>> nodes(rows_,
|
|
std::vector<Node>(cols_, Node()));
|
|
std::vector<Node>(cols_, Node()));
|
|
@@ -65,6 +246,7 @@ void Cluster2D::cluster(const caffe::Blob<float> &category_pt_blob,
|
|
CHECK_LE(valid_indices_in_pc_->size(), tot_point_num);
|
|
CHECK_LE(valid_indices_in_pc_->size(), tot_point_num);
|
|
point2grid_.assign(valid_indices_in_pc_->size(), -1);
|
|
point2grid_.assign(valid_indices_in_pc_->size(), -1);
|
|
|
|
|
|
|
|
+ int64 time1 = std::chrono::system_clock::now().time_since_epoch().count();
|
|
for (size_t i = 0; i < valid_indices_in_pc_->size(); ++i)
|
|
for (size_t i = 0; i < valid_indices_in_pc_->size(); ++i)
|
|
{
|
|
{
|
|
int point_id = valid_indices_in_pc_->at(i);
|
|
int point_id = valid_indices_in_pc_->at(i);
|
|
@@ -84,6 +266,7 @@ void Cluster2D::cluster(const caffe::Blob<float> &category_pt_blob,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ int64 time2 = std::chrono::system_clock::now().time_since_epoch().count();
|
|
// construct graph with center offset prediction and objectness
|
|
// construct graph with center offset prediction and objectness
|
|
for (int row = 0; row < rows_; ++row)
|
|
for (int row = 0; row < rows_; ++row)
|
|
{
|
|
{
|
|
@@ -103,6 +286,7 @@ void Cluster2D::cluster(const caffe::Blob<float> &category_pt_blob,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ int64 time3 = std::chrono::system_clock::now().time_since_epoch().count();
|
|
// traverse nodes
|
|
// traverse nodes
|
|
for (int row = 0; row < rows_; ++row)
|
|
for (int row = 0; row < rows_; ++row)
|
|
{
|
|
{
|
|
@@ -115,6 +299,8 @@ void Cluster2D::cluster(const caffe::Blob<float> &category_pt_blob,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ int64 time4 = std::chrono::system_clock::now().time_since_epoch().count();
|
|
for (int row = 0; row < rows_; ++row)
|
|
for (int row = 0; row < rows_; ++row)
|
|
{
|
|
{
|
|
for (int col = 0; col < cols_; ++col)
|
|
for (int col = 0; col < cols_; ++col)
|
|
@@ -141,6 +327,7 @@ void Cluster2D::cluster(const caffe::Blob<float> &category_pt_blob,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ int64 time5 = std::chrono::system_clock::now().time_since_epoch().count();
|
|
int count_obstacles = 0;
|
|
int count_obstacles = 0;
|
|
obstacles_.clear();
|
|
obstacles_.clear();
|
|
id_img_.assign(grids_, -1);
|
|
id_img_.assign(grids_, -1);
|
|
@@ -167,6 +354,10 @@ void Cluster2D::cluster(const caffe::Blob<float> &category_pt_blob,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
CHECK_EQ(static_cast<size_t>(count_obstacles), obstacles_.size());
|
|
CHECK_EQ(static_cast<size_t>(count_obstacles), obstacles_.size());
|
|
|
|
+ int64 time6 = std::chrono::system_clock::now().time_since_epoch().count();
|
|
|
|
+
|
|
|
|
+ std::cout<<" t1: "<<(time2 - time1)/1000<<" t2: "<<(time3 - time2)/1000<<" t3: "<<(time4 - time3)/1000
|
|
|
|
+ <<" t4: "<<(time5 - time4)/1000<<" t5: "<<(time6 - time5)/1000<<std::endl;
|
|
}
|
|
}
|
|
|
|
|
|
void Cluster2D::filter(const caffe::Blob<float> &confidence_pt_blob,
|
|
void Cluster2D::filter(const caffe::Blob<float> &confidence_pt_blob,
|
|
@@ -194,7 +385,10 @@ void Cluster2D::filter(const caffe::Blob<float> &confidence_pt_blob,
|
|
|
|
|
|
void Cluster2D::classify(const caffe::Blob<float> &classify_pt_blob)
|
|
void Cluster2D::classify(const caffe::Blob<float> &classify_pt_blob)
|
|
{
|
|
{
|
|
|
|
+// int64_t time1 = std::chrono::system_clock::now().time_since_epoch().count()/1000000;
|
|
const float *classify_pt_data = classify_pt_blob.cpu_data();
|
|
const float *classify_pt_data = classify_pt_blob.cpu_data();
|
|
|
|
+// int64_t time2 = std::chrono::system_clock::now().time_since_epoch().count()/1000000;
|
|
|
|
+// std::cout<<"cpu data use: "<<(time2-time1)<<std::endl;
|
|
int num_classes = classify_pt_blob.channels();
|
|
int num_classes = classify_pt_blob.channels();
|
|
CHECK_EQ(num_classes, MAX_META_TYPE);
|
|
CHECK_EQ(num_classes, MAX_META_TYPE);
|
|
for (size_t obs_id = 0; obs_id < obstacles_.size(); obs_id++)
|
|
for (size_t obs_id = 0; obs_id < obstacles_.size(); obs_id++)
|