scikit-image
74 строки · 2.1 Кб
1#cython: cdivision=True
2#cython: boundscheck=False
3#cython: nonecheck=False
4#cython: wraparound=False
5import numpy as np
6
7cimport numpy as cnp
8cnp.import_array()
9
10
11def possible_hull(cnp.uint8_t[:, ::1] img):
12"""Return positions of pixels that possibly belong to the convex hull.
13
14Parameters
15----------
16img : ndarray of bool
17Binary input image.
18
19Returns
20-------
21coords : ndarray (cols, 2)
22The ``(row, column)`` coordinates of all pixels that possibly belong to
23the convex hull.
24
25"""
26cdef Py_ssize_t r, c
27cdef Py_ssize_t rows = img.shape[0]
28cdef Py_ssize_t cols = img.shape[1]
29
30# Output: rows storage slots for left boundary pixels
31# cols storage slots for top boundary pixels
32# rows storage slots for right boundary pixels
33# cols storage slots for bottom boundary pixels
34coords = np.ones((2 * (rows + cols), 2), dtype=np.intp)
35coords *= -1
36
37cdef Py_ssize_t[:, ::1] nonzero = coords
38cdef Py_ssize_t rows_cols = rows + cols
39cdef Py_ssize_t rows_2_cols = 2 * rows + cols
40cdef Py_ssize_t rows_cols_r, rows_c
41
42with nogil:
43for r in range(rows):
44
45rows_cols_r = rows_cols + r
46
47for c in range(cols):
48
49if img[r, c] != 0:
50
51rows_c = rows + c
52rows_2_cols_c = rows_2_cols + c
53
54# Left check
55if nonzero[r, 1] == -1:
56nonzero[r, 0] = r
57nonzero[r, 1] = c
58
59# Right check
60elif nonzero[rows_cols_r, 1] < c:
61nonzero[rows_cols_r, 0] = r
62nonzero[rows_cols_r, 1] = c
63
64# Top check
65if nonzero[rows_c, 1] == -1:
66nonzero[rows_c, 0] = r
67nonzero[rows_c, 1] = c
68
69# Bottom check
70elif nonzero[rows_2_cols_c, 0] < r:
71nonzero[rows_2_cols_c, 0] = r
72nonzero[rows_2_cols_c, 1] = c
73
74return coords[coords[:, 0] != -1]
75