| 379 | |
| 380 | |
| 381 | VARP getStructuringElement(int shape, Size ksize) { |
| 382 | // shape: MORPH_RECT = 0, MORPH_CROSS = 1, MORPH_ELLIPSE = 2 |
| 383 | std::vector<uint8_t> elem(ksize.area()); |
| 384 | int anchor_x = ksize.width / 2, anchor_y = ksize.height / 2, r, c; |
| 385 | double inv_r2 = 0; |
| 386 | if(shape == 2) { |
| 387 | r = anchor_y; |
| 388 | c = anchor_x; |
| 389 | inv_r2 = r ? 1. / ((double)r * r) : 0; |
| 390 | } |
| 391 | for(int i = 0; i < ksize.height; i++ ) { |
| 392 | uint8_t* ptr = elem.data() + i * ksize.width; |
| 393 | int start_x = 0, end_x = 0; |
| 394 | if(shape == 0 || (shape == 1 && i == anchor_y)) { |
| 395 | end_x = ksize.width; |
| 396 | } else if(shape == 1) { |
| 397 | start_x = anchor_x, end_x = start_x + 1; |
| 398 | } else { |
| 399 | int dy = i - r; |
| 400 | if (std::abs(dy) <= r) { |
| 401 | int dx = static_cast<int>(c * std::sqrt((r*r - dy*dy)*inv_r2)); |
| 402 | start_x = std::max(c - dx, 0); |
| 403 | end_x = std::min(c + dx + 1, ksize.width); |
| 404 | } |
| 405 | } |
| 406 | for(int j = 0; j < ksize.width; j++) { |
| 407 | ptr[j] = (j >= start_x && j < end_x); |
| 408 | } |
| 409 | } |
| 410 | return _Const(elem.data(), { ksize.height, ksize.width }, NHWC, halide_type_of<uint8_t>()); |
| 411 | } |
| 412 | |
| 413 | VARP GaussianBlur(VARP src, Size ksize, double sigmaX, double sigmaY, int borderType) { |
| 414 | auto kernelX = getGaussianKernel(ksize.width, sigmaX); |