mirror of
https://github.com/wassname/scikit-image.git
synced 2026-07-13 17:45:20 +08:00
Change type to ssize_t for all index and size variables
This commit is contained in:
@@ -13,47 +13,44 @@ def possible_hull(np.ndarray[dtype=np.uint8_t, ndim=2, mode="c"] img):
|
||||
|
||||
Returns
|
||||
-------
|
||||
coords : ndarray (N, 2)
|
||||
coords : ndarray (cols, 2)
|
||||
The ``(row, column)`` coordinates of all pixels that possibly belong to
|
||||
the convex hull.
|
||||
|
||||
"""
|
||||
cdef int i, j, k
|
||||
cdef unsigned int M, N
|
||||
|
||||
M = img.shape[0]
|
||||
N = img.shape[1]
|
||||
cdef ssize_t r, c
|
||||
cdef ssize_t rows = img.shape[0]
|
||||
cdef ssize_t cols = img.shape[1]
|
||||
|
||||
# Output: M storage slots for left boundary pixels
|
||||
# N storage slots for top boundary pixels
|
||||
# M storage slots for right boundary pixels
|
||||
# N storage slots for bottom boundary pixels
|
||||
cdef np.ndarray[dtype=np.int_t, ndim=2] nonzero = \
|
||||
np.ones((2 * (M + N), 2), dtype=np.int)
|
||||
nonzero *= -1
|
||||
# Output: rows storage slots for left boundary pixels
|
||||
# cols storage slots for top boundary pixels
|
||||
# rows storage slots for right boundary pixels
|
||||
# cols storage slots for bottom boundary pixels
|
||||
cdef np.ndarray[dtype=ssize_t, ndim=2] nonzero = \
|
||||
np.ones((2 * (rows + cols), 2), dtype=np.int)
|
||||
nonzero *= -1
|
||||
|
||||
k = 0
|
||||
for i in range(M):
|
||||
for j in range(N):
|
||||
if img[i, j] != 0:
|
||||
for r in range(rows):
|
||||
for c in range(cols):
|
||||
if img[r, c] != 0:
|
||||
# Left check
|
||||
if nonzero[i, 1] == -1:
|
||||
nonzero[i, 0] = i
|
||||
nonzero[i, 1] = j
|
||||
if nonzero[r, 1] == -1:
|
||||
nonzero[r, 0] = r
|
||||
nonzero[r, 1] = c
|
||||
|
||||
# Right check
|
||||
elif nonzero[M + N + i, 1] < j:
|
||||
nonzero[M + N + i, 0] = i
|
||||
nonzero[M + N + i, 1] = j
|
||||
elif nonzero[rows + cols + r, 1] < c:
|
||||
nonzero[rows + cols + r, 0] = r
|
||||
nonzero[rows + cols + r, 1] = c
|
||||
|
||||
# Top check
|
||||
if nonzero[M + j, 1] == -1:
|
||||
nonzero[M + j, 0] = i
|
||||
nonzero[M + j, 1] = j
|
||||
if nonzero[rows + c, 1] == -1:
|
||||
nonzero[rows + c, 0] = r
|
||||
nonzero[rows + c, 1] = c
|
||||
|
||||
# Bottom check
|
||||
elif nonzero[2 * M + N + j, 0] < i:
|
||||
nonzero[2 * M + N + j, 0] = i
|
||||
nonzero[2 * M + N + j, 1] = j
|
||||
|
||||
elif nonzero[2 * rows + cols + c, 0] < r:
|
||||
nonzero[2 * rows + cols + c, 0] = r
|
||||
nonzero[2 * rows + cols + c, 1] = c
|
||||
|
||||
return nonzero[nonzero[:, 0] != -1]
|
||||
|
||||
@@ -31,18 +31,19 @@ def grid_points_inside_poly(shape, verts):
|
||||
|
||||
vx = verts[:, 0].astype(np.double)
|
||||
vy = verts[:, 1].astype(np.double)
|
||||
cdef int V = vx.shape[0]
|
||||
cdef ssize_t V = vx.shape[0]
|
||||
|
||||
cdef int M = shape[0]
|
||||
cdef int N = shape[1]
|
||||
cdef int m, n
|
||||
cdef ssize_t M = shape[0]
|
||||
cdef ssize_t N = shape[1]
|
||||
cdef ssize_t m, n
|
||||
|
||||
cdef np.ndarray[dtype=np.uint8_t, ndim=2, mode="c"] out = \
|
||||
np.zeros((M, N), dtype=np.uint8)
|
||||
|
||||
for m in range(M):
|
||||
for n in range(N):
|
||||
out[m, n] = point_in_polygon(V, <double*>vx.data, <double*>vy.data, m, n)
|
||||
out[m, n] = point_in_polygon(V, <double*>vx.data, <double*>vy.data,
|
||||
m, n)
|
||||
|
||||
return out.view(bool)
|
||||
|
||||
@@ -76,7 +77,7 @@ def points_inside_poly(points, verts):
|
||||
vy = verts[:, 1].astype(np.double)
|
||||
|
||||
cdef np.ndarray[np.uint8_t, ndim=1] out = \
|
||||
np.zeros(x.shape[0], dtype=np.uint8)
|
||||
np.zeros(x.shape[0], dtype=np.uint8)
|
||||
|
||||
points_in_polygon(vx.shape[0], <double*>vx.data, <double*>vy.data,
|
||||
x.shape[0], <double*>x.data, <double*>y.data,
|
||||
|
||||
@@ -277,8 +277,8 @@ def medial_axis(image, mask=None, return_distance=False):
|
||||
i, j = np.mgrid[0:image.shape[0], 0:image.shape[1]]
|
||||
result = masked_image.copy()
|
||||
distance = distance[result]
|
||||
i = np.ascontiguousarray(i[result], np.int32)
|
||||
j = np.ascontiguousarray(j[result], np.int32)
|
||||
i = np.ascontiguousarray(i[result], np.intp)
|
||||
j = np.ascontiguousarray(j[result], np.intp)
|
||||
result = np.ascontiguousarray(result, np.uint8)
|
||||
|
||||
# Determine the order in which pixels are processed.
|
||||
|
||||
@@ -15,11 +15,11 @@ cimport cython
|
||||
|
||||
|
||||
@cython.boundscheck(False)
|
||||
def _skeletonize_loop(np.ndarray[dtype=np.uint8_t, ndim=2,
|
||||
def _skeletonize_loop(np.ndarray[dtype=np.uint8_t, ndim=2,
|
||||
negative_indices=False, mode='c'] result,
|
||||
np.ndarray[dtype=np.int32_t, ndim=1,
|
||||
np.ndarray[dtype=np.intp_t, ndim=1,
|
||||
negative_indices=False, mode='c'] i,
|
||||
np.ndarray[dtype=np.int32_t, ndim=1,
|
||||
np.ndarray[dtype=np.intp_t, ndim=1,
|
||||
negative_indices=False, mode='c'] j,
|
||||
np.ndarray[dtype=np.int32_t, ndim=1,
|
||||
negative_indices=False, mode='c'] order,
|
||||
@@ -37,13 +37,13 @@ def _skeletonize_loop(np.ndarray[dtype=np.uint8_t, ndim=2,
|
||||
|
||||
i, j : ndarrays
|
||||
The coordinates of each foreground pixel in the image
|
||||
|
||||
|
||||
order : ndarray
|
||||
The index of each pixel, in the order of processing (order[0] is
|
||||
the first pixel to process, etc.)
|
||||
|
||||
|
||||
table : ndarray
|
||||
The 512-element lookup table of values after transformation
|
||||
The 512-element lookup table of values after transformation
|
||||
(whether to keep or not each configuration in a binary 3x3 array)
|
||||
|
||||
Notes
|
||||
@@ -55,15 +55,15 @@ def _skeletonize_loop(np.ndarray[dtype=np.uint8_t, ndim=2,
|
||||
the quench-line of the brushfire will be evaluated later than a
|
||||
point closer to the edge.
|
||||
|
||||
Note that the neighbourhood of a pixel may evolve before the loop
|
||||
arrives at this pixel. This is why it is possible to compute the
|
||||
Note that the neighbourhood of a pixel may evolve before the loop
|
||||
arrives at this pixel. This is why it is possible to compute the
|
||||
skeleton in only one pass, thanks to an adapted ordering of the
|
||||
pixels.
|
||||
"""
|
||||
cdef:
|
||||
np.int32_t accumulator
|
||||
np.int32_t index, order_index
|
||||
np.int32_t ii, jj
|
||||
ssize_t index, order_index
|
||||
ssize_t ii, jj
|
||||
|
||||
for index in range(order.shape[0]):
|
||||
accumulator = 16
|
||||
@@ -110,21 +110,21 @@ def _table_lookup_index(np.ndarray[dtype=np.uint8_t, ndim=2,
|
||||
256 128 64
|
||||
32 16 8
|
||||
4 2 1
|
||||
|
||||
|
||||
but this runs about twice as fast because of inlining and the
|
||||
hardwired kernel.
|
||||
"""
|
||||
cdef:
|
||||
np.ndarray[dtype=np.int32_t, ndim=2,
|
||||
np.ndarray[dtype=np.int32_t, ndim=2,
|
||||
negative_indices=False, mode='c'] indexer
|
||||
np.int32_t *p_indexer
|
||||
np.uint8_t *p_image
|
||||
np.int32_t i_stride
|
||||
np.int32_t i_shape
|
||||
np.int32_t j_shape
|
||||
np.int32_t i
|
||||
np.int32_t j
|
||||
np.int32_t offset
|
||||
ssize_t i_stride
|
||||
ssize_t i_shape
|
||||
ssize_t j_shape
|
||||
ssize_t i
|
||||
ssize_t j
|
||||
ssize_t offset
|
||||
|
||||
i_shape = image.shape[0]
|
||||
j_shape = image.shape[1]
|
||||
|
||||
@@ -9,39 +9,33 @@ All rights reserved.
|
||||
|
||||
Original author: Lee Kamentsky
|
||||
"""
|
||||
|
||||
cdef extern from "numpy/arrayobject.h":
|
||||
cdef void import_array()
|
||||
import_array()
|
||||
|
||||
import numpy as np
|
||||
cimport numpy as np
|
||||
cimport cython
|
||||
|
||||
DTYPE_INT32 = np.int32
|
||||
|
||||
ctypedef np.int32_t DTYPE_INT32_t
|
||||
DTYPE_BOOL = np.bool
|
||||
ctypedef np.int8_t DTYPE_BOOL_t
|
||||
|
||||
|
||||
include "heap_watershed.pxi"
|
||||
|
||||
|
||||
@cython.boundscheck(False)
|
||||
def watershed(np.ndarray[DTYPE_INT32_t, ndim=1, negative_indices=False,
|
||||
mode='c'] image,
|
||||
np.ndarray[DTYPE_INT32_t, ndim=2, negative_indices=False,
|
||||
mode='c'] pq,
|
||||
DTYPE_INT32_t age,
|
||||
np.ndarray[DTYPE_INT32_t, ndim=2, negative_indices=False,
|
||||
mode='c'] structure,
|
||||
DTYPE_INT32_t ndim,
|
||||
np.ndarray[DTYPE_BOOL_t, ndim=1, negative_indices=False,
|
||||
mode='c'] mask,
|
||||
np.ndarray[DTYPE_INT32_t, ndim=1, negative_indices=False,
|
||||
mode='c'] image_shape,
|
||||
np.ndarray[DTYPE_INT32_t, ndim=1, negative_indices=False,
|
||||
mode='c'] output):
|
||||
def watershed(np.ndarray[DTYPE_INT32_t, ndim=1, negative_indices=False,
|
||||
mode='c'] image,
|
||||
np.ndarray[DTYPE_INT32_t, ndim=2, negative_indices=False,
|
||||
mode='c'] pq,
|
||||
ssize_t age,
|
||||
np.ndarray[DTYPE_INT32_t, ndim=2, negative_indices=False,
|
||||
mode='c'] structure,
|
||||
np.ndarray[DTYPE_BOOL_t, ndim=1, negative_indices=False,
|
||||
mode='c'] mask,
|
||||
np.ndarray[DTYPE_INT32_t, ndim=1, negative_indices=False,
|
||||
mode='c'] output):
|
||||
"""Do heavy lifting of watershed algorithm
|
||||
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
@@ -58,20 +52,17 @@ def watershed(np.ndarray[DTYPE_INT32_t, ndim=1, negative_indices=False,
|
||||
in a flattened array. The remaining elements are the
|
||||
offsets from the point to its neighbor in the various
|
||||
dimensions
|
||||
ndim - # of dimensions in the image
|
||||
mask - numpy boolean (char) array indicating which pixels to consider
|
||||
and which to ignore. Also flattened.
|
||||
image_shape - the dimensions of the image, for boundary checking,
|
||||
a numpy array of np.int32
|
||||
output - put the image labels in here
|
||||
"""
|
||||
cdef Heapitem elem
|
||||
cdef Heapitem new_elem
|
||||
cdef DTYPE_INT32_t nneighbors = structure.shape[0]
|
||||
cdef DTYPE_INT32_t i = 0
|
||||
cdef DTYPE_INT32_t index = 0
|
||||
cdef DTYPE_INT32_t old_index = 0
|
||||
cdef DTYPE_INT32_t max_index = image.shape[0]
|
||||
cdef ssize_t nneighbors = structure.shape[0]
|
||||
cdef ssize_t i = 0
|
||||
cdef ssize_t index = 0
|
||||
cdef ssize_t old_index = 0
|
||||
cdef ssize_t max_index = image.shape[0]
|
||||
|
||||
cdef Heap *hp = <Heap *> heap_from_numpy2()
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
"""Export fast union find in Cython"""
|
||||
cimport numpy as np
|
||||
|
||||
DTYPE = np.int
|
||||
ctypedef np.int_t DTYPE_t
|
||||
DTYPE = np.intp
|
||||
ctypedef np.intp_t DTYPE_t
|
||||
|
||||
cdef DTYPE_t find_root(np.int_t *forest, np.int_t n)
|
||||
cdef set_root(np.int_t *forest, np.int_t n, np.int_t root)
|
||||
cdef join_trees(np.int_t *forest, np.int_t n, np.int_t m)
|
||||
cdef link_bg(np.int_t *forest, np.int_t n, np.int_t *background_node)
|
||||
cdef DTYPE_t find_root(DTYPE_t *forest, DTYPE_t n)
|
||||
cdef set_root(DTYPE_t *forest, DTYPE_t n, DTYPE_t root)
|
||||
cdef join_trees(DTYPE_t *forest, DTYPE_t n, DTYPE_t m)
|
||||
cdef link_bg(DTYPE_t *forest, DTYPE_t n, DTYPE_t *background_node)
|
||||
|
||||
@@ -23,23 +23,25 @@ See also:
|
||||
# Tree operations implemented by an array as described in Wu et al.
|
||||
# The term "forest" is used to indicate an array that stores one or more trees
|
||||
|
||||
DTYPE = np.int
|
||||
DTYPE = np.intp
|
||||
|
||||
cdef DTYPE_t find_root(np.int_t *forest, np.int_t n):
|
||||
|
||||
cdef DTYPE_t find_root(DTYPE_t *forest, DTYPE_t n):
|
||||
"""Find the root of node n.
|
||||
|
||||
"""
|
||||
cdef np.int_t root = n
|
||||
cdef DTYPE_t root = n
|
||||
while (forest[root] < root):
|
||||
root = forest[root]
|
||||
return root
|
||||
|
||||
cdef set_root(np.int_t *forest, np.int_t n, np.int_t root):
|
||||
|
||||
cdef set_root(DTYPE_t *forest, DTYPE_t n, DTYPE_t root):
|
||||
"""
|
||||
Set all nodes on a path to point to new_root.
|
||||
|
||||
"""
|
||||
cdef np.int_t j
|
||||
cdef DTYPE_t j
|
||||
while (forest[n] < n):
|
||||
j = forest[n]
|
||||
forest[n] = root
|
||||
@@ -48,12 +50,12 @@ cdef set_root(np.int_t *forest, np.int_t n, np.int_t root):
|
||||
forest[n] = root
|
||||
|
||||
|
||||
cdef join_trees(np.int_t *forest, np.int_t n, np.int_t m):
|
||||
cdef join_trees(DTYPE_t *forest, DTYPE_t n, DTYPE_t m):
|
||||
"""Join two trees containing nodes n and m.
|
||||
|
||||
"""
|
||||
cdef np.int_t root = find_root(forest, n)
|
||||
cdef np.int_t root_m
|
||||
cdef DTYPE_t root = find_root(forest, n)
|
||||
cdef DTYPE_t root_m
|
||||
|
||||
if (n != m):
|
||||
root_m = find_root(forest, m)
|
||||
@@ -64,7 +66,8 @@ cdef join_trees(np.int_t *forest, np.int_t n, np.int_t m):
|
||||
set_root(forest, n, root)
|
||||
set_root(forest, m, root)
|
||||
|
||||
cdef link_bg(np.int_t *forest, np.int_t n, np.int_t *background_node):
|
||||
|
||||
cdef link_bg(DTYPE_t *forest, DTYPE_t n, DTYPE_t *background_node):
|
||||
"""
|
||||
Link a node to the background node.
|
||||
|
||||
@@ -76,7 +79,7 @@ cdef link_bg(np.int_t *forest, np.int_t n, np.int_t *background_node):
|
||||
|
||||
# Connected components search as described in Fiorio et al.
|
||||
|
||||
def label(input, np.int_t neighbors=8, np.int_t background=-1):
|
||||
def label(input, DTYPE_t neighbors=8, DTYPE_t background=-1):
|
||||
"""Label connected regions of an integer array.
|
||||
|
||||
Two pixels are connected when they are neighbors and have the same value.
|
||||
@@ -134,8 +137,8 @@ def label(input, np.int_t neighbors=8, np.int_t background=-1):
|
||||
[-1 -1 -1]]
|
||||
|
||||
"""
|
||||
cdef np.int_t rows = input.shape[0]
|
||||
cdef np.int_t cols = input.shape[1]
|
||||
cdef DTYPE_t rows = input.shape[0]
|
||||
cdef DTYPE_t cols = input.shape[1]
|
||||
|
||||
cdef np.ndarray[DTYPE_t, ndim=2] data = np.array(input, copy=True,
|
||||
dtype=DTYPE)
|
||||
@@ -143,12 +146,12 @@ def label(input, np.int_t neighbors=8, np.int_t background=-1):
|
||||
|
||||
forest = np.arange(data.size, dtype=DTYPE).reshape((rows, cols))
|
||||
|
||||
cdef np.int_t *forest_p = <np.int_t*>forest.data
|
||||
cdef np.int_t *data_p = <np.int_t*>data.data
|
||||
cdef DTYPE_t *forest_p = <DTYPE_t*>forest.data
|
||||
cdef DTYPE_t *data_p = <DTYPE_t*>data.data
|
||||
|
||||
cdef np.int_t i, j
|
||||
cdef DTYPE_t i, j
|
||||
|
||||
cdef np.int_t background_node = -999
|
||||
cdef DTYPE_t background_node = -999
|
||||
|
||||
if neighbors != 4 and neighbors != 8:
|
||||
raise ValueError('Neighbors must be either 4 or 8.')
|
||||
@@ -197,7 +200,7 @@ def label(input, np.int_t neighbors=8, np.int_t background=-1):
|
||||
|
||||
# Label output
|
||||
|
||||
cdef np.int_t ctr = 0
|
||||
cdef DTYPE_t ctr = 0
|
||||
for i in range(rows):
|
||||
for j in range(cols):
|
||||
if (i*cols + j) == background_node:
|
||||
|
||||
@@ -13,13 +13,13 @@ def dilate(np.ndarray[np.uint8_t, ndim=2] image,
|
||||
np.ndarray[np.uint8_t, ndim=2] out=None,
|
||||
char shift_x=0, char shift_y=0):
|
||||
|
||||
cdef int rows = image.shape[0]
|
||||
cdef int cols = image.shape[1]
|
||||
cdef int srows = selem.shape[0]
|
||||
cdef int scols = selem.shape[1]
|
||||
cdef ssize_t rows = image.shape[0]
|
||||
cdef ssize_t cols = image.shape[1]
|
||||
cdef ssize_t srows = selem.shape[0]
|
||||
cdef ssize_t scols = selem.shape[1]
|
||||
|
||||
cdef int centre_r = int(selem.shape[0] / 2) - shift_y
|
||||
cdef int centre_c = int(selem.shape[1] / 2) - shift_x
|
||||
cdef ssize_t centre_r = int(selem.shape[0] / 2) - shift_y
|
||||
cdef ssize_t centre_c = int(selem.shape[1] / 2) - shift_x
|
||||
|
||||
image = np.ascontiguousarray(image)
|
||||
if out is None:
|
||||
@@ -30,11 +30,11 @@ def dilate(np.ndarray[np.uint8_t, ndim=2] image,
|
||||
cdef np.uint8_t* out_data = <np.uint8_t*>out.data
|
||||
cdef np.uint8_t* image_data = <np.uint8_t*>image.data
|
||||
|
||||
cdef int r, c, rr, cc, s, value, local_max
|
||||
cdef ssize_t r, c, rr, cc, s, value, local_max
|
||||
|
||||
cdef int selem_num = np.sum(selem != 0)
|
||||
cdef int* sr = <int*>malloc(selem_num * sizeof(int))
|
||||
cdef int* sc = <int*>malloc(selem_num * sizeof(int))
|
||||
cdef ssize_t selem_num = np.sum(selem != 0)
|
||||
cdef ssize_t* sr = <ssize_t*>malloc(selem_num * sizeof(ssize_t))
|
||||
cdef ssize_t* sc = <ssize_t*>malloc(selem_num * sizeof(ssize_t))
|
||||
|
||||
s = 0
|
||||
for r in range(srows):
|
||||
@@ -68,13 +68,13 @@ def erode(np.ndarray[np.uint8_t, ndim=2] image,
|
||||
np.ndarray[np.uint8_t, ndim=2] out=None,
|
||||
char shift_x=0, char shift_y=0):
|
||||
|
||||
cdef int rows = image.shape[0]
|
||||
cdef int cols = image.shape[1]
|
||||
cdef int srows = selem.shape[0]
|
||||
cdef int scols = selem.shape[1]
|
||||
cdef ssize_t rows = image.shape[0]
|
||||
cdef ssize_t cols = image.shape[1]
|
||||
cdef ssize_t srows = selem.shape[0]
|
||||
cdef ssize_t scols = selem.shape[1]
|
||||
|
||||
cdef int centre_r = int(selem.shape[0] / 2) - shift_y
|
||||
cdef int centre_c = int(selem.shape[1] / 2) - shift_x
|
||||
cdef ssize_t centre_r = int(selem.shape[0] / 2) - shift_y
|
||||
cdef ssize_t centre_c = int(selem.shape[1] / 2) - shift_x
|
||||
|
||||
image = np.ascontiguousarray(image)
|
||||
if out is None:
|
||||
@@ -87,9 +87,9 @@ def erode(np.ndarray[np.uint8_t, ndim=2] image,
|
||||
|
||||
cdef int r, c, rr, cc, s, value, local_min
|
||||
|
||||
cdef int selem_num = np.sum(selem != 0)
|
||||
cdef int* sr = <int*>malloc(selem_num * sizeof(int))
|
||||
cdef int* sc = <int*>malloc(selem_num * sizeof(int))
|
||||
cdef ssize_t selem_num = np.sum(selem != 0)
|
||||
cdef ssize_t* sr = <ssize_t*>malloc(selem_num * sizeof(ssize_t))
|
||||
cdef ssize_t* sc = <ssize_t*>malloc(selem_num * sizeof(ssize_t))
|
||||
|
||||
s = 0
|
||||
for r in range(srows):
|
||||
|
||||
@@ -10,21 +10,18 @@ All rights reserved.
|
||||
Original author: Lee Kamentsky
|
||||
"""
|
||||
|
||||
cdef extern from "stdlib.h":
|
||||
ctypedef unsigned long size_t
|
||||
void free(void *ptr)
|
||||
void *malloc(size_t size)
|
||||
void *realloc(void *ptr, size_t size)
|
||||
from libc.stdlib cimport free, malloc, realloc
|
||||
|
||||
|
||||
cdef struct Heap:
|
||||
unsigned int items
|
||||
unsigned int space
|
||||
ssize_t items
|
||||
ssize_t space
|
||||
Heapitem *data
|
||||
Heapitem **ptrs
|
||||
|
||||
cdef inline Heap *heap_from_numpy2():
|
||||
cdef unsigned int k
|
||||
cdef Heap *heap
|
||||
cdef ssize_t k
|
||||
cdef Heap *heap
|
||||
heap = <Heap *> malloc(sizeof (Heap))
|
||||
heap.items = 0
|
||||
heap.space = 1000
|
||||
@@ -39,7 +36,7 @@ cdef inline void heap_done(Heap *heap):
|
||||
free(heap.ptrs)
|
||||
free(heap)
|
||||
|
||||
cdef inline void swap(unsigned int a, unsigned int b, Heap *h):
|
||||
cdef inline void swap(ssize_t a, ssize_t b, Heap *h):
|
||||
h.ptrs[a], h.ptrs[b] = h.ptrs[b], h.ptrs[a]
|
||||
|
||||
|
||||
@@ -47,13 +44,13 @@ cdef inline void swap(unsigned int a, unsigned int b, Heap *h):
|
||||
# heappop - inlined
|
||||
#
|
||||
# pop an element off the heap, maintaining heap invariant
|
||||
#
|
||||
#
|
||||
# Note: heap ordering is the same as python heapq, i.e., smallest first.
|
||||
######################################################
|
||||
cdef inline void heappop(Heap *heap,
|
||||
Heapitem *dest):
|
||||
cdef unsigned int i, smallest, l, r # heap indices
|
||||
|
||||
cdef inline void heappop(Heap *heap, Heapitem *dest):
|
||||
|
||||
cdef ssize_t i, smallest, l, r # heap indices
|
||||
|
||||
#
|
||||
# Start by copying the first element to the destination
|
||||
#
|
||||
@@ -76,10 +73,10 @@ cdef inline void heappop(Heap *heap,
|
||||
smallest = i
|
||||
while True:
|
||||
# loop invariant here: smallest == i
|
||||
|
||||
|
||||
# find smallest of (i, l, r), and swap it to i's position if necessary
|
||||
l = i*2+1 #__left(i)
|
||||
r = i*2+2 #__right(i)
|
||||
l = i * 2 + 1 #__left(i)
|
||||
r = i * 2 + 2 #__right(i)
|
||||
if l < heap.items:
|
||||
if smaller(heap.ptrs[l], heap.ptrs[i]):
|
||||
smallest = l
|
||||
@@ -88,13 +85,14 @@ cdef inline void heappop(Heap *heap,
|
||||
else:
|
||||
# this is unnecessary, but trims 0.04 out of 0.85 seconds...
|
||||
break
|
||||
# the element at i is smaller than either of its children, heap invariant restored.
|
||||
# the element at i is smaller than either of its children, heap
|
||||
# invariant restored.
|
||||
if smallest == i:
|
||||
break
|
||||
# swap
|
||||
swap(i, smallest, heap)
|
||||
i = smallest
|
||||
|
||||
|
||||
##################################################
|
||||
# heappush - inlined
|
||||
#
|
||||
@@ -102,34 +100,36 @@ cdef inline void heappop(Heap *heap,
|
||||
#
|
||||
# Note: heap ordering is the same as python heapq, i.e., smallest first.
|
||||
##################################################
|
||||
cdef inline void heappush(Heap *heap,
|
||||
Heapitem *new_elem):
|
||||
cdef unsigned int child = heap.items
|
||||
cdef unsigned int parent
|
||||
cdef unsigned int k
|
||||
cdef Heapitem *new_data
|
||||
cdef inline void heappush(Heap *heap, Heapitem *new_elem):
|
||||
|
||||
# grow if necessary
|
||||
if heap.items == heap.space:
|
||||
cdef ssize_t child = heap.items
|
||||
cdef ssize_t parent
|
||||
cdef ssize_t k
|
||||
cdef Heapitem *new_data
|
||||
|
||||
# grow if necessary
|
||||
if heap.items == heap.space:
|
||||
heap.space = heap.space * 2
|
||||
new_data = <Heapitem *> realloc(<void *> heap.data, <size_t> (heap.space * sizeof(Heapitem)))
|
||||
heap.ptrs = <Heapitem **> realloc(<void *> heap.ptrs, <size_t> (heap.space * sizeof(Heapitem *)))
|
||||
new_data = <Heapitem*>realloc(<void*>heap.data,
|
||||
<ssize_t>(heap.space * sizeof(Heapitem)))
|
||||
heap.ptrs = <Heapitem**>realloc(<void*>heap.ptrs,
|
||||
<ssize_t>(heap.space * sizeof(Heapitem *)))
|
||||
for k in range(heap.items):
|
||||
heap.ptrs[k] = new_data + (heap.ptrs[k] - heap.data)
|
||||
for k in range(heap.items, heap.space):
|
||||
heap.ptrs[k] = new_data + k
|
||||
heap.data = new_data
|
||||
|
||||
# insert new data at child
|
||||
heap.ptrs[child][0] = new_elem[0]
|
||||
heap.items += 1
|
||||
# insert new data at child
|
||||
heap.ptrs[child][0] = new_elem[0]
|
||||
heap.items += 1
|
||||
|
||||
# restore heap invariant, all parents <= children
|
||||
while child>0:
|
||||
parent = (child + 1) / 2 - 1 # __parent(i)
|
||||
|
||||
if smaller(heap.ptrs[child], heap.ptrs[parent]):
|
||||
swap(parent, child, heap)
|
||||
child = parent
|
||||
else:
|
||||
break
|
||||
# restore heap invariant, all parents <= children
|
||||
while child > 0:
|
||||
parent = (child + 1) / 2 - 1 # __parent(i)
|
||||
|
||||
if smaller(heap.ptrs[child], heap.ptrs[parent]):
|
||||
swap(parent, child, heap)
|
||||
child = parent
|
||||
else:
|
||||
break
|
||||
|
||||
@@ -13,14 +13,17 @@ import numpy as np
|
||||
cimport numpy as np
|
||||
cimport cython
|
||||
|
||||
|
||||
cdef struct Heapitem:
|
||||
np.int32_t value
|
||||
np.int32_t age
|
||||
np.int32_t index
|
||||
ssize_t index
|
||||
|
||||
|
||||
cdef inline int smaller(Heapitem *a, Heapitem *b):
|
||||
if a.value <> b.value:
|
||||
return a.value < b.value
|
||||
return a.value < b.value
|
||||
return a.age < b.age
|
||||
|
||||
|
||||
include "heap_general.pxi"
|
||||
|
||||
@@ -214,9 +214,7 @@ def watershed(image, markers, connectivity=None, offset=None, mask=None):
|
||||
c_mask = c_mask.astype(np.int8).flatten()
|
||||
_watershed.watershed(c_image.flatten(),
|
||||
pq, age, c,
|
||||
c_image.ndim,
|
||||
c_mask,
|
||||
np.array(c_image.shape, np.int32),
|
||||
c_output)
|
||||
c_output = c_output.reshape(c_image.shape)[[slice(1, -1, None)] *
|
||||
image.ndim]
|
||||
|
||||
@@ -54,23 +54,23 @@ def _felzenszwalb_grey(image, double scale=1, sigma=0.8, int min_size=20):
|
||||
uright_cost.ravel()]).astype(np.float)
|
||||
# compute edges between pixels:
|
||||
height, width = image.shape[:2]
|
||||
cdef np.ndarray[np.int_t, ndim=2] segments \
|
||||
= np.arange(width * height, dtype=np.int).reshape(height, width)
|
||||
cdef np.ndarray[np.intp_t, ndim=2] segments \
|
||||
= np.arange(width * height, dtype=np.intp).reshape(height, width)
|
||||
right_edges = np.c_[segments[1:, :].ravel(), segments[:-1, :].ravel()]
|
||||
down_edges = np.c_[segments[:, 1:].ravel(), segments[:, :-1].ravel()]
|
||||
dright_edges = np.c_[segments[1:, 1:].ravel(), segments[:-1, :-1].ravel()]
|
||||
uright_edges = np.c_[segments[:-1, 1:].ravel(), segments[1:, :-1].ravel()]
|
||||
cdef np.ndarray[np.int_t, ndim=2] edges \
|
||||
cdef np.ndarray[np.intp_t, ndim=2] edges \
|
||||
= np.vstack([right_edges, down_edges, dright_edges, uright_edges])
|
||||
# initialize data structures for segment size
|
||||
# and inner cost, then start greedy iteration over edges.
|
||||
edge_queue = np.argsort(costs)
|
||||
edges = np.ascontiguousarray(edges[edge_queue])
|
||||
costs = np.ascontiguousarray(costs[edge_queue])
|
||||
cdef np.int_t *segments_p = <np.int_t*>segments.data
|
||||
cdef np.int_t *edges_p = <np.int_t*>edges.data
|
||||
cdef np.intp_t *segments_p = <np.intp_t*>segments.data
|
||||
cdef np.intp_t *edges_p = <np.intp_t*>edges.data
|
||||
cdef np.float_t *costs_p = <np.float_t*>costs.data
|
||||
cdef np.ndarray[np.int_t, ndim=1] segment_size \
|
||||
cdef np.ndarray[np.intp_t, ndim=1] segment_size \
|
||||
= np.ones(width * height, dtype=np.int)
|
||||
# inner cost of segments
|
||||
cdef np.ndarray[np.float_t, ndim=1] cint = np.zeros(width * height)
|
||||
@@ -96,7 +96,7 @@ def _felzenszwalb_grey(image, double scale=1, sigma=0.8, int min_size=20):
|
||||
cint[seg_new] = costs_p[0]
|
||||
|
||||
# postprocessing to remove small segments
|
||||
edges_p = <np.int_t*>edges.data
|
||||
edges_p = <np.intp_t*>edges.data
|
||||
for e in range(costs.size):
|
||||
seg0 = find_root(segments_p, edges_p[0])
|
||||
seg1 = find_root(segments_p, edges_p[1])
|
||||
|
||||
Reference in New Issue
Block a user