Change type to ssize_t for all index and size variables

This commit is contained in:
Johannes Schönberger
2013-01-22 22:14:22 +01:00
parent 0b99eb68f4
commit c9f72e93d6
12 changed files with 173 additions and 180 deletions
+27 -30
View File
@@ -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]
+7 -6
View File
@@ -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,
+2 -2
View File
@@ -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.
+18 -18
View File
@@ -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]
+20 -29
View File
@@ -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()
+6 -6
View File
@@ -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)
+20 -17
View File
@@ -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:
+19 -19
View File
@@ -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):
+42 -42
View File
@@ -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
+5 -2
View File
@@ -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"
-2
View File
@@ -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]
+7 -7
View File
@@ -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])