Skip to content

Commit

Permalink
Replace boundary calculation lists with IntArrays.
Browse files Browse the repository at this point in the history
  • Loading branch information
stefanv committed Oct 29, 2009
1 parent ead888e commit 4fb2610
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 29 deletions.
9 changes: 5 additions & 4 deletions lulu/base.pyx
Expand Up @@ -14,6 +14,7 @@ from lulu.connected_region cimport ConnectedRegion

cimport lulu.connected_region_handler as crh
cimport int_array as iarr
from int_array cimport IntArray

def connected_regions(np.ndarray[np.int_t, ndim=2] img):
"""Return ConnectedRegions that, together, compose the whole image.
Expand Down Expand Up @@ -165,7 +166,7 @@ cdef dict _identify_pulses_and_merges(set regions, int area, dict pulses,
cdef dict merges = {}
cdef list merge_indices = []
cdef list y, x
cdef IntArray y, x
cdef int i, idx0, idx1
cdef int xi, yi
cdef bool do_merge
Expand Down Expand Up @@ -218,9 +219,9 @@ cdef dict _identify_pulses_and_merges(set regions, int area, dict pulses,
cr_save._value = old_value - cr._value # == pulse height
(<list>pulses[area]).append(cr_save)
for i in range(len(x)):
xi = x[i]
yi = y[i]
for i in range(x.size):
xi = x.buf[i]
yi = y.buf[i]
if (xi < 0) or (xi >= cols) or (yi < 0) or (yi >= rows):
# Position outside boundary
Expand Down
5 changes: 3 additions & 2 deletions lulu/connected_region_handler.pxd
Expand Up @@ -2,6 +2,7 @@

from connected_region cimport ConnectedRegion
cimport numpy as np
from int_array cimport IntArray

cdef _iterate_rows(ConnectedRegion cr)
cpdef int nnz(ConnectedRegion cr)
Expand All @@ -22,10 +23,10 @@ cpdef ConnectedRegion copy(ConnectedRegion cr)
cpdef int contains(ConnectedRegion cr, int r, int c)
cpdef outside_boundary(ConnectedRegion cr)
cpdef validate(ConnectedRegion cr)
cdef int _boundary_maximum(list boundary_x, list boundary_y,
cdef int _boundary_maximum(IntArray boundary_x, IntArray boundary_y,
np.int_t* img,
int rows, int cols)
cdef int _boundary_minimum(list boundary_x, list boundary_y,
cdef int _boundary_minimum(IntArray boundary_x, IntArray boundary_y,
np.int_t* img,
int rows, int cols)
cpdef merge(ConnectedRegion, ConnectedRegion)
Expand Down
35 changes: 18 additions & 17 deletions lulu/connected_region_handler.pyx
Expand Up @@ -167,7 +167,7 @@ cpdef outside_boundary(ConnectedRegion cr):
cdef int i # scanline row-position
cdef int j # column position in scanline
cdef int start, end, k, c
cdef list x = [], y = []
cdef IntArray x = IntArray(), y = IntArray()

cdef int* rowptr = cr.rowptr.buf
cdef int* colptr = cr.colptr.buf
Expand All @@ -188,8 +188,8 @@ cpdef outside_boundary(ConnectedRegion cr):
r = cr._start_row
c = colptr[0]

x = [c, c-1, c+1, c]
y = [r-1, r, r, r+1]
iarr.from_list(x, [c, c-1, c+1, c])
iarr.from_list(y, [r-1, r, r, r+1])

return y, x

Expand Down Expand Up @@ -223,19 +223,19 @@ cpdef outside_boundary(ConnectedRegion cr):
for j in range(columns):
# Test four neighbours for connections
if j == 0 and line[j] == 1:
x.append(-1 + col_min)
y.append(i - 1 + cr._start_row)
iarr.append(x, -1 + col_min)
iarr.append(y, i - 1 + cr._start_row)

if (line[j] == 0) and \
(line_above[j] == 1 or line_below[j] == 1 or
((j - 1) >= 0 and line[j - 1] == 1) or \
((j + 1) < columns and line[j + 1] == 1)):
x.append(j + col_min)
y.append(i - 1 + cr._start_row)
iarr.append(x, j + col_min)
iarr.append(y, i - 1 + cr._start_row)

if j == columns - 1 and line[j] == 1:
x.append(columns + col_min)
y.append(i - 1 + cr._start_row)
iarr.append(x, columns + col_min)
iarr.append(y, i - 1 + cr._start_row)

stdlib.free(line_above)
stdlib.free(line)
Expand Down Expand Up @@ -266,7 +266,7 @@ cdef int gt(int a, int b):
cdef int lt(int a, int b):
return a < b

cdef int _boundary_extremum(list boundary_x, list boundary_y,
cdef int _boundary_extremum(IntArray boundary_x, IntArray boundary_y,
np.int_t* img,
int max_rows, int max_cols,
int (*func)(int, int),
Expand All @@ -292,9 +292,9 @@ cdef int _boundary_extremum(list boundary_x, list boundary_y,
cdef np.int_t img_val
cdef int extremum = initial_extremum

for i in range(len(boundary_y)):
r = boundary_y[i]
c = boundary_x[i]
for i in range(boundary_y.size):
r = boundary_y.buf[i]
c = boundary_x.buf[i]

if r < 0 or r >= max_rows or c < 0 or c >= max_cols:
continue
Expand All @@ -305,28 +305,29 @@ cdef int _boundary_extremum(list boundary_x, list boundary_y,

return extremum

cdef int _boundary_maximum(list boundary_x, list boundary_y,
cdef int _boundary_maximum(IntArray boundary_x, IntArray boundary_y,
np.int_t* img,
int max_rows, int max_cols):
return _boundary_extremum(boundary_x, boundary_y, img,
max_rows, max_cols, gt, -1)

cdef int _boundary_minimum(list boundary_x, list boundary_y,
cdef int _boundary_minimum(IntArray boundary_x, IntArray boundary_y,
np.int_t* img,
int max_rows, int max_cols):
return _boundary_extremum(boundary_x, boundary_y, img,
max_rows, max_cols, lt, 256)

# Python wrappers for the above two functions
def boundary_maximum(ConnectedRegion cr,
np.ndarray[np.int_t, ndim=2] img):
cdef list y, x
cdef IntArray y, x
y, x = outside_boundary(cr)
return _boundary_maximum(x, y, <np.int_t*>img.data,
img.shape[0], img.shape[1])

def boundary_minimum(ConnectedRegion cr,
np.ndarray[np.int_t, ndim=2] img):
cdef list y, x
cdef IntArray y, x
y, x = outside_boundary(cr)
return _boundary_minimum(x, y, <np.int_t*>img.data,
img.shape[0], img.shape[1])
Expand Down
18 changes: 12 additions & 6 deletions lulu/tests/test_connectedregion.py
Expand Up @@ -58,15 +58,19 @@ def test_contains(self):

def test_outside_boundary(self):
y, x = crh.outside_boundary(self.c)
assert_array_equal(x, [2, 4, 0, 1, 3, 5, -1, 3, 4, 0, 1, 5, 2, 3, 4])
assert_array_equal(y, [0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4])
assert_array_equal(iarr.to_list(x),
[2, 4, 0, 1, 3, 5, -1, 3, 4, 0, 1, 5, 2, 3, 4])
assert_array_equal(iarr.to_list(y),
[0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4])

c = ConnectedRegion(shape=(1, 5),
rowptr=[0, 2],
colptr=[2, 3])
y, x = crh.outside_boundary(c)
assert_array_equal(x, [2, 1, 3, 2])
assert_array_equal(y, [-1, 0, 0, 1])
assert_array_equal(iarr.to_list(x),
[2, 1, 3, 2])
assert_array_equal(iarr.to_list(y),
[-1, 0, 0, 1])

def test_outside_boundary_beyond_border(self):
c = ConnectedRegion(shape=(2, 2),
Expand All @@ -76,8 +80,10 @@ def test_outside_boundary_beyond_border(self):
assert_array_equal(crh.todense(c), np.eye(2))

y, x = crh.outside_boundary(c)
assert_array_equal(y, [-1, 0, 0, 1, 1, 2])
assert_array_equal(x, [0, -1, 1, 0, 2, 1])
assert_array_equal(iarr.to_list(y),
[-1, 0, 0, 1, 1, 2])
assert_array_equal(iarr.to_list(x),
[0, -1, 1, 0, 2, 1])

def test_value(self):
c = ConnectedRegion(shape=(2, 2))
Expand Down

0 comments on commit 4fb2610

Please sign in to comment.