From fe4a9b58471af2a123266eecfdb063a9a5f240e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C4=9Bj=20T=C3=BD=C4=8D?= Date: Wed, 19 Nov 2014 23:02:34 +0100 Subject: [PATCH] Made the scan code cleaner and faster (but longer) --- skimage/measure/_ccomp.pyx | 178 +++++++++++++++++++++++++++++-------- 1 file changed, 139 insertions(+), 39 deletions(-) diff --git a/skimage/measure/_ccomp.pyx b/skimage/measure/_ccomp.pyx index d471ef16..685cb338 100644 --- a/skimage/measure/_ccomp.pyx +++ b/skimage/measure/_ccomp.pyx @@ -502,7 +502,6 @@ cdef void scan1D(DTYPE_t *data_p, DTYPE_t *forest_p, shape_info *shapeinfo, for x in range(1, shapeinfo.x): rindex += 1 # Handle the first row - # First row => rindex == j if data_p[rindex] == bgval: # Nothing to do if we are background continue @@ -519,6 +518,7 @@ cdef void scan2D(DTYPE_t *data_p, DTYPE_t *forest_p, shape_info *shapeinfo, cdef INTS_t *DEX = shapeinfo.DEX scan1D(data_p, forest_p, shapeinfo, bg, connectivity, 0, z) for y in range(1, shapeinfo.y): + # BEGINNING of x = 0 rindex = shapeinfo.ravel_index(0, y, 0, shapeinfo) # Handle the first column if data_p[rindex] != bgval: @@ -528,9 +528,9 @@ cdef void scan2D(DTYPE_t *data_p, DTYPE_t *forest_p, shape_info *shapeinfo, if connectivity >= 2: join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ec]) + # END of x = 0 - # Handle the rest of columns - for x in range(1, shapeinfo.x): + for x in range(1, shapeinfo.x - 1): # We have just moved to another column (of the same row) # so we increment the raveled index. It will be reset when we get # to another row, so we don't have to worry about altering it here. @@ -544,14 +544,27 @@ cdef void scan2D(DTYPE_t *data_p, DTYPE_t *forest_p, shape_info *shapeinfo, if connectivity >= 2: join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ea]) - if x + 1 < shapeinfo.x: - join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ec]) + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ec]) + + # Finally, the last column + # BEGINNING of x = max + rindex += 1 + if data_p[rindex] != bgval: + # Nothing to do if we are background + + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_eb]) + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ed]) + + if connectivity >= 2: + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ea]) + # END of x = max cdef void scan3D(DTYPE_t *data_p, DTYPE_t *forest_p, shape_info *shapeinfo, bginfo *bg, DTYPE_t connectivity): """ Perform forward scan on a 2D array. + """ cdef DTYPE_t x, y, z, rindex, bgval = bg.background_val cdef INTS_t *DEX = shapeinfo.DEX @@ -559,6 +572,8 @@ cdef void scan3D(DTYPE_t *data_p, DTYPE_t *forest_p, shape_info *shapeinfo, scan2D(data_p, forest_p, shapeinfo, bg, connectivity, 0) for z in range(1, shapeinfo.z): # Handle first row in 3D manner + # BEGINNING of y = 0 + # BEGINNING of x = 0 rindex = shapeinfo.ravel_index(0, 0, z, shapeinfo) if data_p[rindex] != bgval: # Nothing to do if we are background @@ -571,28 +586,45 @@ cdef void scan3D(DTYPE_t *data_p, DTYPE_t *forest_p, shape_info *shapeinfo, join_trees_wrapper(data_p, forest_p, rindex, DEX[D_em]) if connectivity >= 3: join_trees_wrapper(data_p, forest_p, rindex, DEX[D_en]) + # END of x = 0 - for x in range(1, shapeinfo.x): + for x in range(1, shapeinfo.x - 1): rindex += 1 # Handle the first row - if data_p[rindex] != bgval: + if data_p[rindex] == bgval: # Nothing to do if we are background + continue - join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ed]) - join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ej]) + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ed]) + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ej]) - if connectivity >= 2: - join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ei]) - if x + 1 < shapeinfo.x: - join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ek]) - join_trees_wrapper(data_p, forest_p, rindex, DEX[D_em]) - if connectivity >= 3: - join_trees_wrapper(data_p, forest_p, rindex, DEX[D_el]) - if x + 1 < shapeinfo.x: - join_trees_wrapper(data_p, forest_p, rindex, - DEX[D_en]) + if connectivity >= 2: + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ei]) + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ek]) + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_em]) + if connectivity >= 3: + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_el]) + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_en]) - for y in range(1, shapeinfo.y): + # BEGINNING of x = max + rindex += 1 + # Handle the last element of the first row + if data_p[rindex] != bgval: + # Nothing to do if we are background + + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ed]) + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ej]) + + if connectivity >= 2: + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ei]) + if connectivity >= 3: + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_el]) + # END of x = max + # END of y = 0 + + for y in range(1, shapeinfo.y - 1): + # BEGINNING of y = ... + # BEGINNING of x = 0 rindex = shapeinfo.ravel_index(0, y, z, shapeinfo) # Handle the first column in 3D manner if data_p[rindex] != bgval: @@ -605,17 +637,14 @@ cdef void scan3D(DTYPE_t *data_p, DTYPE_t *forest_p, shape_info *shapeinfo, join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ec]) join_trees_wrapper(data_p, forest_p, rindex, DEX[D_eg]) join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ek]) - if y + 1 < shapeinfo.y: - join_trees_wrapper(data_p, forest_p, rindex, DEX[D_em]) + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_em]) if connectivity >= 3: join_trees_wrapper(data_p, forest_p, rindex, DEX[D_eh]) - if y + 1 < shapeinfo.y: - join_trees_wrapper(data_p, forest_p, rindex, - DEX[D_en]) - + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_en]) + # END of x = 0 # Handle the rest of columns - for x in range(1, shapeinfo.x): + for x in range(1, shapeinfo.x - 1): rindex += 1 if data_p[rindex] == bgval: # Nothing to do if we are background @@ -629,17 +658,88 @@ cdef void scan3D(DTYPE_t *data_p, DTYPE_t *forest_p, shape_info *shapeinfo, join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ea]) join_trees_wrapper(data_p, forest_p, rindex, DEX[D_eg]) join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ei]) - if x + 1 < shapeinfo.x: - join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ec]) - join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ek]) - if y + 1 < shapeinfo.y: - join_trees_wrapper(data_p, forest_p, rindex, DEX[D_em]) + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ec]) + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ek]) + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_em]) if connectivity >= 3: join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ef]) - if x + 1 < shapeinfo.x: - join_trees_wrapper(data_p, forest_p, rindex, DEX[D_eh]) - if y + 1 < shapeinfo.y: - join_trees_wrapper(data_p, forest_p, rindex, DEX[D_el]) - if x + 1 < shapeinfo.x: - join_trees_wrapper(data_p, forest_p, - rindex, DEX[D_en]) + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_eh]) + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_el]) + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_en]) + + # BEGINNING of x = max + rindex += 1 + if data_p[rindex] != bgval: + # Nothing to do if we are background + + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_eb]) + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ed]) + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ej]) + + if connectivity >= 2: + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ea]) + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_eg]) + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ei]) + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_em]) + if connectivity >= 3: + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ef]) + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_el]) + # END of x = max + # END of y = ... + + # BEGINNING of y = max + # BEGINNING of x = 0 + rindex = shapeinfo.ravel_index(0, shapeinfo.y, z, shapeinfo) + # Handle the first column in 3D manner + if data_p[rindex] != bgval: + # Nothing to do if we are background + + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_eb]) + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ej]) + + if connectivity >= 2: + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ec]) + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_eg]) + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ek]) + if connectivity >= 3: + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_eh]) + # END of x = 0 + + # Handle the rest of columns + for x in range(1, shapeinfo.x - 1): + rindex += 1 + if data_p[rindex] == bgval: + # Nothing to do if we are background + continue + + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_eb]) + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ed]) + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ej]) + + if connectivity >= 2: + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ea]) + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_eg]) + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ei]) + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ec]) + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ek]) + if connectivity >= 3: + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ef]) + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_eh]) + + # BEGINNING of x = max + rindex += 1 + if data_p[rindex] != bgval: + # Nothing to do if we are background + + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_eb]) + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ed]) + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ej]) + + if connectivity >= 2: + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ea]) + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_eg]) + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ei]) + if connectivity >= 3: + join_trees_wrapper(data_p, forest_p, rindex, DEX[D_ef]) + # END of x = max + # END of y = max