Apollo  6.0
Open source self driving car software
spp_seg_cc_2d.h
Go to the documentation of this file.
1 /******************************************************************************
2  * Copyright 2018 The Apollo Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *****************************************************************************/
16 #pragma once
17 
18 #include <vector>
19 
23 
24 namespace apollo {
25 namespace perception {
26 namespace lidar {
27 
29  public:
30  SppCCDetector() = default;
31 
33  if (nodes_ != nullptr) {
34  common::IFree2(&nodes_);
35  }
36  }
37  // @brief: initialize detector
38  // @param [in]: rows of feature map
39  // @param [in]: cols of feature map
40  void Init(int rows, int cols) {
41  if (rows_ * cols_ != rows * cols) {
42  if (nodes_ != nullptr) {
43  common::IFree2(&nodes_);
44  }
45  nodes_ = common::IAlloc2<Node>(rows, cols);
46  rows_ = static_cast<int>(rows);
47  cols_ = static_cast<int>(cols);
48  }
49  CleanNodes();
50  }
51  // @brief: set data for clusterin
52  // @param [in]: probability map
53  // @param [in]: center offset map
54  // @param [in]: scale of offset map
55  // @param [in]: objectness threshold
56  void SetData(const float* const* prob_map, const float* offset_map,
57  float scale, float objectness_threshold);
58  // @brief: detect clusters
59  // @param [out]: label image
60  // @return: label number
61  size_t Detect(SppLabelImage* labels);
62 
63  private:
64  // @brief: build node matrix given start row index and end row index
65  // @param [in]: start row index, inclusive
66  // @param [in]: end row index, exclusive
67  // @param [out]: state of build nodes
68  bool BuildNodes(int start_row_index, int end_row_index);
69  // @brief: traverse node matrix
70  void TraverseNodes();
71  // @brief: union adjacent nodes
72  void UnionNodes();
73  // @brief: collect clusters to label map
74  size_t ToLabelMap(SppLabelImage* labels);
75  // @brief: clean node matrix
76  bool CleanNodes();
77 
78  private:
79  struct Node {
80  uint32_t center_node = 0;
81  uint32_t parent = 0;
82  uint16_t id = 0;
83  // Note, we compress node_rank, traversed, is_center and is_object
84  // in one 16bits variable, the arrangemant is as following
85  // |is_center(1bit)|is_object(1bit)|traversed(3bit)|node_rank(11bit)|
86  uint16_t status = 0;
87 
88  inline uint16_t get_node_rank() { return status & 2047; }
89  inline void set_node_rank(uint16_t node_rank) {
90  status &= 63488;
91  status |= node_rank;
92  }
93  inline uint16_t get_traversed() {
94  uint16_t pattern = 14336;
95  return static_cast<uint16_t>((status & pattern) >> 11);
96  }
97  inline void set_traversed(uint16_t traversed) {
98  status &= 51199;
99  uint16_t pattern = 7;
100  status |= static_cast<uint16_t>((traversed & pattern) << 11);
101  }
102  inline bool is_center() { return static_cast<bool>(status & 32768); }
103  inline void set_is_center(bool is_center) {
104  if (is_center) {
105  status |= 32768;
106  } else {
107  status &= 32767;
108  }
109  }
110  inline bool is_object() { return static_cast<bool>(status & 16384); }
111  inline void set_is_object(bool is_object) {
112  if (is_object) {
113  status |= 16384; // 2^14
114  } else {
115  status &= 49151; // 65535 - 2^14
116  }
117  }
118  };
119  // @brief: tranverse a node
120  // @param [in]: input node
121  void Traverse(Node* x);
122  // @brief: find root of input node and compress path
123  // @param [in]: input node
124  // @return: root node
125  Node* DisjointSetFindLoop(Node* x);
126  // @brief: find root of input node
127  // @param [in]: input node
128  // @return: root node
129  Node* DisjointSetFind(Node* x);
130  // @brief: union of two sets
131  // @param [in]: input two nodes
132  void DisjointSetUnion(Node* x, Node* y);
133 
134  private:
135  int rows_ = 0;
136  int cols_ = 0;
137  Node** nodes_ = nullptr;
138 
139  const float* const* prob_map_ = nullptr;
140  const float* offset_map_ = nullptr;
141  float scale_ = 0.f;
142  float objectness_threshold_ = 0.f;
143 
144  lib::ThreadWorker worker_;
145  bool first_process_ = true;
146 
147  private:
148  static const size_t kDefaultReserveSize = 500;
149 }; // class SppCCDetector
150 
151 } // namespace lidar
152 } // namespace perception
153 } // namespace apollo
Definition: spp_seg_cc_2d.h:28
T * DisjointSetFindLoop(T *x)
Definition: disjoint_set.h:37
void DisjointSetUnion(T *x, T *y)
Definition: disjoint_set.h:70
PlanningContext is the runtime context in planning. It is persistent across multiple frames...
Definition: atomic_hash_map.h:25
T * DisjointSetFind(T *x)
Definition: disjoint_set.h:55
size_t Detect(SppLabelImage *labels)
~SppCCDetector()
Definition: spp_seg_cc_2d.h:32
void IFree2(T ***A)
Definition: i_alloc.h:79
Definition: spp_label_image.h:32
Definition: thread_worker.h:27
void SetData(const float *const *prob_map, const float *offset_map, float scale, float objectness_threshold)
void Init(int rows, int cols)
Definition: spp_seg_cc_2d.h:40