-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #104 from jni/optimise-grain-finding-3
Optimise grain finding
- Loading branch information
Showing
14 changed files
with
318 additions
and
205 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
from numba import njit | ||
import numpy as np | ||
|
||
|
||
@njit | ||
def find_first(arr): | ||
for i in range(len(arr)): | ||
if arr[i]: | ||
return i | ||
|
||
|
||
@njit | ||
def flood_fill(seed, index, points_remaining, grains, boundary_x, boundary_y, | ||
added_coords): | ||
"""Flood fill algorithm that uses the x and y boundary arrays to | ||
fill a connected area around the seed point. The points are inserted | ||
into a grain object and the grain map array is updated. | ||
Parameters | ||
---------- | ||
seed : tuple of 2 int | ||
Seed point x for flood fill | ||
index : int | ||
Value to fill in grain map | ||
points_remaining : numpy.ndarray | ||
Boolean map of the points that have not been assigned a grain yet | ||
Returns | ||
------- | ||
grain : defdap.ebsd.Grain | ||
New grain object with points added | ||
""" | ||
x, y = seed | ||
grains[y, x] = index | ||
points_remaining[y, x] = False | ||
edge = [seed] | ||
added_coords[0] = seed | ||
npoints = 1 | ||
|
||
while edge: | ||
x, y = edge.pop() | ||
moves = [(x+1, y), (x-1, y), (x, y+1), (x, y-1)] | ||
# get rid of any that go out of the map area | ||
if x <= 0: | ||
moves.pop(1) | ||
elif x > grains.shape[1] - 2: | ||
moves.pop(0) | ||
if y <= 0: | ||
moves.pop(-1) | ||
elif y > grains.shape[0] - 2: | ||
moves.pop(-2) | ||
|
||
for (s, t) in moves: | ||
if grains[t, s] > 0: | ||
continue | ||
|
||
add_point = False | ||
|
||
if t == y: | ||
# moving horizontally | ||
if s > x: | ||
# moving right | ||
add_point = not boundary_x[y, x] | ||
else: | ||
# moving left | ||
add_point = not boundary_x[t, s] | ||
else: | ||
# moving vertically | ||
if t > y: | ||
# moving down | ||
add_point = not boundary_y[y, x] | ||
else: | ||
# moving up | ||
add_point = not boundary_y[t, s] | ||
|
||
if add_point: | ||
added_coords[npoints] = s, t | ||
grains[t, s] = index | ||
points_remaining[t, s] = False | ||
npoints += 1 | ||
edge.append((s, t)) | ||
|
||
return added_coords[:npoints] | ||
|
||
|
||
@njit | ||
def flood_fill_dic(seed, index, points_remaining, grains, added_coords): | ||
"""Flood fill algorithm that uses the combined x and y boundary array | ||
to fill a connected area around the seed point. The points are returned and | ||
the grain map array is updated. | ||
Parameters | ||
---------- | ||
seed : tuple of 2 int | ||
Seed point x for flood fill | ||
index : int | ||
Value to fill in grain map | ||
points_remaining : numpy.ndarray | ||
Boolean map of the points remaining to assign a grain yet | ||
grains : numpy.ndarray | ||
added_coords : numpy.ndarray | ||
Buffer for points in the grain | ||
Returns | ||
------- | ||
numpy.ndarray | ||
Flooded points (n, 2) | ||
""" | ||
# add first point to the grain | ||
x, y = seed | ||
grains[y, x] = index | ||
points_remaining[y, x] = False | ||
edge = [seed] | ||
added_coords[0] = seed | ||
npoints = 1 | ||
|
||
while edge: | ||
x, y = edge.pop() | ||
|
||
moves = [(x+1, y), (x-1, y), (x, y+1), (x, y-1)] | ||
# get rid of any that go out of the map area | ||
if x <= 0: | ||
moves.pop(1) | ||
elif x >= grains.shape[1] - 1: | ||
moves.pop(0) | ||
if y <= 0: | ||
moves.pop(-1) | ||
elif y >= grains.shape[0] - 1: | ||
moves.pop(-2) | ||
|
||
for (s, t) in moves: | ||
add_point = False | ||
|
||
if grains[t, s] == 0: | ||
add_point = True | ||
edge.append((s, t)) | ||
|
||
elif grains[t, s] == -1 and (s > x or t > y): | ||
add_point = True | ||
|
||
if add_point: | ||
added_coords[npoints] = (s, t) | ||
grains[t, s] = index | ||
points_remaining[t, s] = False | ||
npoints += 1 | ||
|
||
return added_coords[:npoints] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.