27 const float* offset_map,
float scale,
28 float objectness_threshold) {
30 offset_map_ = offset_map;
32 objectness_threshold_ = objectness_threshold;
33 worker_.
Bind(std::bind(&SppCCDetector::CleanNodes,
this));
37bool SppCCDetector::BuildNodes(
int start_row_index,
int end_row_index) {
38 const float* offset_row_ptr = offset_map_ + start_row_index * cols_;
39 const float* offset_col_ptr = offset_map_ + (rows_ + start_row_index) * cols_;
40 const float* prob_map_ptr = prob_map_[0] + start_row_index * cols_;
41 Node* node_ptr = nodes_[0] + start_row_index * cols_;
42 for (
int row = start_row_index; row < end_row_index; ++row) {
43 for (
int col = 0; col < cols_; ++col) {
44 node_ptr->set_is_object(*prob_map_ptr++ >= objectness_threshold_);
45 int center_row =
static_cast<int>(*offset_row_ptr++ * scale_ +
46 static_cast<float>(row) + 0.5f);
47 int center_col =
static_cast<int>(*offset_col_ptr++ * scale_ +
48 static_cast<float>(col) + 0.5f);
49 center_row = std::max(0, std::min(rows_ - 1, center_row));
50 center_col = std::max(0, std::min(cols_ - 1, center_col));
51 (node_ptr++)->center_node = center_row * cols_ + center_col;
57bool SppCCDetector::CleanNodes() {
58 memset(nodes_[0], 0,
sizeof(
Node) * rows_ * cols_);
59 uint32_t node_idx = 0;
60 for (
int row = 0; row < rows_; ++row) {
61 for (
int col = 0; col < cols_; ++col) {
62 nodes_[row][col].parent = node_idx++;
70 if (!first_process_) {
73 first_process_ =
false;
75 double init_time = timer.
toc(
true);
77 double sync_time = timer.
toc(
true);
80 double traverse_time = timer.
toc(
true);
83 double union_time = timer.
toc(
true);
85 size_t num = ToLabelMap(labels);
87 double collect_time = timer.
toc(
true);
89 AINFO <<
"SppSegCC2D: init: " << init_time <<
"\tsync: " << sync_time
90 <<
"\ttraverse: " << traverse_time <<
"\tunion: " << union_time
91 <<
"\tcollect: " << collect_time <<
"\t#obj: " << num;
96void SppCCDetector::TraverseNodes() {
97 for (
int row = 0; row < rows_; row++) {
98 for (
int col = 0; col < cols_; col++) {
99 Node& node = nodes_[row][col];
100 if (node.is_object() && node.get_traversed() == 0) {
107void SppCCDetector::UnionNodes() {
108 for (
int row = 0; row < rows_; ++row) {
109 for (
int col = 0; col < cols_; ++col) {
110 Node* node = &nodes_[row][col];
111 if (!node->is_center()) {
114 Node* node_neighbor =
nullptr;
116 if (col < cols_ - 1) {
117 node_neighbor = &nodes_[row][col + 1];
118 if (node_neighbor->is_center()) {
119 DisjointSetUnion(node, node_neighbor);
123 if (row < rows_ - 1) {
124 node_neighbor = &nodes_[row + 1][col];
125 if (node_neighbor->is_center()) {
126 DisjointSetUnion(node, node_neighbor);
130 if (row < rows_ - 1 && col < cols_ - 1) {
131 node_neighbor = &nodes_[row + 1][col + 1];
132 if (node_neighbor->is_center()) {
133 DisjointSetUnion(node, node_neighbor);
137 if (row < rows_ - 1 && col > 0) {
138 node_neighbor = &nodes_[row + 1][col - 1];
139 if (node_neighbor->is_center()) {
140 DisjointSetUnion(node, node_neighbor);
147size_t SppCCDetector::ToLabelMap(SppLabelImage* labels) {
149 uint32_t pixel_id = 0;
150 labels->ResetClusters(kDefaultReserveSize);
151 for (
int row = 0; row < rows_; ++row) {
152 for (
int col = 0; col < cols_; ++col, ++pixel_id) {
153 Node* node = &nodes_[row][col];
154 if (!node->is_object()) {
155 (*labels)[row][col] = 0;
158 Node* root = DisjointSetFind(node);
164 (*labels)[row][col] = root->id;
165 labels->AddPixelSample(root->id - 1, pixel_id);
168 labels->ResizeClusters(
id);
172void SppCCDetector::Traverse(SppCCDetector::Node* x) {
173 std::vector<SppCCDetector::Node*> p;
175 while (x->get_traversed() == 0) {
178 x = nodes_[0] + x->center_node;
180 if (x->get_traversed() == 2) {
181 for (
int i =
static_cast<int>(p.size()) - 1; i >= 0 && p[i] != x; i--) {
182 p[i]->set_is_center(
true);
184 x->set_is_center(
true);
186 for (
size_t i = 0; i < p.size(); i++) {
189 y->parent = x->parent;
193SppCCDetector::Node* SppCCDetector::DisjointSetFindLoop(
Node* x) {
195 while (nodes_[0] + root->parent != root) {
196 root = nodes_[0] + root->parent;
199 while (nodes_[0] + w->parent != w) {
200 Node* temp = nodes_[0] + w->parent;
201 w->parent = root->parent;
207SppCCDetector::Node* SppCCDetector::DisjointSetFind(
Node* x) {
208 Node* y = nodes_[0] + x->parent;
209 if (y == x || nodes_[0] + y->parent == y) {
212 Node* root = DisjointSetFindLoop(nodes_[0] + y->parent);
213 x->parent = root->parent;
214 y->parent = root->parent;
218void SppCCDetector::DisjointSetUnion(
Node* x,
Node* y) {
219 x = DisjointSetFind(x);
220 y = DisjointSetFind(y);
224 uint16_t x_node_rank = x->get_node_rank();
225 uint16_t y_node_rank = y->get_node_rank();
226 if (x_node_rank < y_node_rank) {
227 x->parent = y->parent;
228 }
else if (y_node_rank < x_node_rank) {
229 y->parent = x->parent;
231 y->parent = x->parent;
232 x->set_node_rank(
static_cast<uint16_t
>(x_node_rank + 1));
void Bind(const std::function< bool()> &func)
void SetData(const float *const *prob_map, const float *offset_map, float scale, float objectness_threshold)
size_t Detect(SppLabelImage *labels)
double toc(bool reset=false)