def test_01_03_crop_labels(self): labels, image = cpo.crop_labels_and_image(np.zeros((10, 30)), np.zeros((10, 20))) self.assertEqual(tuple(labels.shape), (10, 20)) self.assertEqual(tuple(image.shape), (10, 20)) labels, image = cpo.crop_labels_and_image(np.zeros((20, 20)), np.zeros((10, 20))) self.assertEqual(tuple(labels.shape), (10, 20)) self.assertEqual(tuple(image.shape), (10, 20))
def do_measurements(self, workspace, image_name, object_name, center_object_name, center_choice, bin_count_settings, dd): '''Perform the radial measurements on the image set workspace - workspace that holds images / objects image_name - make measurements on this image object_name - make measurements on these objects center_object_name - use the centers of these related objects as the centers for radial measurements. None to use the objects themselves. center_choice - the user's center choice for this object: C_SELF, C_CENTERS_OF_OBJECTS or C_EDGES_OF_OBJECTS. bin_count_settings - the bin count settings group d - a dictionary for saving reusable partial results returns one statistics tuple per ring. ''' assert isinstance(workspace, cpw.Workspace) assert isinstance(workspace.object_set, cpo.ObjectSet) bin_count = bin_count_settings.bin_count.value wants_scaled = bin_count_settings.wants_scaled.value maximum_radius = bin_count_settings.maximum_radius.value image = workspace.image_set.get_image(image_name, must_be_grayscale=True) objects = workspace.object_set.get_objects(object_name) labels, pixel_data = cpo.crop_labels_and_image(objects.segmented, image.pixel_data) nobjects = np.max(objects.segmented) measurements = workspace.measurements assert isinstance(measurements, cpmeas.Measurements) heatmaps = {} for heatmap in self.heatmaps: if heatmap.object_name.get_objects_name() == object_name and \ image_name == heatmap.image_name.get_image_name() and \ heatmap.get_number_of_bins() == bin_count: dd[id(heatmap)] = \ heatmaps[MEASUREMENT_ALIASES[heatmap.measurement.value]] = \ np.zeros(labels.shape) if nobjects == 0: for bin in range(1, bin_count + 1): for feature in (F_FRAC_AT_D, F_MEAN_FRAC, F_RADIAL_CV): feature_name = ( (feature + FF_GENERIC) % (image_name, bin, bin_count)) measurements.add_measurement( object_name, "_".join([M_CATEGORY, feature_name]), np.zeros(0)) if not wants_scaled: measurement_name = "_".join([M_CATEGORY, feature, image_name, FF_OVERFLOW]) measurements.add_measurement( object_name, measurement_name, np.zeros(0)) return [(image_name, object_name, "no objects", "-", "-", "-", "-")] name = (object_name if center_object_name is None else "%s_%s" % (object_name, center_object_name)) if dd.has_key(name): normalized_distance, i_center, j_center, good_mask = dd[name] else: d_to_edge = distance_to_edge(labels) if center_object_name is not None: # # Use the center of the centering objects to assign a center # to each labeled pixel using propagation # center_objects = workspace.object_set.get_objects(center_object_name) center_labels, cmask = cpo.size_similarly( labels, center_objects.segmented) pixel_counts = fix(scind.sum( np.ones(center_labels.shape), center_labels, np.arange(1, np.max(center_labels) + 1, dtype=np.int32))) good = pixel_counts > 0 i, j = (centers_of_labels(center_labels) + .5).astype(int) ig = i[good] jg = j[good] lg = np.arange(1, len(i) + 1)[good] if center_choice == C_CENTERS_OF_OTHER: # # Reduce the propagation labels to the centers of # the centering objects # center_labels = np.zeros(center_labels.shape, int) center_labels[ig, jg] = lg cl, d_from_center = propagate(np.zeros(center_labels.shape), center_labels, labels != 0, 1) # # Erase the centers that fall outside of labels # cl[labels == 0] = 0 # # If objects are hollow or crescent-shaped, there may be # objects without center labels. As a backup, find the # center that is the closest to the center of mass. # missing_mask = (labels != 0) & (cl == 0) missing_labels = np.unique(labels[missing_mask]) if len(missing_labels): all_centers = centers_of_labels(labels) missing_i_centers, missing_j_centers = \ all_centers[:, missing_labels - 1] di = missing_i_centers[:, np.newaxis] - ig[np.newaxis, :] dj = missing_j_centers[:, np.newaxis] - jg[np.newaxis, :] missing_best = lg[np.argsort((di * di + dj * dj,))[:, 0]] best = np.zeros(np.max(labels) + 1, int) best[missing_labels] = missing_best cl[missing_mask] = best[labels[missing_mask]] # # Now compute the crow-flies distance to the centers # of these pixels from whatever center was assigned to # the object. # iii, jjj = np.mgrid[0:labels.shape[0], 0:labels.shape[1]] di = iii[missing_mask] - i[cl[missing_mask] - 1] dj = jjj[missing_mask] - j[cl[missing_mask] - 1] d_from_center[missing_mask] = np.sqrt(di * di + dj * dj) else: # Find the point in each object farthest away from the edge. # This does better than the centroid: # * The center is within the object # * The center tends to be an interesting point, like the # center of the nucleus or the center of one or the other # of two touching cells. # i, j = maximum_position_of_labels(d_to_edge, labels, objects.indices) center_labels = np.zeros(labels.shape, int) center_labels[i, j] = labels[i, j] # # Use the coloring trick here to process touching objects # in separate operations # colors = color_labels(labels) ncolors = np.max(colors) d_from_center = np.zeros(labels.shape) cl = np.zeros(labels.shape, int) for color in range(1, ncolors + 1): mask = colors == color l, d = propagate(np.zeros(center_labels.shape), center_labels, mask, 1) d_from_center[mask] = d[mask] cl[mask] = l[mask] good_mask = cl > 0 if center_choice == C_EDGES_OF_OTHER: # Exclude pixels within the centering objects # when performing calculations from the centers good_mask = good_mask & (center_labels == 0) i_center = np.zeros(cl.shape) i_center[good_mask] = i[cl[good_mask] - 1] j_center = np.zeros(cl.shape) j_center[good_mask] = j[cl[good_mask] - 1] normalized_distance = np.zeros(labels.shape) if wants_scaled: total_distance = d_from_center + d_to_edge normalized_distance[good_mask] = (d_from_center[good_mask] / (total_distance[good_mask] + .001)) else: normalized_distance[good_mask] = \ d_from_center[good_mask] / maximum_radius dd[name] = [normalized_distance, i_center, j_center, good_mask] ngood_pixels = np.sum(good_mask) good_labels = labels[good_mask] bin_indexes = (normalized_distance * bin_count).astype(int) bin_indexes[bin_indexes > bin_count] = bin_count labels_and_bins = (good_labels - 1, bin_indexes[good_mask]) histogram = coo_matrix((pixel_data[good_mask], labels_and_bins), (nobjects, bin_count + 1)).toarray() sum_by_object = np.sum(histogram, 1) sum_by_object_per_bin = np.dstack([sum_by_object] * (bin_count + 1))[0] fraction_at_distance = histogram / sum_by_object_per_bin number_at_distance = coo_matrix((np.ones(ngood_pixels), labels_and_bins), (nobjects, bin_count + 1)).toarray() object_mask = number_at_distance > 0 sum_by_object = np.sum(number_at_distance, 1) sum_by_object_per_bin = np.dstack([sum_by_object] * (bin_count + 1))[0] fraction_at_bin = number_at_distance / sum_by_object_per_bin mean_pixel_fraction = fraction_at_distance / (fraction_at_bin + np.finfo(float).eps) masked_fraction_at_distance = masked_array(fraction_at_distance, ~object_mask) masked_mean_pixel_fraction = masked_array(mean_pixel_fraction, ~object_mask) # Anisotropy calculation. Split each cell into eight wedges, then # compute coefficient of variation of the wedges' mean intensities # in each ring. # # Compute each pixel's delta from the center object's centroid i, j = np.mgrid[0:labels.shape[0], 0:labels.shape[1]] imask = i[good_mask] > i_center[good_mask] jmask = j[good_mask] > j_center[good_mask] absmask = (abs(i[good_mask] - i_center[good_mask]) > abs(j[good_mask] - j_center[good_mask])) radial_index = (imask.astype(int) + jmask.astype(int) * 2 + absmask.astype(int) * 4) statistics = [] for bin in range(bin_count + (0 if wants_scaled else 1)): bin_mask = (good_mask & (bin_indexes == bin)) bin_pixels = np.sum(bin_mask) bin_labels = labels[bin_mask] bin_radial_index = radial_index[bin_indexes[good_mask] == bin] labels_and_radii = (bin_labels - 1, bin_radial_index) radial_values = coo_matrix((pixel_data[bin_mask], labels_and_radii), (nobjects, 8)).toarray() pixel_count = coo_matrix((np.ones(bin_pixels), labels_and_radii), (nobjects, 8)).toarray() mask = pixel_count == 0 radial_means = masked_array(radial_values / pixel_count, mask) radial_cv = np.std(radial_means, 1) / np.mean(radial_means, 1) radial_cv[np.sum(~mask, 1) == 0] = 0 for measurement, feature, overflow_feature in ( (fraction_at_distance[:, bin], MF_FRAC_AT_D, OF_FRAC_AT_D), (mean_pixel_fraction[:, bin], MF_MEAN_FRAC, OF_MEAN_FRAC), (np.array(radial_cv), MF_RADIAL_CV, OF_RADIAL_CV)): if bin == bin_count: measurement_name = overflow_feature % image_name else: measurement_name = feature % (image_name, bin + 1, bin_count) measurements.add_measurement(object_name, measurement_name, measurement) if feature in heatmaps: heatmaps[feature][bin_mask] = measurement[bin_labels - 1] radial_cv.mask = np.sum(~mask, 1) == 0 bin_name = str(bin + 1) if bin < bin_count else "Overflow" statistics += [(image_name, object_name, bin_name, str(bin_count), round(np.mean(masked_fraction_at_distance[:, bin]), 4), round(np.mean(masked_mean_pixel_fraction[:, bin]), 4), round(np.mean(radial_cv), 4))] return statistics
def run(self, workspace): if self.show_window: workspace.display_data.col_labels = ("Image", "Object", "Feature", "Mean", "Median", "STD") workspace.display_data.statistics = statistics = [] for image_name in [img.name for img in self.images]: image = workspace.image_set.get_image(image_name.value, must_be_grayscale=True) for object_name in [obj.name for obj in self.objects]: # Need to refresh image after each iteration... img = image.pixel_data if image.has_mask: masked_image = img.copy() masked_image[~image.mask] = 0 else: masked_image = img objects = workspace.object_set.get_objects(object_name.value) nobjects = objects.count integrated_intensity = np.zeros((nobjects,)) integrated_intensity_edge = np.zeros((nobjects,)) mean_intensity = np.zeros((nobjects,)) mean_intensity_edge = np.zeros((nobjects,)) std_intensity = np.zeros((nobjects,)) std_intensity_edge = np.zeros((nobjects,)) min_intensity = np.zeros((nobjects,)) min_intensity_edge = np.zeros((nobjects,)) max_intensity = np.zeros((nobjects,)) max_intensity_edge = np.zeros((nobjects,)) mass_displacement = np.zeros((nobjects,)) lower_quartile_intensity = np.zeros((nobjects,)) median_intensity = np.zeros((nobjects,)) mad_intensity = np.zeros((nobjects,)) upper_quartile_intensity = np.zeros((nobjects,)) cmi_x = np.zeros((nobjects,)) cmi_y = np.zeros((nobjects,)) max_x = np.zeros((nobjects,)) max_y = np.zeros((nobjects,)) for labels, lindexes in objects.get_labels(): lindexes = lindexes[lindexes != 0] labels, img = cpo.crop_labels_and_image(labels, img) _, masked_image = cpo.crop_labels_and_image(labels, masked_image) outlines = cpmo.outline(labels) if image.has_mask: _, mask = cpo.crop_labels_and_image(labels, image.mask) masked_labels = labels.copy() masked_labels[~mask] = 0 masked_outlines = outlines.copy() masked_outlines[~mask] = 0 else: masked_labels = labels masked_outlines = outlines lmask = masked_labels > 0 & np.isfinite(img) # Ignore NaNs, Infs has_objects = np.any(lmask) if has_objects: limg = img[lmask] llabels = labels[lmask] mesh_y, mesh_x = np.mgrid[0 : masked_image.shape[0], 0 : masked_image.shape[1]] mesh_x = mesh_x[lmask] mesh_y = mesh_y[lmask] lcount = fix(nd.sum(np.ones(len(limg)), llabels, lindexes)) integrated_intensity[lindexes - 1] = fix(nd.sum(limg, llabels, lindexes)) mean_intensity[lindexes - 1] = integrated_intensity[lindexes - 1] / lcount std_intensity[lindexes - 1] = np.sqrt( fix(nd.mean((limg - mean_intensity[llabels - 1]) ** 2, llabels, lindexes)) ) min_intensity[lindexes - 1] = fix(nd.minimum(limg, llabels, lindexes)) max_intensity[lindexes - 1] = fix(nd.maximum(limg, llabels, lindexes)) # Compute the position of the intensity maximum max_position = np.array(fix(nd.maximum_position(limg, llabels, lindexes)), dtype=int) max_position = np.reshape(max_position, (max_position.shape[0],)) max_x[lindexes - 1] = mesh_x[max_position] max_y[lindexes - 1] = mesh_y[max_position] # The mass displacement is the distance between the center # of mass of the binary image and of the intensity image. The # center of mass is the average X or Y for the binary image # and the sum of X or Y * intensity / integrated intensity cm_x = fix(nd.mean(mesh_x, llabels, lindexes)) cm_y = fix(nd.mean(mesh_y, llabels, lindexes)) i_x = fix(nd.sum(mesh_x * limg, llabels, lindexes)) i_y = fix(nd.sum(mesh_y * limg, llabels, lindexes)) cmi_x[lindexes - 1] = i_x / integrated_intensity[lindexes - 1] cmi_y[lindexes - 1] = i_y / integrated_intensity[lindexes - 1] diff_x = cm_x - cmi_x[lindexes - 1] diff_y = cm_y - cmi_y[lindexes - 1] mass_displacement[lindexes - 1] = np.sqrt(diff_x * diff_x + diff_y * diff_y) # # Sort the intensities by label, then intensity. # For each label, find the index above and below # the 25%, 50% and 75% mark and take the weighted # average. # order = np.lexsort((limg, llabels)) areas = lcount.astype(int) indices = np.cumsum(areas) - areas for dest, fraction in ( (lower_quartile_intensity, 1.0 / 4.0), (median_intensity, 1.0 / 2.0), (upper_quartile_intensity, 3.0 / 4.0), ): qindex = indices.astype(float) + areas * fraction qfraction = qindex - np.floor(qindex) qindex = qindex.astype(int) qmask = qindex < indices + areas - 1 qi = qindex[qmask] qf = qfraction[qmask] dest[lindexes[qmask] - 1] = limg[order[qi]] * (1 - qf) + limg[order[qi + 1]] * qf # # In some situations (e.g. only 3 points), there may # not be an upper bound. # qmask = (~qmask) & (areas > 0) dest[lindexes[qmask] - 1] = limg[order[qindex[qmask]]] # # Once again, for the MAD # madimg = np.abs(limg - median_intensity[llabels - 1]) order = np.lexsort((madimg, llabels)) qindex = indices.astype(float) + areas / 2.0 qfraction = qindex - np.floor(qindex) qindex = qindex.astype(int) qmask = qindex < indices + areas - 1 qi = qindex[qmask] qf = qfraction[qmask] mad_intensity[lindexes[qmask] - 1] = madimg[order[qi]] * (1 - qf) + madimg[order[qi + 1]] * qf qmask = (~qmask) & (areas > 0) mad_intensity[lindexes[qmask] - 1] = madimg[order[qindex[qmask]]] emask = masked_outlines > 0 eimg = img[emask] elabels = labels[emask] has_edge = len(eimg) > 0 if has_edge: ecount = fix(nd.sum(np.ones(len(eimg)), elabels, lindexes)) integrated_intensity_edge[lindexes - 1] = fix(nd.sum(eimg, elabels, lindexes)) mean_intensity_edge[lindexes - 1] = integrated_intensity_edge[lindexes - 1] / ecount std_intensity_edge[lindexes - 1] = np.sqrt( fix(nd.mean((eimg - mean_intensity_edge[elabels - 1]) ** 2, elabels, lindexes)) ) min_intensity_edge[lindexes - 1] = fix(nd.minimum(eimg, elabels, lindexes)) max_intensity_edge[lindexes - 1] = fix(nd.maximum(eimg, elabels, lindexes)) m = workspace.measurements for category, feature_name, measurement in ( (INTENSITY, INTEGRATED_INTENSITY, integrated_intensity), (INTENSITY, MEAN_INTENSITY, mean_intensity), (INTENSITY, STD_INTENSITY, std_intensity), (INTENSITY, MIN_INTENSITY, min_intensity), (INTENSITY, MAX_INTENSITY, max_intensity), (INTENSITY, INTEGRATED_INTENSITY_EDGE, integrated_intensity_edge), (INTENSITY, MEAN_INTENSITY_EDGE, mean_intensity_edge), (INTENSITY, STD_INTENSITY_EDGE, std_intensity_edge), (INTENSITY, MIN_INTENSITY_EDGE, min_intensity_edge), (INTENSITY, MAX_INTENSITY_EDGE, max_intensity_edge), (INTENSITY, MASS_DISPLACEMENT, mass_displacement), (INTENSITY, LOWER_QUARTILE_INTENSITY, lower_quartile_intensity), (INTENSITY, MEDIAN_INTENSITY, median_intensity), (INTENSITY, MAD_INTENSITY, mad_intensity), (INTENSITY, UPPER_QUARTILE_INTENSITY, upper_quartile_intensity), (C_LOCATION, LOC_CMI_X, cmi_x), (C_LOCATION, LOC_CMI_Y, cmi_y), (C_LOCATION, LOC_MAX_X, max_x), (C_LOCATION, LOC_MAX_Y, max_y), ): measurement_name = "%s_%s_%s" % (category, feature_name, image_name.value) m.add_measurement(object_name.value, measurement_name, measurement) if self.show_window and len(measurement) > 0: statistics.append( ( image_name.value, object_name.value, feature_name, np.round(np.mean(measurement), 3), np.round(np.median(measurement), 3), np.round(np.std(measurement), 3), ) )
def run(self, workspace): if self.show_window: workspace.display_data.col_labels = ( "Image", "Object", "Feature", "Mean", "Median", "STD") workspace.display_data.statistics = statistics = [] for image_name in [img.name for img in self.images]: image = workspace.image_set.get_image(image_name.value, must_be_grayscale=True) for object_name in [obj.name for obj in self.objects]: # Need to refresh image after each iteration... img = image.pixel_data if image.has_mask: masked_image = img.copy() masked_image[~image.mask] = 0 else: masked_image = img objects = workspace.object_set.get_objects(object_name.value) nobjects = objects.count integrated_intensity = np.zeros((nobjects,)) integrated_intensity_edge = np.zeros((nobjects,)) mean_intensity = np.zeros((nobjects,)) mean_intensity_edge = np.zeros((nobjects,)) std_intensity = np.zeros((nobjects,)) std_intensity_edge = np.zeros((nobjects,)) min_intensity = np.zeros((nobjects,)) min_intensity_edge = np.zeros((nobjects,)) max_intensity = np.zeros((nobjects,)) max_intensity_edge = np.zeros((nobjects,)) mass_displacement = np.zeros((nobjects,)) lower_quartile_intensity = np.zeros((nobjects,)) median_intensity = np.zeros((nobjects,)) mad_intensity = np.zeros((nobjects,)) upper_quartile_intensity = np.zeros((nobjects,)) cmi_x = np.zeros((nobjects,)) cmi_y = np.zeros((nobjects,)) max_x = np.zeros((nobjects,)) max_y = np.zeros((nobjects,)) for labels, lindexes in objects.get_labels(): lindexes = lindexes[lindexes != 0] labels, img = cpo.crop_labels_and_image(labels, img) _, masked_image = cpo.crop_labels_and_image(labels, masked_image) outlines = cpmo.outline(labels) if image.has_mask: _, mask = cpo.crop_labels_and_image(labels, image.mask) masked_labels = labels.copy() masked_labels[~mask] = 0 masked_outlines = outlines.copy() masked_outlines[~mask] = 0 else: masked_labels = labels masked_outlines = outlines lmask = masked_labels > 0 & np.isfinite(img) # Ignore NaNs, Infs has_objects = np.any(lmask) if has_objects: limg = img[lmask] llabels = labels[lmask] mesh_y, mesh_x = np.mgrid[0:masked_image.shape[0], 0:masked_image.shape[1]] mesh_x = mesh_x[lmask] mesh_y = mesh_y[lmask] lcount = fix(nd.sum(np.ones(len(limg)), llabels, lindexes)) integrated_intensity[lindexes - 1] = \ fix(nd.sum(limg, llabels, lindexes)) mean_intensity[lindexes - 1] = \ integrated_intensity[lindexes - 1] / lcount std_intensity[lindexes - 1] = np.sqrt( fix(nd.mean((limg - mean_intensity[llabels - 1]) ** 2, llabels, lindexes))) min_intensity[lindexes - 1] = fix(nd.minimum(limg, llabels, lindexes)) max_intensity[lindexes - 1] = fix( nd.maximum(limg, llabels, lindexes)) # Compute the position of the intensity maximum max_position = np.array(fix(nd.maximum_position(limg, llabels, lindexes)), dtype=int) max_position = np.reshape(max_position, (max_position.shape[0],)) max_x[lindexes - 1] = mesh_x[max_position] max_y[lindexes - 1] = mesh_y[max_position] # The mass displacement is the distance between the center # of mass of the binary image and of the intensity image. The # center of mass is the average X or Y for the binary image # and the sum of X or Y * intensity / integrated intensity cm_x = fix(nd.mean(mesh_x, llabels, lindexes)) cm_y = fix(nd.mean(mesh_y, llabels, lindexes)) i_x = fix(nd.sum(mesh_x * limg, llabels, lindexes)) i_y = fix(nd.sum(mesh_y * limg, llabels, lindexes)) cmi_x[lindexes - 1] = i_x / integrated_intensity[lindexes - 1] cmi_y[lindexes - 1] = i_y / integrated_intensity[lindexes - 1] diff_x = cm_x - cmi_x[lindexes - 1] diff_y = cm_y - cmi_y[lindexes - 1] mass_displacement[lindexes - 1] = \ np.sqrt(diff_x * diff_x + diff_y * diff_y) # # Sort the intensities by label, then intensity. # For each label, find the index above and below # the 25%, 50% and 75% mark and take the weighted # average. # order = np.lexsort((limg, llabels)) areas = lcount.astype(int) indices = np.cumsum(areas) - areas for dest, fraction in ( (lower_quartile_intensity, 1.0 / 4.0), (median_intensity, 1.0 / 2.0), (upper_quartile_intensity, 3.0 / 4.0)): qindex = indices.astype(float) + areas * fraction qfraction = qindex - np.floor(qindex) qindex = qindex.astype(int) qmask = qindex < indices + areas - 1 qi = qindex[qmask] qf = qfraction[qmask] dest[lindexes[qmask] - 1] = ( limg[order[qi]] * (1 - qf) + limg[order[qi + 1]] * qf) # # In some situations (e.g. only 3 points), there may # not be an upper bound. # qmask = (~qmask) & (areas > 0) dest[lindexes[qmask] - 1] = limg[order[qindex[qmask]]] # # Once again, for the MAD # madimg = np.abs(limg - median_intensity[llabels - 1]) order = np.lexsort((madimg, llabels)) qindex = indices.astype(float) + areas / 2.0 qfraction = qindex - np.floor(qindex) qindex = qindex.astype(int) qmask = qindex < indices + areas - 1 qi = qindex[qmask] qf = qfraction[qmask] mad_intensity[lindexes[qmask] - 1] = ( madimg[order[qi]] * (1 - qf) + madimg[order[qi + 1]] * qf) qmask = (~qmask) & (areas > 0) mad_intensity[lindexes[qmask] - 1] = madimg[order[qindex[qmask]]] emask = masked_outlines > 0 eimg = img[emask] elabels = labels[emask] has_edge = len(eimg) > 0 if has_edge: ecount = fix(nd.sum( np.ones(len(eimg)), elabels, lindexes)) integrated_intensity_edge[lindexes - 1] = \ fix(nd.sum(eimg, elabels, lindexes)) mean_intensity_edge[lindexes - 1] = \ integrated_intensity_edge[lindexes - 1] / ecount std_intensity_edge[lindexes - 1] = \ np.sqrt(fix(nd.mean( (eimg - mean_intensity_edge[elabels - 1]) ** 2, elabels, lindexes))) min_intensity_edge[lindexes - 1] = fix( nd.minimum(eimg, elabels, lindexes)) max_intensity_edge[lindexes - 1] = fix( nd.maximum(eimg, elabels, lindexes)) m = workspace.measurements for category, feature_name, measurement in \ ((INTENSITY, INTEGRATED_INTENSITY, integrated_intensity), (INTENSITY, MEAN_INTENSITY, mean_intensity), (INTENSITY, STD_INTENSITY, std_intensity), (INTENSITY, MIN_INTENSITY, min_intensity), (INTENSITY, MAX_INTENSITY, max_intensity), (INTENSITY, INTEGRATED_INTENSITY_EDGE, integrated_intensity_edge), (INTENSITY, MEAN_INTENSITY_EDGE, mean_intensity_edge), (INTENSITY, STD_INTENSITY_EDGE, std_intensity_edge), (INTENSITY, MIN_INTENSITY_EDGE, min_intensity_edge), (INTENSITY, MAX_INTENSITY_EDGE, max_intensity_edge), (INTENSITY, MASS_DISPLACEMENT, mass_displacement), (INTENSITY, LOWER_QUARTILE_INTENSITY, lower_quartile_intensity), (INTENSITY, MEDIAN_INTENSITY, median_intensity), (INTENSITY, MAD_INTENSITY, mad_intensity), (INTENSITY, UPPER_QUARTILE_INTENSITY, upper_quartile_intensity), (C_LOCATION, LOC_CMI_X, cmi_x), (C_LOCATION, LOC_CMI_Y, cmi_y), (C_LOCATION, LOC_MAX_X, max_x), (C_LOCATION, LOC_MAX_Y, max_y)): measurement_name = "%s_%s_%s" % (category, feature_name, image_name.value) m.add_measurement(object_name.value, measurement_name, measurement) if self.show_window and len(measurement) > 0: statistics.append((image_name.value, object_name.value, feature_name, np.round(np.mean(measurement), 3), np.round(np.median(measurement), 3), np.round(np.std(measurement), 3)))