def loop_connected_components(mask):
"""
@type mask: np.ndarray
@rtype (np.ndarray, np.ndarray, np.ndarray)
"""
c = np.array([])
init = np.array([])
fin = np.array([])
if mask.sum() > 0:
labeled = sp_image.label(mask)[0]
components = sp_image.measurements.find_objects(labeled)
c_fin = [(s[0].stop - s[0].start, s[0].stop - 1) for s in components]
if len(c_fin) > 1 and mask[0] and mask[-1]:
c_fin[0] = c_fin[0][0] + c_fin[-1][0], c_fin[0][1]
c_fin = c_fin[0:-1]
c, fin = zip(*c_fin)
c = np.array(c, dtype=int)
fin = np.array(fin, dtype=int)
init = (fin - c + 1) % mask.shape[0]
return c, init, fin
python类label()的实例源码
def remove_artifacts(self, image):
"""
Remove the connected components that are not within the parameters
Operates in place
:param image: sudoku's thresholded image w/o grid
:return: None
"""
labeled, features = label(image, structure=CROSS)
lbls = np.arange(1, features + 1)
areas = extract_feature(image, labeled, lbls, np.sum,
np.uint32, 0)
sides = extract_feature(image, labeled, lbls, min_side,
np.float32, 0, True)
diags = extract_feature(image, labeled, lbls, diagonal,
np.float32, 0, True)
for index in lbls:
area = areas[index - 1] / 255
side = sides[index - 1]
diag = diags[index - 1]
if side < 5 or side > 20 \
or diag < 15 or diag > 25 \
or area < 40:
image[labeled == index] = 0
return None
def remove_artifacts(self, image):
"""
Remove the connected components that are not within the parameters
Operates in place
:param image: sudoku's thresholded image w/o grid
:return: None
"""
labeled, features = label(image, structure=CROSS)
lbls = np.arange(1, features + 1)
areas = extract_feature(image, labeled, lbls, np.sum,
np.uint32, 0)
sides = extract_feature(image, labeled, lbls, min_side,
np.float32, 0, True)
diags = extract_feature(image, labeled, lbls, diagonal,
np.float32, 0, True)
for index in lbls:
area = areas[index - 1] / 255
side = sides[index - 1]
diag = diags[index - 1]
if side < 5 or side > 20 \
or diag < 15 or diag > 25 \
or area < 40:
image[labeled == index] = 0
return None
def adjust_prediction(self, prediction):
new_prediction = prediction
labeled, n_objects = ndimage.label(prediction > 0)
max_volume = 0
volumes = {}
for object_n in range(1, n_objects + 1):
volume = np.sum(prediction[labeled == object_n])
if volume > max_volume:
max_volume = volume
volumes.update({object_n: volume})
for object_n, volume in volumes.iteritems():
if volume < self.threshold * max_volume:
new_prediction[labeled == object_n] = 0
return new_prediction
def write_file(filename, resolution, **kwargs):
h5file = h5py.File(filename, 'w')
config = {'hdf5_file': os.path.basename(filename)}
channels = ['image', 'label', 'mask']
default_datasets = {
'image': 'volumes/raw',
'label': 'volumes/labels/neuron_ids',
'mask': 'volumes/labels/mask',
}
for channel in channels:
data = kwargs.get('{}_data'.format(channel), None)
dataset_name = kwargs.get('{}_dataset'.format(channel), default_datasets[channel])
if data is not None:
dataset = h5file.create_dataset(dataset_name, data=data, dtype=data.dtype)
dataset.attrs['resolution'] = resolution
config['{}_dataset'.format(channel)] = dataset_name
h5file.close()
return config
def find_windows_from_heatmap(image):
hot_windows = []
# Threshold the heatmap
thres = 0
image[image <= thres] = 0
# Set labels
labels = ndi.label(image)
# iterate through labels and find windows
for car_number in range(1, labels[1]+1):
# Find pixels with each car_number label value
nonzero = (labels[0] == car_number).nonzero()
# Identify x and y values of those pixels
nonzeroy = np.array(nonzero[0])
nonzerox = np.array(nonzero[1])
# Define a bounding box based on min/max x and y
bbox = ((np.min(nonzerox), np.min(nonzeroy)), (np.max(nonzerox), np.max(nonzeroy)))
hot_windows.append(bbox)
return hot_windows
def calc_detection_rate(prediction,label):
'''
Calculate the detection True Positives, False Negatives and False Positives.
TP occurs whenever the prediction region intersects the ground truth region.
FP occurs
'''
label_temp=np.copy(label)
TP=FN=FP=0.0
# pattern for ndimage neighbouring pixels
s = [[1,1,1],
[1,1,1],
[1,1,1]]
labeled_prediction, num_features_prediction = ndimage.label(prediction, structure=s)
labeled_label, num_features_label = ndimage.label(label_temp, structure=s)
for i in range(1,num_features_prediction+1):
intersection=np.sum(labeled_prediction[label==1]==i)
if intersection>0:
TP+=1
else:
FP+=1
for i in range(1,num_features_label+1):
intersection=np.sum(labeled_label[prediction==1]==i)
if intersection==0:
FN=+1
return TP,FN,FP
def calc_detection_rate(prediction,label):
'''
Calculate the detection True Positives, False Negatives and False Positives.
TP occurs whenever the prediction region intersects the ground truth region.
FP occurs
'''
label_temp=np.copy(label)
TP=FN=FP=0.0
# pattern for ndimage neighbouring pixels
s = [[1,1,1],
[1,1,1],
[1,1,1]]
labeled_prediction, num_features_prediction = ndimage.label(prediction, structure=s)
labeled_label, num_features_label = ndimage.label(label_temp, structure=s)
for i in range(1,num_features_prediction+1):
intersection=np.sum(labeled_prediction[label==1]==i)
if intersection>0:
TP+=1
else:
FP+=1
for i in range(1,num_features_label+1):
intersection=np.sum(labeled_label[prediction==1]==i)
if intersection==0:
FN=+1
return TP,FN,FP
def calc_detection_rate(prediction,label):
'''
Calculate the detection True Positives, False Negatives and False Positives.
TP occurs whenever the prediction region intersects the ground truth region.
FP occurs
'''
label_temp=np.copy(label)
TP=FN=FP=0.0
# pattern for ndimage neighbouring pixels
s = [[1,1,1],
[1,1,1],
[1,1,1]]
labeled_prediction, num_features_prediction = ndimage.label(prediction, structure=s)
labeled_label, num_features_label = ndimage.label(label_temp, structure=s)
for i in range(1,num_features_prediction+1):
intersection=np.sum(labeled_prediction[label==1]==i)
if intersection>0:
TP+=1
else:
FP+=1
for i in range(1,num_features_label+1):
intersection=np.sum(labeled_label[prediction==1]==i)
if intersection==0:
FN=+1
return TP,FN,FP
def calc_detection_rate(prediction,label):
'''
Calculate the detection True Positives, False Negatives and False Positives.
TP occurs whenever the prediction region intersects the ground truth region.
FP occurs
'''
label_temp=np.copy(label)
TP=FN=FP=0.0
# pattern for ndimage neighbouring pixels
s = [[1,1,1],
[1,1,1],
[1,1,1]]
labeled_prediction, num_features_prediction = ndimage.label(prediction, structure=s)
labeled_label, num_features_label = ndimage.label(label_temp, structure=s)
for i in range(1,num_features_prediction+1):
intersection=np.sum(labeled_prediction[label==1]==i)
if intersection>0:
TP+=1
else:
FP+=1
for i in range(1,num_features_label+1):
intersection=np.sum(labeled_label[prediction==1]==i)
if intersection==0:
FN=+1
return TP,FN,FP
def calc_detection_rate(prediction,label):
'''
Calculate the detection True Positives, False Negatives and False Positives.
TP occurs whenever the prediction region intersects the ground truth region.
FP occurs
'''
label_temp=np.copy(label)
TP=FN=FP=0.0
# pattern for ndimage neighbouring pixels
s = [[1,1,1],
[1,1,1],
[1,1,1]]
labeled_prediction, num_features_prediction = ndimage.label(prediction, structure=s)
labeled_label, num_features_label = ndimage.label(label_temp, structure=s)
for i in range(1,num_features_prediction+1):
intersection=np.sum(labeled_prediction[label==1]==i)
if intersection>0:
TP+=1
else:
FP+=1
for i in range(1,num_features_label+1):
intersection=np.sum(labeled_label[prediction==1]==i)
if intersection==0:
FN=+1
return TP,FN,FP
def get_centers_of_mass_from_blobs(segmentation_layer, iterations=3):
"""
Determine the centers of each object in an image
::param segmentation_layer: NxM ndarray image mask of all target objects
::param iterations: threshold for removal of small non-target objects
::return centers_of_mass: a np ndarray of x,y coordinates for the center of each target object
"""
segmentation_layer = ndimage.binary_opening(segmentation_layer, iterations=iterations) # remove small objects
labels, label_number = ndimage.measurements.label(segmentation_layer) # label remaining blobs
centers_of_mass = np.zeros((label_number, 2))
for i in range(label_number):
idx = np.where(labels == i+1) # calculate the center of mass for each blob
centers_of_mass[i, 1] = np.mean(idx[1].astype(float)) # must be float
centers_of_mass[i, 0] = np.mean(idx[0].astype(float)) # must be float
return centers_of_mass
def remove_small_blobs(centers_of_mass, segmentation_layer):
"""
removes non-overlapping pixel-islands and cell centres (centers_of_mass)
:param segmentation_layer: NxM ndarray image mask of all target objects
:param centers_of_mass: a np ndarray of x,y coordinates for the center of each target object
:return updated_labels:
"""
labels, label_number = ndimage.label(segmentation_layer) # label all pixel islands
updated_labels = np.zeros_like(labels)
centers_of_mass_to_keep = np.zeros(len(centers_of_mass)) # holder
for i in range(label_number):
idx = np.where(labels == i+1)
for j, c in enumerate(centers_of_mass.astype(int)):
if labels[c[0], c[1]] == i+1: # if the center_of_mass is in the blob
updated_labels[idx] = 1 # add the blob
centers_of_mass_to_keep[j] = 1 # add the center_of_mass
centers_of_mass_idx = np.where(centers_of_mass_to_keep == 1)
updated_centers_of_mass = centers_of_mass[centers_of_mass_idx]
return updated_labels, updated_centers_of_mass
def calculate_distance(centers_of_mass, image):
"""
takes the centers of each blob, and an image to be segmented. Divides the image according to the center of masses
by a random walk
:param image: a binarised image to be segmented
:param centers_of_mass: the centres that will define the maxima of the watershed segmentation
:return segmentation_labels: a labelled image/segmentation, where each index belongs do a different center of mass
"""
# random walk segmentation of 2D image-mask array
distance = ndimage.distance_transform_edt(np.abs(image-1))
local_maxi = np.zeros_like(image)
for c in centers_of_mass:
local_maxi[int(c[0]), int(c[1])] = 1
markers = ndimage.label(local_maxi)[0]
segmentation_labels = segmentation.random_walker(distance, markers, beta=60)
return segmentation_labels
def blob_labels(centers_of_mass, blob_image):
"""
label nuclei with segmentation - so labels are in the same order as the outer layer
:param list centers_of_mass: centers of target blobs/cells
:param np.array blob_image: image of the target cells, or nuclei of cells
:return segmented_blobs: a labelled image where each index is a different cell
:return distance: image where each pixel's value is related to how far away from a blob center it is
"""
image = np.abs(blob_image-1)
distance = ndimage.distance_transform_edt(np.abs(image-1))
local_maxi = np.zeros_like(image)
for c in centers_of_mass:
local_maxi[int(c[0]), int(c[1])] = 1
markers = ndimage.label(local_maxi)[0]
segmented_blobs = segmentation.random_walker(distance, markers, beta=20)
return segmented_blobs, distance
def getAlignImg(t,label = None):#!!!notice, only take uint8 type for the imrotate function!!!
f = lambda x:np.asarray([float(a) for a in x]);
o = f(t.ImageOrientationPatient);
o1 = o[:3];
o2 = o[3:];
oh = np.cross(o1,o2);
or1 = np.asarray([0.6,0.6,-0.2]);
o2new = np.cross(oh,or1);
theta = np.arccos(np.dot(o2,o2new)/np.sqrt(np.sum(o2**2)*np.sum(o2new**2)))*180/3.1416;
theta = theta * np.sign(np.dot(oh,np.cross(o2,o2new)));
im_max = np.percentile(t.pixel_array.flatten(),99);
res = imrotate(np.array(np.clip(np.array(t.pixel_array,dtype=np.float)/im_max*256,0,255),dtype=np.uint8),theta);
if label is None:
return res;
else:
lab = imrotate(label,theta);
return res,lab
def getAlignImg(t,label = None):#!!!notice, only take uint8 type for the imrotate function!!!
print 'CALLING GET_ALIGN'
f = lambda x:np.asarray([float(a) for a in x]);
o = f(t.ImageOrientationPatient);
o1 = o[:3];
o2 = o[3:];
oh = np.cross(o1,o2);
or1 = np.asarray([0.6,0.6,-0.2]);
o2new = np.cross(oh,or1);
theta = np.arccos(np.dot(o2,o2new)/np.sqrt(np.sum(o2**2)*np.sum(o2new**2)))*180/3.1416;
theta = theta * np.sign(np.dot(oh,np.cross(o2,o2new)));
im_max = np.percentile(t.pixel_array.flatten(),99);
res = imrotate(np.array(np.clip(np.array(t.pixel_array,dtype=np.float)/im_max*256,0,255),
dtype=np.uint8),theta);
if label is None:
return res;
else:
lab = imrotate(label,theta);
return res,lab
def check(n):
a = [(n>>i) & 1 for i in range(8)]
a.insert(4, 0) # make the 3x3 unit
# if up, down, left, right all are 1, you cannot make a hole
if a[1] & a[3] & a[5] & a[7]:return False
#if sum(a)==1: return False
a = np.array(a).reshape((3,3))
# segments
n = label(a, strc)[1]
# if sum is 0, it is a isolate point, you cannot remove it.
# if number of segments > 2, you cannot split them.
return n<2
return a.sum()>1 and n<2
if a.sum()==1 or n>2: return 2
if a.sum()>1 and n<2: return 1
return 0
def run(self, ips, snap, img, para = None):
self.ips.lut[:] = self.buflut
ndimg.gaussian_filter(snap, para['sigma'], output=img)
mark = img<para['thr'] if para['ud'] else img>para['thr']
markers, n = ndimg.label(mark, np.ones((3,3)), output=np.uint16)
if not para['ud']:img[:] = 255-img
mark = watershed(img, markers, line=True, conn=para['con']+1)
mark = np.multiply((mark==0), 255, dtype=np.uint8)
if para['type'] == 'white line':
img[:] = mark
if para['type'] == 'gray line':
np.minimum(snap, mark, out=img)
if para['type'] == 'white line on ori':
#img //=2
np.maximum(snap, mark, out=img)
def run(self, ips, snap, img, para = None):
#denoised = rank.median(img, disk(para['sigma']))
#gradient = rank.gradient(denoised, disk(para['gdt']))
ndimg.gaussian_filter(snap, para['sigma'], output=img)
markers, n = ndimg.label(ips.get_msk(), np.ones((3,3)), output=np.uint16)
if not para['ud']:img[:] = 255-img
mark = watershed(img, markers, line=True, conn=para['con']+1)
mark = np.multiply((mark==0), 255, dtype=np.uint8)
if para['type'] == 'white line':
img[:] = mark
if para['type'] == 'gray line':
np.minimum(snap, mark, out=img)
if para['type'] == 'white line on ori':
np.maximum(snap, mark, out=img)
def run(self, ips, imgs, para = None):
k, unit = ips.unit
strc = generate_binary_structure(3, 1 if para['con']=='4-connect' else 2)
lab, n = label(imgs==0 if para['inv'] else imgs, strc, output=np.uint16)
idx = (np.ones(n+1)*(0 if para['inv'] else para['front'])).astype(np.uint8)
ls = regionprops(lab)
for i in ls:
if para['vol'] == 0: break
if para['vol']>0:
if i.area*k**3 < para['vol']: idx[i.label] = para['back']
if para['vol']<0:
if i.area*k**3 >= -para['vol']: idx[i.label] = para['back']
for i in ls:
if para['dia'] == 0: break
d = norm(np.array(i.bbox[:3]) - np.array(i.bbox[3:]))
if para['dia']>0:
if d*k < para['dia']: idx[i.label] = para['back']
if para['dia']<0:
if d*k >= -para['dia']: idx[i.label] = para['back']
idx[0] = para['front'] if para['inv'] else 0
imgs[:] = idx[lab]
def __init__(self,path):
blur_radius = 1.0
threshold = 50
img = misc.imread(path)
self.origin = img
# smooth the image (to remove small objects)
imgf = ndimage.gaussian_filter(img, blur_radius)
threshold = 50
# find connected components
self.img, self.count = ndimage.label(imgf > threshold)
self.labels = self.calculate_labels()
# Return
# ----------
# labels : dictionary, key = label, value = list of bounding in order y1, y2, x1, x2
def detect_objects_heatmap(heatmap):
data = 256 * heatmap
data_max = filters.maximum_filter(data, 3)
maxima = (data == data_max)
data_min = filters.minimum_filter(data, 3)
diff = ((data_max - data_min) > 0.3)
maxima[diff == 0] = 0
labeled, num_objects = ndimage.label(maxima)
slices = ndimage.find_objects(labeled)
objects = np.zeros((num_objects, 2), dtype=np.int32)
pidx = 0
for (dy, dx) in slices:
pos = [(dy.start + dy.stop - 1) // 2, (dx.start + dx.stop - 1) // 2]
if heatmap[pos[0], pos[1]] > config.CENTER_TR:
objects[pidx, :] = pos
pidx += 1
return objects[:pidx]
def findMaximaOnFG(self, param):
self.defineFG(param)
#self.smooth_corr()
self.coorExtract = [0, 0]
xmin, ymin = self.coorExtract
img=self.candi
img [self.FG ==0] =0
im = img_as_float(img)
image_max = ndimage.maximum_filter(im, size=10, mode='constant')
coordinates = peak_local_max(im, min_distance=10)
tep=np.zeros(self.candi.shape)
for i,ide in enumerate(coordinates):
tep[ide[0],ide[1]] = self.candi[ide[0],ide[1]]
lbl = ndimage.label(tep)[0]
centerc = np.round(ndimage.measurements.center_of_mass(tep, lbl, range(1,np.max(lbl)+1)))
if centerc.size > 0:
self.centersX = centerc[:,0].astype(int)
self.centersY = centerc[:,1].astype(int)
self.nComponents = len(self.centersX)
def extract_digits(self, image):
"""
Extract digits from a binary image representing a sudoku
:param image: binary image/sudoku
:return: array of digits and their probabilities
"""
prob = np.zeros(4, dtype=np.float32)
digits = np.zeros((4, 9, 9), dtype=object)
for i in range(4):
labeled, features = label(image, structure=CROSS)
objs = find_objects(labeled)
for obj in objs:
roi = image[obj]
# center of bounding box
cy = (obj[0].stop + obj[0].start) / 2
cx = (obj[1].stop + obj[1].start) / 2
dists = cdist([[cy, cx]], CENTROIDS, 'euclidean')
pos = np.argmin(dists)
cy, cx = pos % 9, pos / 9
# 28x28 image, center relative to sudoku
prediction = self.classifier.classify(morph(roi))
if digits[i, cy, cx] is 0:
# Newly found digit
digits[i, cy, cx] = prediction
prob[i] += prediction[0, 0]
elif prediction[0, 0] > digits[i, cy, cx][0, 0]:
# Overlapping! (noise), choose the most probable prediction
prob[i] -= digits[i, cy, cx][0, 0]
digits[i, cy, cx] = prediction
prob[i] += prediction[0, 0]
image = np.rot90(image)
logging.info(prob)
return digits[np.argmax(prob)]
def extract_digits(self, image):
"""
Extract digits from a binary image representing a sudoku
:param image: binary image/sudoku
:return: array of digits and their probabilities
"""
prob = np.zeros(4, dtype=np.float32)
digits = np.zeros((4, 9, 9), dtype=object)
for i in range(4):
labeled, features = label(image, structure=CROSS)
objs = find_objects(labeled)
for obj in objs:
roi = image[obj]
# center of bounding box
cy = (obj[0].stop + obj[0].start) / 2
cx = (obj[1].stop + obj[1].start) / 2
dists = cdist([[cy, cx]], CENTROIDS, 'euclidean')
pos = np.argmin(dists)
cy, cx = pos % 9, pos / 9
# 28x28 image, center relative to sudoku
prediction = self.classifier.classify(morph(roi))
if digits[i, cy, cx] is 0:
# Newly found digit
digits[i, cy, cx] = prediction
prob[i] += prediction[0, 0]
elif prediction[0, 0] > digits[i, cy, cx][0, 0]:
# Overlapping! (noise), choose the most probable prediction
prob[i] -= digits[i, cy, cx][0, 0]
digits[i, cy, cx] = prediction
prob[i] += prediction[0, 0]
image = np.rot90(image)
logging.info(prob)
return digits[np.argmax(prob)]
def filter_isolated_cells(array, struct):
filtered_array = np.copy(array)
id_regions, num_ids = ndimage.label(filtered_array, structure=struct)
id_sizes = np.array(ndimage.sum(array, id_regions, range(num_ids + 1)))
area_mask = (id_sizes == 1)
filtered_array[area_mask[id_regions]] = 0
return filtered_array
#Decide if given spectrum shows bird sounds or noise only
def hysteresis_thresholding(probs: np.array, candidates: np.array, low_threshold: float, high_threshold: float):
low_mask = candidates & (probs > low_threshold)
# Connected components extraction
label_components, count = label(low_mask, np.ones((3, 3)))
# Keep components with high threshold elements
good_labels = np.unique(label_components[low_mask & (probs > high_threshold)])
label_masks = np.zeros((count + 1,), bool)
label_masks[good_labels] = 1
return label_masks[label_components]
def has_uniform_seed_margin(self, seed_margin=20.0):
"""Test if a subvolume has a margin of uniform label around its seed.
Parameters
----------
seed_margin : float, optional
The minimum acceptable margin of uniform target label around the seed
voxel (in nm, default 20.0).
Returns
-------
bool
True if the rectangular margin around the seed position is uniform.
"""
margin = np.ceil(np.reciprocal(np.array(CONFIG.volume.resolution),
dtype=np.float64) * seed_margin).astype(np.int64)
mask_target = self.label_mask
# If data is unlabeled, can not test so always succeed.
if mask_target is None:
return True
# Seed location in the mask accounting for offset of label from image.
ctr = self.seed - (np.asarray(self.image.shape) - np.asarray(mask_target.shape)) // 2
seed_fov = (ctr - margin, ctr + margin + 1)
seed_region = mask_target[seed_fov[0][0]:seed_fov[1][0],
seed_fov[0][1]:seed_fov[1][1],
seed_fov[0][2]:seed_fov[1][2]]
return np.all(seed_region)
def __next__(self):
subv = six.next(self.subvolume_generator)
label_im, _ = ndimage.label(subv.label_mask)
label_axis_margin = (np.array(subv.image.shape) - np.array(subv.label_mask.shape)) // 2
seed_label = label_im[tuple(subv.seed - label_axis_margin)]
subv.label_mask = label_im == seed_label
return subv