Spaces:
Build error
Build error
// Copyright (c) OpenMMLab. All rights reserved | |
// It is modified from https://github.com/whai362/PSENet | |
using namespace std; | |
class Point2d { | |
public: | |
int x; | |
int y; | |
Point2d() : x(0), y(0) {} | |
Point2d(int _x, int _y) : x(_x), y(_y) {} | |
}; | |
void kernel_dilate(const uint8_t *data, IntArrayRef data_shape, | |
const int *label_map, int &label_num, int &min_area, | |
vector<vector<int>> &text_line) { | |
std::vector<int> area(label_num + 1); | |
int kernel_num = data_shape[0]; | |
int height = data_shape[1]; | |
int width = data_shape[2]; | |
for (int x = 0; x < height; ++x) { | |
for (int y = 0; y < width; ++y) { | |
int label = label_map[x * width + y]; | |
if (label == 0) continue; | |
area[label] += 1; | |
} | |
} | |
queue<Point2d> queue, next_queue; | |
for (int x = 0; x < height; ++x) { | |
vector<int> row(width); | |
for (int y = 0; y < width; ++y) { | |
int label = label_map[x * width + y]; | |
if (label == 0) continue; | |
if (area[label] < min_area) continue; | |
Point2d point(x, y); | |
queue.push(point); | |
row[y] = label; | |
} | |
text_line.emplace_back(row); | |
} | |
int dx[] = {-1, 1, 0, 0}; | |
int dy[] = {0, 0, -1, 1}; | |
vector<int> kernel_step(kernel_num); | |
std::for_each(kernel_step.begin(), kernel_step.end(), | |
[=](int &k) { return k * height * width; }); | |
for (int kernel_id = kernel_num - 2; kernel_id >= 0; --kernel_id) { | |
while (!queue.empty()) { | |
Point2d point = queue.front(); | |
queue.pop(); | |
int x = point.x; | |
int y = point.y; | |
int label = text_line[x][y]; | |
bool is_edge = true; | |
for (int d = 0; d < 4; ++d) { | |
int tmp_x = x + dx[d]; | |
int tmp_y = y + dy[d]; | |
if (tmp_x < 0 || tmp_x >= height) continue; | |
if (tmp_y < 0 || tmp_y >= width) continue; | |
int kernel_value = data[kernel_step[kernel_id] + tmp_x * width + tmp_y]; | |
if (kernel_value == 0) continue; | |
if (text_line[tmp_x][tmp_y] > 0) continue; | |
Point2d point(tmp_x, tmp_y); | |
queue.push(point); | |
text_line[tmp_x][tmp_y] = label; | |
is_edge = false; | |
} | |
if (is_edge) { | |
next_queue.push(point); | |
} | |
} | |
swap(queue, next_queue); | |
} | |
} | |
std::vector<std::vector<int>> contour_expand(Tensor kernel_mask, | |
Tensor internal_kernel_label, | |
int min_kernel_area, | |
int kernel_num) { | |
kernel_mask = kernel_mask.contiguous(); | |
internal_kernel_label = internal_kernel_label.contiguous(); | |
assert(kernel_mask.dim() == 3); | |
assert(internal_kernel_label.dim() == 2); | |
assert(kernel_mask.size(1) == internal_kernel_label.size(0)); | |
assert(kernel_mask.size(2) == internal_kernel_label.size(1)); | |
CHECK_CPU_INPUT(kernel_mask); | |
CHECK_CPU_INPUT(internal_kernel_label); | |
auto ptr_data = kernel_mask.data_ptr<uint8_t>(); | |
IntArrayRef data_shape = kernel_mask.sizes(); | |
auto data_label_map = internal_kernel_label.data_ptr<int32_t>(); | |
vector<vector<int>> text_line; | |
kernel_dilate(ptr_data, data_shape, data_label_map, kernel_num, | |
min_kernel_area, text_line); | |
return text_line; | |
} | |