I have relatively large 3D arrays where I'm attempting to filter out specific labeled sets of pixels (operationally defined here as volumes). Labeled volumes have 26-connectivity.
I start with:
- A labeled array (based on 26-connectivity), where each connected component is assigned a value
- A array of label values that need to be removed from the labeled/binary array
- An array with single seed indices from each of the labeled regions that are to be deleted.
A mock version of these starting variables can be constructed below.
import numpy as np
labeled = np.zeros((600,600,600)) # Empty labeled array
filter_coords = np.zeros((1000, 3),dtype=int) # Empty coords array
filter_ids = np.arange(3,3001, step=3)# Values associated with each label coord
id = 0
for i in range(1,3001):
# Random bottom and top coords to label and create a "volume".
b = np.random.randint(0,600,3,dtype=int)
t = np.random.randint(0,50,3,dtype=int)
top = b + t
#Fill the labeled array with 'mock' labeled volumes
labeled[b[0]:top[0],
b[1]:top[1],
b[2]:top[2]] = i
# Find coords from 1000 of these volumes
if i % 3 == 0:
filter_coords[id] = b
id += 1
In my current approach, I find a single seed coordinate from a single element of the labeled volume that needs to be filtered. I then start expanding a box around that region and convert all labeled elements into zeros until the expanding box meets no more labeled elements of interest.
# Remove labeled regions from volume
def filter(label, filter_ids, fcoords):
for i in range(fcoords.shape[0]):
filtered = False
b = 25 # Arbitrary starting box size
while filtered == False:
min = fcoords[i] - b
min[min < 0] = 0 # Make sure lower bound isn't negative
mask = label[min[0]:fcoords[i,0]+b+1,
min[1]:fcoords[i,1]+b+1,
min[2]:fcoords[i,2]+b+1]
if filter_ids[i] in mask:
# If the id is present in our sub-set, replace it w/ 0
mask[mask == filter_ids[i]] = 0
# Then replace the original region with the mask
label[min[0]:fcoords[i,0]+b+1,
min[1]:fcoords[i,1]+b+1,
min[2]:fcoords[i,2]+b+1] = mask
b += 5 # Increase box size
else:
filtered = True
return label
labeled = filter(labeled, filter_ids, filter_coords)
Could anyone provide suggestions on whether my approach to this problem is robust? If not, are there alternative methods that I could implement?
Thanks.