コード例 #1
0
 def test_01_02_larger_secondary(self):
     secondary, mask = cpo.size_similarly(np.zeros((10,20)), 
                                          np.zeros((10,30)))
     self.assertEqual(tuple(secondary.shape), (10,20))
     self.assertTrue(np.all(mask))
     secondary, mask = cpo.size_similarly(np.zeros((10,20)), 
                                          np.zeros((20,20)))
     self.assertEqual(tuple(secondary.shape), (10,20))
     self.assertTrue(np.all(mask))
コード例 #2
0
ファイル: test_objects.py プロジェクト: erexhepa/CellProfiler
 def test_01_02_larger_secondary(self):
     secondary, mask = cpo.size_similarly(np.zeros((10, 20)),
                                          np.zeros((10, 30)))
     self.assertEqual(tuple(secondary.shape), (10, 20))
     self.assertTrue(np.all(mask))
     secondary, mask = cpo.size_similarly(np.zeros((10, 20)),
                                          np.zeros((20, 20)))
     self.assertEqual(tuple(secondary.shape), (10, 20))
     self.assertTrue(np.all(mask))
コード例 #3
0
 def test_01_04_size_color(self):
     secondary, mask = cpo.size_similarly(np.zeros((10,20), int), 
                                          np.zeros((10,15,3), np.float32))
     self.assertEqual(tuple(secondary.shape), (10,20,3))
     self.assertTrue(np.all(mask[:10,:15]))
     self.assertTrue(np.all(~mask[:10,15:]))
     self.assertEqual(secondary.dtype, np.dtype(np.float32))
コード例 #4
0
ファイル: test_objects.py プロジェクト: erexhepa/CellProfiler
 def test_01_04_size_color(self):
     secondary, mask = cpo.size_similarly(np.zeros((10, 20), int),
                                          np.zeros((10, 15, 3), np.float32))
     self.assertEqual(tuple(secondary.shape), (10, 20, 3))
     self.assertTrue(np.all(mask[:10, :15]))
     self.assertTrue(np.all(~mask[:10, 15:]))
     self.assertEqual(secondary.dtype, np.dtype(np.float32))
コード例 #5
0
 def run_one(self, image_name, object_name, scale, workspace):
     """Run, computing the area measurements for a single map of objects"""
     statistics = []
     image = workspace.image_set.get_image(image_name,
                                           must_be_grayscale=True)
     objects = workspace.get_objects(object_name)
     pixel_data = image.pixel_data
     if image.has_mask:
         mask = image.mask
     else:
         mask = None
     labels = objects.segmented
     try:
         pixel_data = objects.crop_image_similarly(pixel_data)
     except ValueError:
         #
         # Recover by cropping the image to the labels
         #
         pixel_data, m1 = cpo.size_similarly(labels, pixel_data)
         if np.any(~m1):
             if mask is None:
                 mask = m1
             else:
                 mask, m2 = cpo.size_similarly(labels, mask)
                 mask[~m2] = False
         
     if np.all(labels == 0):
         for name in F_HARALICK:
             statistics += self.record_measurement(workspace, 
                                                   image_name, 
                                                   object_name, 
                                                   scale,
                                                   name, 
                                                   np.zeros((0,)))
     else:
         for name, value in zip(F_HARALICK, Haralick(pixel_data,
                                                     labels,
                                                     scale,
                                                     mask=mask).all()):
             statistics += self.record_measurement(workspace, 
                                                   image_name, 
                                                   object_name, 
                                                   scale,
                                                   name, 
                                                   value)
     return statistics
コード例 #6
0
 def run_one_gabor(self, image_name, object_name, scale, workspace):
     objects = workspace.get_objects(object_name)
     labels = objects.segmented
     object_count = np.max(labels)
     if object_count > 0:
         image = workspace.image_set.get_image(image_name,
                                               must_be_grayscale=True)
         pixel_data = image.pixel_data
         labels = objects.segmented
         if image.has_mask:
             mask = image.mask
         else:
             mask = None
         try:
             pixel_data = objects.crop_image_similarly(pixel_data)
             if mask is not None:
                 mask = objects.crop_image_similarly(mask)
                 labels[~mask] = 0
         except ValueError:
             pixel_data, m1 = cpo.size_similarly(labels, pixel_data)
             labels[~m1] = 0
             if mask is not None:
                 mask, m2 = cpo.size_similarly(labels, mask)
                 labels[~m2] = 0
                 labels[~mask] = 0
         pixel_data = normalized_per_object(pixel_data, labels)
         best_score = np.zeros((object_count,))
         for angle in range(self.gabor_angles.value):
             theta = np.pi * angle / self.gabor_angles.value
             g = gabor(pixel_data, labels, scale, theta)
             score_r = fix(scind.sum(g.real, labels,
                                      np.arange(object_count, dtype=np.int32)+ 1))
             score_i = fix(scind.sum(g.imag, labels,
                                      np.arange(object_count, dtype=np.int32)+ 1))
             score = np.sqrt(score_r**2+score_i**2)
             best_score = np.maximum(best_score, score)
     else:
         best_score = np.zeros((0,))
     statistics = self.record_measurement(workspace, 
                                          image_name, 
                                          object_name, 
                                          scale,
                                          F_GABOR, 
                                          best_score)
     return statistics
コード例 #7
0
    def run_object(self, image_name, object_name, bins, workspace):
        """Run, computing the area measurements for a single map of objects"""
        statistics = []
        image = workspace.image_set.get_image(image_name,
                                              must_be_grayscale=True)
        objects = workspace.get_objects(object_name)
        pixel_data = image.pixel_data
        if image.has_mask:
            mask = image.mask
        else:
            mask = None
        labels = objects.segmented
        try:
            pixel_data = objects.crop_image_similarly(pixel_data)
        except ValueError:
            #
            # Recover by cropping the image to the labels
            #
            pixel_data, m1 = cpo.size_similarly(labels, pixel_data)
            if np.any(~m1):
                if mask is None:
                    mask = m1
                else:
                    mask, m2 = cpo.size_similarly(labels, mask)
                    mask[~m2] = False

        if mask is not None:
            labels = labels.copy()
            labels[~mask] = 0

        hist = get_objects_histogram(pixel_data, labels, bins)
        if np.all(labels == 0):
            for b in range(0, bins):
                statistics += self.record_measurement(
                    workspace, image_name, object_name,
                    str(bins) + BINS + str(b), np.zeros((0, )))
        else:
            for b in range(0, bins):
                value = hist[:, b]
                statistics += self.record_measurement(
                    workspace, image_name, object_name,
                    str(bins) + BINS + str(b), value)

        return statistics
コード例 #8
0
 def run_one_gabor(self, image_name, object_name, scale, workspace):
     objects = workspace.get_objects(object_name)
     labels = objects.segmented
     object_count = np.max(labels)
     if object_count > 0:
         image = workspace.image_set.get_image(image_name,
                                               must_be_grayscale=True)
         pixel_data = image.pixel_data
         labels = objects.segmented
         if image.has_mask:
             mask = image.mask
         else:
             mask = None
         try:
             pixel_data = objects.crop_image_similarly(pixel_data)
             if mask is not None:
                 mask = objects.crop_image_similarly(mask)
                 labels[~mask] = 0
         except ValueError:
             pixel_data, m1 = cpo.size_similarly(labels, pixel_data)
             labels[~m1] = 0
             if mask is not None:
                 mask, m2 = cpo.size_similarly(labels, mask)
                 labels[~m2] = 0
                 labels[~mask] = 0
         pixel_data = normalized_per_object(pixel_data, labels)
         best_score = np.zeros((object_count, ))
         for angle in range(self.gabor_angles.value):
             theta = np.pi * angle / self.gabor_angles.value
             g = gabor(pixel_data, labels, scale, theta)
             score_r = fix(
                 scind.sum(g.real, labels,
                           np.arange(object_count, dtype=np.int32) + 1))
             score_i = fix(
                 scind.sum(g.imag, labels,
                           np.arange(object_count, dtype=np.int32) + 1))
             score = np.sqrt(score_r**2 + score_i**2)
             best_score = np.maximum(best_score, score)
     else:
         best_score = np.zeros((0, ))
     statistics = self.record_measurement(workspace, image_name,
                                          object_name, scale, F_GABOR,
                                          best_score)
     return statistics
コード例 #9
0
    def run_object(self, image_name, object_name, bins, workspace):
        """Run, computing the area measurements for a single map of objects"""
        statistics = []
        image = workspace.image_set.get_image(image_name,
                                              must_be_grayscale=True)
        objects = workspace.get_objects(object_name)
        pixel_data = image.pixel_data
        if image.has_mask:
            mask = image.mask
        else:
            mask = None
        labels = objects.segmented
        try:
            pixel_data = objects.crop_image_similarly(pixel_data)
        except ValueError:
            #
            # Recover by cropping the image to the labels
            #
            pixel_data, m1 = cpo.size_similarly(labels, pixel_data)
            if np.any(~m1):
                if mask is None:
                    mask = m1
                else:
                    mask, m2 = cpo.size_similarly(labels, mask)
                    mask[~m2] = False
        
        if mask is not None:
            labels = labels.copy()
            labels[~mask] = 0    

        hist = get_objects_histogram(pixel_data, labels, bins)
        if np.all(labels == 0):
            for b in range(0,bins):
                statistics += self.record_measurement(
                    workspace, image_name, object_name, 
                    str(bins) + BINS + str(b), np.zeros((0,)))
        else:
            for b in range(0,bins):
                value=hist[:,b]  
                statistics += self.record_measurement(
                    workspace, image_name, object_name, 
                    str(bins) + BINS + str(b), value)
            
        return statistics           
コード例 #10
0
    def run_one(self, image_name, object_name, scale, angle, workspace):
        """Run, computing the area measurements for a single map of objects"""
        statistics = []
        image = workspace.image_set.get_image(image_name,
                                              must_be_grayscale=True)
        objects = workspace.get_objects(object_name)
        pixel_data = image.pixel_data
        if image.has_mask:
            mask = image.mask
        else:
            mask = None
        labels = objects.segmented
        try:
            pixel_data = objects.crop_image_similarly(pixel_data)
        except ValueError:
            #
            # Recover by cropping the image to the labels
            #
            pixel_data, m1 = cpo.size_similarly(labels, pixel_data)
            if np.any(~m1):
                if mask is None:
                    mask = m1
                else:
                    mask, m2 = cpo.size_similarly(labels, mask)
                    mask[~m2] = False

        if np.all(labels == 0):
            for name in F_HARALICK:
                statistics += self.record_measurement(
                    workspace, image_name, object_name,
                    str(scale) + "_" + H_TO_A[angle], name, np.zeros((0, )))
        else:
            scale_i, scale_j = self.get_angle_ij(angle, scale)

            for name, value in zip(
                    F_HARALICK,
                    Haralick(pixel_data, labels, scale_i, scale_j,
                             mask=mask).all()):
                statistics += self.record_measurement(
                    workspace, image_name, object_name,
                    str(scale) + "_" + H_TO_A[angle], name, value)
        return statistics
コード例 #11
0
        def display():
            if len(orig_axes.images) > 0:
                # Save zoom and scale if coming through here a second time
                x0, x1 = orig_axes.get_xlim()
                y0, y1 = orig_axes.get_ylim()
                set_lim = True
            else:
                set_lim = False
            for axes, labels, title in ((orig_axes, orig_labels,
                                         "Original: %s" % orig_objects_name),
                                        (keep_axes, orig_labels * mask,
                                         "Objects to keep"),
                                        (remove_axes, orig_labels * (~mask),
                                         "Objects to remove")):

                assert isinstance(axes, matplotlib.axes.Axes)
                labels = renumber_labels_for_display(labels)
                axes.clear()
                if np.all(labels == 0):
                    use_cm = matplotlib.cm.gray
                    is_blank = True
                else:
                    use_cm = cm
                    is_blank = False
                if wants_image_display[0]:
                    outlines = outline(labels)
                    image = workspace.image_set.get_image(
                        self.image_name.value)
                    image = image.pixel_data.astype(np.float)
                    image, _ = cpo.size_similarly(labels, image)
                    if image.ndim == 2:
                        image = np.dstack((image, image, image))
                    if not is_blank:
                        mappable = matplotlib.cm.ScalarMappable(cmap=use_cm)
                        mappable.set_clim(1, labels.max())
                        limage = mappable.to_rgba(labels)[:, :, :3]
                        image[outlines != 0, :] = limage[outlines != 0, :]
                    axes.imshow(image)

                else:
                    axes.imshow(labels, cmap=use_cm)
                axes.set_title(title,
                               fontname=cpprefs.get_title_font_name(),
                               fontsize=cpprefs.get_title_font_size())
            if set_lim:
                orig_axes.set_xlim((x0, x1))
                orig_axes.set_ylim((y0, y1))
            figure.canvas.draw()
            panel.Refresh()
コード例 #12
0
 def run_object(self, image_name, object_name, workspace):
     statistics = []
     input_image = workspace.image_set.get_image(image_name,
                                                 must_be_grayscale = True)            
     objects = workspace.get_objects(object_name)  
     pixels = input_image.pixel_data
     if input_image.has_mask:
         mask = input_image.mask
     else:
         mask = None
     labels = objects.segmented
     try:
         pixels = objects.crop_image_similarly(pixels)
     except ValueError:
         #
         # Recover by cropping the image to the labels
         #
         pixels, m1 = cpo.size_similarly(labels, pixels)
         if np.any(~m1):
             if mask is None:
                 mask = m1
             else:
                 mask, m2 = cpo.size_similarly(labels, mask)
                 mask[~m2] = False
     
     if mask is not None:
         labels = labels.copy()
         labels[~mask] = 0   
         
     for name in self.moms.value.split(','):
         fn=MOM_TO_F[name]
         value=get_object_moment(pixels, fn)
         statistics+=self.record_measurement(workspace,
                                             image_name, object_name,
                                             name, value)        
     return statistics
コード例 #13
0
    def filter_labels(self, labels_out, objects, workspace):
        """Filter labels out of the output
        
        Filter labels that are not in the segmented input labels. Optionally
        filter labels that are touching the edge.
        
        labels_out - the unfiltered output labels
        objects    - the objects thing, containing both segmented and 
                     small_removed labels
        """
        segmented_labels = objects.segmented
        max_out = np.max(labels_out)
        if max_out > 0:
            segmented_labels, m1 = cpo.size_similarly(labels_out, segmented_labels)
            segmented_labels[~m1] = 0
            lookup = scind.maximum(segmented_labels, labels_out, range(max_out + 1))
            lookup = np.array(lookup, int)
            lookup[0] = 0
            segmented_labels_out = lookup[labels_out]
        else:
            segmented_labels_out = labels_out.copy()
        if self.wants_discard_edge:
            image = workspace.image_set.get_image(self.image_name.value)
            if image.has_mask:
                mask_border = image.mask & ~scind.binary_erosion(image.mask)
                edge_labels = segmented_labels_out[mask_border]
            else:
                edge_labels = np.hstack(
                    (
                        segmented_labels_out[0, :],
                        segmented_labels_out[-1, :],
                        segmented_labels_out[:, 0],
                        segmented_labels_out[:, -1],
                    )
                )
            edge_labels = np.unique(edge_labels)
            #
            # Make a lookup table that translates edge labels to zero
            # but translates everything else to itself
            #
            lookup = np.arange(max_out + 1)
            lookup[edge_labels] = 0
            #
            # Run the segmented labels through this to filter out edge
            # labels
            segmented_labels_out = lookup[segmented_labels_out]

        return segmented_labels_out
コード例 #14
0
 def display():
     if len(orig_axes.images) > 0:
         # Save zoom and scale if coming through here a second time
         x0, x1 = orig_axes.get_xlim()
         y0, y1 = orig_axes.get_ylim()
         set_lim = True
     else:
         set_lim = False
     for axes, labels, title in (
         (orig_axes, orig_labels, "Original: %s"%orig_objects_name),
         (keep_axes, orig_labels * mask,"Objects to keep"),
         (remove_axes, orig_labels * (~ mask), "Objects to remove")):
         
         assert isinstance(axes, matplotlib.axes.Axes)
         labels = renumber_labels_for_display(labels)
         axes.clear()
         if np.all(labels == 0):
             use_cm = matplotlib.cm.gray
             is_blank = True
         else:
             use_cm = cm
             is_blank = False
         if wants_image_display[0]:
             outlines = outline(labels)
             image = workspace.image_set.get_image(self.image_name.value)
             image = image.pixel_data.astype(np.float)
             image, _ = cpo.size_similarly(labels, image)
             if image.ndim == 2:
                 image = np.dstack((image, image, image))
             if not is_blank:
                 mappable = matplotlib.cm.ScalarMappable(cmap=use_cm)
                 mappable.set_clim(1,labels.max())
                 limage = mappable.to_rgba(labels)[:,:,:3]
                 image[outlines != 0,:] = limage[outlines != 0, :]
             axes.imshow(image)
             
         else:
             axes.imshow(labels, cmap = use_cm)
         axes.set_title(title,
                        fontname=cpprefs.get_title_font_name(),
                        fontsize=cpprefs.get_title_font_size())
     if set_lim:
         orig_axes.set_xlim((x0, x1))
         orig_axes.set_ylim((y0, y1))
     figure.canvas.draw()
     panel.Refresh()
コード例 #15
0
    def filter_labels(self, labels_out, objects, workspace):
        """Filter labels out of the output
        
        Filter labels that are not in the segmented input labels. Optionally
        filter labels that are touching the edge.
        
        labels_out - the unfiltered output labels
        objects    - the objects thing, containing both segmented and 
                     small_removed labels
        """
        segmented_labels = objects.segmented
        max_out = np.max(labels_out)
        if max_out > 0:
            segmented_labels, m1 = cpo.size_similarly(labels_out,
                                                      segmented_labels)
            segmented_labels[~m1] = 0
            lookup = scind.maximum(segmented_labels, labels_out,
                                   range(max_out + 1))
            lookup = np.array(lookup, int)
            lookup[0] = 0
            segmented_labels_out = lookup[labels_out]
        else:
            segmented_labels_out = labels_out.copy()
        if self.wants_discard_edge:
            image = workspace.image_set.get_image(self.image_name.value)
            if image.has_mask:
                mask_border = (image.mask & ~scind.binary_erosion(image.mask))
                edge_labels = segmented_labels_out[mask_border]
            else:
                edge_labels = np.hstack(
                    (segmented_labels_out[0, :], segmented_labels_out[-1, :],
                     segmented_labels_out[:, 0], segmented_labels_out[:, -1]))
            edge_labels = np.unique(edge_labels)
            #
            # Make a lookup table that translates edge labels to zero
            # but translates everything else to itself
            #
            lookup = np.arange(max(max_out, np.max(segmented_labels)) + 1)
            lookup[edge_labels] = 0
            #
            # Run the segmented labels through this to filter out edge
            # labels
            segmented_labels_out = lookup[segmented_labels_out]

        return segmented_labels_out
コード例 #16
0
    def run_image_pair_objects(self, workspace, first_image_name,
                               second_image_name, object_name):
        '''Calculate per-object correlations between intensities in two images'''
        first_image = workspace.image_set.get_image(first_image_name,
                                                    must_be_grayscale=True)
        second_image = workspace.image_set.get_image(second_image_name,
                                                     must_be_grayscale=True)
        objects = workspace.object_set.get_objects(object_name)
        #
        # Crop both images to the size of the labels matrix
        #
        labels = objects.segmented
        try:
            first_pixels = objects.crop_image_similarly(first_image.pixel_data)
            first_mask = objects.crop_image_similarly(first_image.mask)
        except ValueError:
            first_pixels, m1 = cpo.size_similarly(labels,
                                                  first_image.pixel_data)
            first_mask, m1 = cpo.size_similarly(labels, first_image.mask)
            first_mask[~m1] = False
        try:
            second_pixels = objects.crop_image_similarly(
                second_image.pixel_data)
            second_mask = objects.crop_image_similarly(second_image.mask)
        except ValueError:
            second_pixels, m1 = cpo.size_similarly(labels,
                                                   second_image.pixel_data)
            second_mask, m1 = cpo.size_similarly(labels, second_image.mask)
            second_mask[~m1] = False
        mask = ((labels > 0) & first_mask & second_mask)
        first_pixels = first_pixels[mask]
        second_pixels = second_pixels[mask]
        labels = labels[mask]
        result = []
        first_pixel_data = first_image.pixel_data
        first_mask = first_image.mask
        first_pixel_count = np.product(first_pixel_data.shape)
        second_pixel_data = second_image.pixel_data
        second_mask = second_image.mask
        second_pixel_count = np.product(second_pixel_data.shape)
        #
        # Crop the larger image similarly to the smaller one
        #
        if first_pixel_count < second_pixel_count:
            second_pixel_data = first_image.crop_image_similarly(
                second_pixel_data)
            second_mask = first_image.crop_image_similarly(second_mask)
        elif second_pixel_count < first_pixel_count:
            first_pixel_data = second_image.crop_image_similarly(
                first_pixel_data)
            first_mask = second_image.crop_image_similarly(first_mask)
        mask = (first_mask & second_mask & (~np.isnan(first_pixel_data)) &
                (~np.isnan(second_pixel_data)))
        if np.any(mask):
            #
            # Perform the correlation, which returns:
            # [ [ii, ij],
            #   [ji, jj] ]
            #
            fi = first_pixel_data[mask]
            si = second_pixel_data[mask]

        n_objects = objects.count
        # Handle case when both images for the correlation are completely masked out

        if n_objects == 0:
            corr = np.zeros((0, ))
            overlap = np.zeros((0, ))
            K1 = np.zeros((0, ))
            K2 = np.zeros((0, ))
            M1 = np.zeros((0, ))
            M2 = np.zeros((0, ))
            RWC1 = np.zeros((0, ))
            RWC2 = np.zeros((0, ))
            C1 = np.zeros((0, ))
            C2 = np.zeros((0, ))
        elif np.where(mask)[0].__len__() == 0:
            corr = np.zeros((n_objects, ))
            corr[:] = np.NaN
            overlap = K1 = K2 = M1 = M2 = RWC1 = RWC2 = C1 = C2 = corr
        else:
            #
            # The correlation is sum((x-mean(x))(y-mean(y)) /
            #                         ((n-1) * std(x) *std(y)))
            #
            lrange = np.arange(n_objects, dtype=np.int32) + 1
            area = fix(scind.sum(np.ones_like(labels), labels, lrange))
            mean1 = fix(scind.mean(first_pixels, labels, lrange))
            mean2 = fix(scind.mean(second_pixels, labels, lrange))
            #
            # Calculate the standard deviation times the population.
            #
            std1 = np.sqrt(
                fix(
                    scind.sum((first_pixels - mean1[labels - 1])**2, labels,
                              lrange)))
            std2 = np.sqrt(
                fix(
                    scind.sum((second_pixels - mean2[labels - 1])**2, labels,
                              lrange)))
            x = first_pixels - mean1[labels - 1]  # x - mean(x)
            y = second_pixels - mean2[labels - 1]  # y - mean(y)
            corr = fix(
                scind.sum(x * y / (std1[labels - 1] * std2[labels - 1]),
                          labels, lrange))
            # Explicitly set the correlation to NaN for masked objects
            corr[scind.sum(1, labels, lrange) == 0] = np.NaN
            result += [[
                first_image_name, second_image_name, object_name,
                "Mean Correlation coeff",
                "%.3f" % np.mean(corr)
            ],
                       [
                           first_image_name, second_image_name, object_name,
                           "Median Correlation coeff",
                           "%.3f" % np.median(corr)
                       ],
                       [
                           first_image_name, second_image_name, object_name,
                           "Min Correlation coeff",
                           "%.3f" % np.min(corr)
                       ],
                       [
                           first_image_name, second_image_name, object_name,
                           "Max Correlation coeff",
                           "%.3f" % np.max(corr)
                       ]]

            # Threshold as percentage of maximum intensity of objects in each channel
            tff = (self.thr.value / 100) * fix(
                scind.maximum(first_pixels, labels, lrange))
            tss = (self.thr.value / 100) * fix(
                scind.maximum(second_pixels, labels, lrange))

            combined_thresh = (first_pixels > tff[labels - 1]) & (
                second_pixels > tss[labels - 1])
            fi_thresh = first_pixels[combined_thresh]
            si_thresh = second_pixels[combined_thresh]
            tot_fi_thr = scind.sum(
                first_pixels[first_pixels > tff[labels - 1]],
                labels[first_pixels > tff[labels - 1]], lrange)
            tot_si_thr = scind.sum(
                second_pixels[second_pixels > tss[labels - 1]],
                labels[second_pixels > tss[labels - 1]], lrange)

            nonZero = (fi > 0) | (si > 0)
            xvar = np.var(fi[nonZero], axis=0, ddof=1)
            yvar = np.var(si[nonZero], axis=0, ddof=1)

            xmean = np.mean(fi[nonZero], axis=0)
            ymean = np.mean(si[nonZero], axis=0)

            z = fi[nonZero] + si[nonZero]
            zvar = np.var(z, axis=0, ddof=1)

            covar = 0.5 * (zvar - (xvar + yvar))

            denom = 2 * covar
            num = (yvar - xvar) + np.sqrt((yvar - xvar) * (yvar - xvar) + 4 *
                                          (covar * covar))
            a = (num / denom)
            b = (ymean - a * xmean)

            i = 1
            while i > 0.003921568627:
                thr_fi_c = i
                thr_si_c = (a * i) + b
                combt = (fi < thr_fi_c) | (si < thr_si_c)
                costReg = scistat.pearsonr(fi[combt], si[combt])
                if costReg[0] <= 0:
                    break
                i = i - 0.003921568627

            # Costes' thershold for entire image is applied to each object
            fi_above_thr = first_pixels > thr_fi_c
            si_above_thr = second_pixels > thr_si_c
            combined_thresh_c = fi_above_thr & si_above_thr
            fi_thresh_c = first_pixels[combined_thresh_c]
            si_thresh_c = second_pixels[combined_thresh_c]
            if np.any(fi_above_thr):
                tot_fi_thr_c = scind.sum(first_pixels[first_pixels > thr_fi_c],
                                         labels[first_pixels > thr_fi_c],
                                         lrange)
            else:
                tot_fi_thr_c = np.zeros(len(lrange))
            if np.any(si_above_thr):
                tot_si_thr_c = scind.sum(
                    second_pixels[second_pixels > thr_si_c],
                    labels[second_pixels > thr_si_c], lrange)
            else:
                tot_si_thr_c = np.zeros(len(lrange))

            # Manders Coefficient
            M1 = np.zeros(len(lrange))
            M2 = np.zeros(len(lrange))

            if np.any(combined_thresh):
                M1 = np.array(
                    scind.sum(fi_thresh, labels[combined_thresh],
                              lrange)) / np.array(tot_fi_thr)
                M2 = np.array(
                    scind.sum(si_thresh, labels[combined_thresh],
                              lrange)) / np.array(tot_si_thr)
            result += [[
                first_image_name, second_image_name, object_name,
                "Mean Manders coeff",
                "%.3f" % np.mean(M1)
            ],
                       [
                           first_image_name, second_image_name, object_name,
                           "Median Manders coeff",
                           "%.3f" % np.median(M1)
                       ],
                       [
                           first_image_name, second_image_name, object_name,
                           "Min Manders coeff",
                           "%.3f" % np.min(M1)
                       ],
                       [
                           first_image_name, second_image_name, object_name,
                           "Max Manders coeff",
                           "%.3f" % np.max(M1)
                       ]]
            result += [[
                second_image_name, first_image_name, object_name,
                "Mean Manders coeff",
                "%.3f" % np.mean(M2)
            ],
                       [
                           second_image_name, first_image_name, object_name,
                           "Median Manders coeff",
                           "%.3f" % np.median(M2)
                       ],
                       [
                           second_image_name, first_image_name, object_name,
                           "Min Manders coeff",
                           "%.3f" % np.min(M2)
                       ],
                       [
                           second_image_name, first_image_name, object_name,
                           "Max Manders coeff",
                           "%.3f" % np.max(M2)
                       ]]

            # RWC Coefficient
            RWC1 = np.zeros(len(lrange))
            RWC2 = np.zeros(len(lrange))
            [Rank1] = np.lexsort(([labels], [first_pixels]))
            [Rank2] = np.lexsort(([labels], [second_pixels]))
            Rank1_U = np.hstack(
                [[False], first_pixels[Rank1[:-1]] != first_pixels[Rank1[1:]]])
            Rank2_U = np.hstack(
                [[False],
                 second_pixels[Rank2[:-1]] != second_pixels[Rank2[1:]]])
            Rank1_S = np.cumsum(Rank1_U)
            Rank2_S = np.cumsum(Rank2_U)
            Rank_im1 = np.zeros(first_pixels.shape, dtype=int)
            Rank_im2 = np.zeros(second_pixels.shape, dtype=int)
            Rank_im1[Rank1] = Rank1_S
            Rank_im2[Rank2] = Rank2_S

            R = max(Rank_im1.max(), Rank_im2.max()) + 1
            Di = abs(Rank_im1 - Rank_im2)
            weight = (R - Di) * 1.0 / R
            weight_thresh = weight[combined_thresh]
            if np.any(combined_thresh_c):
                RWC1 = np.array(
                    scind.sum(fi_thresh * weight_thresh,
                              labels[combined_thresh],
                              lrange)) / np.array(tot_fi_thr)
                RWC2 = np.array(
                    scind.sum(si_thresh * weight_thresh,
                              labels[combined_thresh],
                              lrange)) / np.array(tot_si_thr)

            result += [[
                first_image_name, second_image_name, object_name,
                "Mean RWC coeff",
                "%.3f" % np.mean(RWC1)
            ],
                       [
                           first_image_name, second_image_name, object_name,
                           "Median RWC coeff",
                           "%.3f" % np.median(RWC1)
                       ],
                       [
                           first_image_name, second_image_name, object_name,
                           "Min RWC coeff",
                           "%.3f" % np.min(RWC1)
                       ],
                       [
                           first_image_name, second_image_name, object_name,
                           "Max RWC coeff",
                           "%.3f" % np.max(RWC1)
                       ]]
            result += [[
                second_image_name, first_image_name, object_name,
                "Mean RWC coeff",
                "%.3f" % np.mean(RWC2)
            ],
                       [
                           second_image_name, first_image_name, object_name,
                           "Median RWC coeff",
                           "%.3f" % np.median(RWC2)
                       ],
                       [
                           second_image_name, first_image_name, object_name,
                           "Min RWC coeff",
                           "%.3f" % np.min(RWC2)
                       ],
                       [
                           second_image_name, first_image_name, object_name,
                           "Max RWC coeff",
                           "%.3f" % np.max(RWC2)
                       ]]

            # Costes Automated Threshold
            C1 = np.zeros(len(lrange))
            C2 = np.zeros(len(lrange))
            if np.any(combined_thresh_c):
                C1 = np.array(
                    scind.sum(fi_thresh_c, labels[combined_thresh_c],
                              lrange)) / np.array(tot_fi_thr_c)
                C2 = np.array(
                    scind.sum(si_thresh_c, labels[combined_thresh_c],
                              lrange)) / np.array(tot_si_thr_c)
            result += [[
                first_image_name, second_image_name, object_name,
                "Mean Manders coeff (Costes)",
                "%.3f" % np.mean(C1)
            ],
                       [
                           first_image_name, second_image_name, object_name,
                           "Median Manders coeff (Costes)",
                           "%.3f" % np.median(C1)
                       ],
                       [
                           first_image_name, second_image_name, object_name,
                           "Min Manders coeff (Costes)",
                           "%.3f" % np.min(C1)
                       ],
                       [
                           first_image_name, second_image_name, object_name,
                           "Max Manders coeff (Costes)",
                           "%.3f" % np.max(C1)
                       ]]
            result += [[
                second_image_name, first_image_name, object_name,
                "Mean Manders coeff (Costes)",
                "%.3f" % np.mean(C2)
            ],
                       [
                           second_image_name, first_image_name, object_name,
                           "Median Manders coeff (Costes)",
                           "%.3f" % np.median(C2)
                       ],
                       [
                           second_image_name, first_image_name, object_name,
                           "Min Manders coeff (Costes)",
                           "%.3f" % np.min(C2)
                       ],
                       [
                           second_image_name, first_image_name, object_name,
                           "Max Manders coeff (Costes)",
                           "%.3f" % np.max(C2)
                       ]]

            # Overlap Coefficient
            fpsq = scind.sum(first_pixels[combined_thresh]**2,
                             labels[combined_thresh], lrange)
            spsq = scind.sum(second_pixels[combined_thresh]**2,
                             labels[combined_thresh], lrange)
            pdt = np.sqrt(np.array(fpsq) * np.array(spsq))

            if np.any(combined_thresh):
                overlap = fix(
                    scind.sum(
                        first_pixels[combined_thresh] *
                        second_pixels[combined_thresh],
                        labels[combined_thresh], lrange) / pdt)
                K1 = fix((scind.sum(
                    first_pixels[combined_thresh] *
                    second_pixels[combined_thresh], labels[combined_thresh],
                    lrange)) / (np.array(fpsq)))
                K2 = fix(
                    scind.sum(
                        first_pixels[combined_thresh] *
                        second_pixels[combined_thresh],
                        labels[combined_thresh], lrange) / np.array(spsq))
            else:
                overlap = K1 = K2 = np.zeros(len(lrange))
            result += [[
                first_image_name, second_image_name, object_name,
                "Mean Overlap coeff",
                "%.3f" % np.mean(overlap)
            ],
                       [
                           first_image_name, second_image_name, object_name,
                           "Median Overlap coeff",
                           "%.3f" % np.median(overlap)
                       ],
                       [
                           first_image_name, second_image_name, object_name,
                           "Min Overlap coeff",
                           "%.3f" % np.min(overlap)
                       ],
                       [
                           first_image_name, second_image_name, object_name,
                           "Max Overlap coeff",
                           "%.3f" % np.max(overlap)
                       ]]

        measurement = ("Correlation_Correlation_%s_%s" %
                       (first_image_name, second_image_name))
        overlap_measurement = (F_OVERLAP_FORMAT %
                               (first_image_name, second_image_name))
        k_measurement_1 = (F_K_FORMAT % (first_image_name, second_image_name))
        k_measurement_2 = (F_K_FORMAT % (second_image_name, first_image_name))
        manders_measurement_1 = (F_MANDERS_FORMAT %
                                 (first_image_name, second_image_name))
        manders_measurement_2 = (F_MANDERS_FORMAT %
                                 (second_image_name, first_image_name))
        rwc_measurement_1 = (F_RWC_FORMAT %
                             (first_image_name, second_image_name))
        rwc_measurement_2 = (F_RWC_FORMAT %
                             (second_image_name, first_image_name))
        costes_measurement_1 = (F_COSTES_FORMAT %
                                (first_image_name, second_image_name))
        costes_measurement_2 = (F_COSTES_FORMAT %
                                (second_image_name, first_image_name))

        workspace.measurements.add_measurement(object_name, measurement, corr)
        workspace.measurements.add_measurement(object_name,
                                               overlap_measurement, overlap)
        workspace.measurements.add_measurement(object_name, k_measurement_1,
                                               K1)
        workspace.measurements.add_measurement(object_name, k_measurement_2,
                                               K2)
        workspace.measurements.add_measurement(object_name,
                                               manders_measurement_1, M1)
        workspace.measurements.add_measurement(object_name,
                                               manders_measurement_2, M2)
        workspace.measurements.add_measurement(object_name, rwc_measurement_1,
                                               RWC1)
        workspace.measurements.add_measurement(object_name, rwc_measurement_2,
                                               RWC2)
        workspace.measurements.add_measurement(object_name,
                                               costes_measurement_1, C1)
        workspace.measurements.add_measurement(object_name,
                                               costes_measurement_2, C2)

        if n_objects == 0:
            return [[
                first_image_name, second_image_name, object_name,
                "Mean correlation", "-"
            ],
                    [
                        first_image_name, second_image_name, object_name,
                        "Median correlation", "-"
                    ],
                    [
                        first_image_name, second_image_name, object_name,
                        "Min correlation", "-"
                    ],
                    [
                        first_image_name, second_image_name, object_name,
                        "Max correlation", "-"
                    ]]
        else:
            return result
コード例 #17
0
    def run(self, workspace):
        '''Run the module on the image set'''
        seed_objects_name = self.seed_objects_name.value
        skeleton_name = self.image_name.value
        seed_objects = workspace.object_set.get_objects(seed_objects_name)
        labels = seed_objects.segmented
        labels_count = np.max(labels)
        label_range = np.arange(labels_count, dtype=np.int32) + 1

        skeleton_image = workspace.image_set.get_image(skeleton_name,
                                                       must_be_binary=True)
        skeleton = skeleton_image.pixel_data
        if skeleton_image.has_mask:
            skeleton = skeleton & skeleton_image.mask
        try:
            labels = skeleton_image.crop_image_similarly(labels)
        except:
            labels, m1 = cpo.size_similarly(skeleton, labels)
            labels[~m1] = 0
        #
        # The following code makes a ring around the seed objects with
        # the skeleton trunks sticking out of it.
        #
        # Create a new skeleton with holes at the seed objects
        # First combine the seed objects with the skeleton so
        # that the skeleton trunks come out of the seed objects.
        #
        # Erode the labels once so that all of the trunk branchpoints
        # will be within the labels
        #
        #
        # Dilate the objects, then subtract them to make a ring
        #
        my_disk = morph.strel_disk(1.5).astype(int)
        dilated_labels = grey_dilation(labels, footprint=my_disk)
        seed_mask = dilated_labels > 0
        combined_skel = skeleton | seed_mask

        closed_labels = grey_erosion(dilated_labels, footprint=my_disk)
        seed_center = closed_labels > 0
        combined_skel = combined_skel & (~seed_center)
        #
        # Fill in single holes (but not a one-pixel hole made by
        # a one-pixel image)
        #
        if self.wants_to_fill_holes:

            def size_fn(area, is_object):
                return (~is_object) and (area <= self.maximum_hole_size.value)

            combined_skel = morph.fill_labeled_holes(combined_skel,
                                                     ~seed_center, size_fn)
        #
        # Reskeletonize to make true branchpoints at the ring boundaries
        #
        combined_skel = morph.skeletonize(combined_skel)
        #
        # The skeleton outside of the labels
        #
        outside_skel = combined_skel & (dilated_labels == 0)
        #
        # Associate all skeleton points with seed objects
        #
        dlabels, distance_map = propagate.propagate(np.zeros(labels.shape),
                                                    dilated_labels,
                                                    combined_skel, 1)
        #
        # Get rid of any branchpoints not connected to seeds
        #
        combined_skel[dlabels == 0] = False
        #
        # Find the branchpoints
        #
        branch_points = morph.branchpoints(combined_skel)
        #
        # Odd case: when four branches meet like this, branchpoints are not
        # assigned because they are arbitrary. So assign them.
        #
        # .  .
        #  B.
        #  .B
        # .  .
        #
        odd_case = (combined_skel[:-1, :-1] & combined_skel[1:, :-1]
                    & combined_skel[:-1, 1:] & combined_skel[1, 1])
        branch_points[:-1, :-1][odd_case] = True
        branch_points[1:, 1:][odd_case] = True
        #
        # Find the branching counts for the trunks (# of extra branches
        # eminating from a point other than the line it might be on).
        #
        branching_counts = morph.branchings(combined_skel)
        branching_counts = np.array([0, 0, 0, 1, 2])[branching_counts]
        #
        # Only take branches within 1 of the outside skeleton
        #
        dilated_skel = scind.binary_dilation(outside_skel, morph.eight_connect)
        branching_counts[~dilated_skel] = 0
        #
        # Find the endpoints
        #
        end_points = morph.endpoints(combined_skel)
        #
        # We use two ranges for classification here:
        # * anything within one pixel of the dilated image is a trunk
        # * anything outside of that range is a branch
        #
        nearby_labels = dlabels.copy()
        nearby_labels[distance_map > 1.5] = 0

        outside_labels = dlabels.copy()
        outside_labels[nearby_labels > 0] = 0
        #
        # The trunks are the branchpoints that lie within one pixel of
        # the dilated image.
        #
        if labels_count > 0:
            trunk_counts = fix(
                scind.sum(branching_counts, nearby_labels,
                          label_range)).astype(int)
        else:
            trunk_counts = np.zeros((0, ), int)
        #
        # The branches are the branchpoints that lie outside the seed objects
        #
        if labels_count > 0:
            branch_counts = fix(
                scind.sum(branch_points, outside_labels, label_range))
        else:
            branch_counts = np.zeros((0, ), int)
        #
        # Save the endpoints
        #
        if labels_count > 0:
            end_counts = fix(scind.sum(end_points, outside_labels,
                                       label_range))
        else:
            end_counts = np.zeros((0, ), int)
        #
        # Save measurements
        #
        m = workspace.measurements
        assert isinstance(m, cpmeas.Measurements)
        feature = "_".join((C_NEURON, F_NUMBER_TRUNKS, skeleton_name))
        m.add_measurement(seed_objects_name, feature, trunk_counts)
        feature = "_".join(
            (C_NEURON, F_NUMBER_NON_TRUNK_BRANCHES, skeleton_name))
        m.add_measurement(seed_objects_name, feature, branch_counts)
        feature = "_".join((C_NEURON, F_NUMBER_BRANCH_ENDS, skeleton_name))
        m.add_measurement(seed_objects_name, feature, end_counts)
        #
        # Collect the graph information
        #
        if self.wants_neuron_graph:
            trunk_mask = (branching_counts > 0) & (nearby_labels != 0)
            intensity_image = workspace.image_set.get_image(
                self.intensity_image_name.value)
            edge_graph, vertex_graph = self.make_neuron_graph(
                combined_skel, dlabels, trunk_mask,
                branch_points & ~trunk_mask, end_points,
                intensity_image.pixel_data)

            image_number = workspace.measurements.image_set_number

            edge_path, vertex_path = self.get_graph_file_paths(
                m, m.image_number)
            workspace.interaction_request(self,
                                          m.image_number,
                                          edge_path,
                                          edge_graph,
                                          vertex_path,
                                          vertex_graph,
                                          headless_ok=True)

            if self.show_window:
                workspace.display_data.edge_graph = edge_graph
                workspace.display_data.vertex_graph = vertex_graph
                workspace.display_data.intensity_image = intensity_image.pixel_data
        #
        # Make the display image
        #
        if self.show_window or self.wants_branchpoint_image:
            branchpoint_image = np.zeros(
                (skeleton.shape[0], skeleton.shape[1], 3))
            trunk_mask = (branching_counts > 0) & (nearby_labels != 0)
            branch_mask = branch_points & (outside_labels != 0)
            end_mask = end_points & (outside_labels != 0)
            branchpoint_image[outside_skel, :] = 1
            branchpoint_image[trunk_mask | branch_mask | end_mask, :] = 0
            branchpoint_image[trunk_mask, 0] = 1
            branchpoint_image[branch_mask, 1] = 1
            branchpoint_image[end_mask, 2] = 1
            branchpoint_image[dilated_labels != 0, :] *= .875
            branchpoint_image[dilated_labels != 0, :] += .1
            if self.show_window:
                workspace.display_data.branchpoint_image = branchpoint_image
            if self.wants_branchpoint_image:
                bi = cpi.Image(branchpoint_image, parent_image=skeleton_image)
                workspace.image_set.add(self.branchpoint_image_name.value, bi)
コード例 #18
0
    def run(self, workspace):
        '''Run the module on the image set'''
        seed_objects_name = self.seed_objects_name.value
        skeleton_name = self.image_name.value
        seed_objects = workspace.object_set.get_objects(seed_objects_name)
        labels = seed_objects.segmented
        labels_count = np.max(labels)
        label_range = np.arange(labels_count,dtype=np.int32)+1
        
        skeleton_image = workspace.image_set.get_image(
            skeleton_name, must_be_binary = True)
        skeleton = skeleton_image.pixel_data
        if skeleton_image.has_mask:
            skeleton = skeleton & skeleton_image.mask
        try:
            labels = skeleton_image.crop_image_similarly(labels)
        except:
            labels, m1 = cpo.size_similarly(skeleton, labels)
            labels[~m1] = 0
        #
        # The following code makes a ring around the seed objects with
        # the skeleton trunks sticking out of it.
        #
        # Create a new skeleton with holes at the seed objects
        # First combine the seed objects with the skeleton so
        # that the skeleton trunks come out of the seed objects.
        #
        # Erode the labels once so that all of the trunk branchpoints
        # will be within the labels
        #
        #
        # Dilate the objects, then subtract them to make a ring
        #
        my_disk = morph.strel_disk(1.5).astype(int)
        dilated_labels = grey_dilation(labels, footprint=my_disk)
        seed_mask = dilated_labels > 0
        combined_skel = skeleton | seed_mask
        
        closed_labels = grey_erosion(dilated_labels,
                                     footprint = my_disk)
        seed_center = closed_labels > 0
        combined_skel = combined_skel & (~seed_center)
        #
        # Fill in single holes (but not a one-pixel hole made by
        # a one-pixel image)
        #
        if self.wants_to_fill_holes:
            def size_fn(area, is_object):
                return (~ is_object) and (area <= self.maximum_hole_size.value)
            combined_skel = morph.fill_labeled_holes(
                combined_skel, ~seed_center, size_fn)
        #
        # Reskeletonize to make true branchpoints at the ring boundaries
        #
        combined_skel = morph.skeletonize(combined_skel)
        #
        # The skeleton outside of the labels
        #
        outside_skel = combined_skel & (dilated_labels == 0)
        #
        # Associate all skeleton points with seed objects
        #
        dlabels, distance_map = propagate.propagate(np.zeros(labels.shape),
                                                    dilated_labels,
                                                    combined_skel, 1)
        #
        # Get rid of any branchpoints not connected to seeds
        #
        combined_skel[dlabels == 0] = False
        #
        # Find the branchpoints
        #
        branch_points = morph.branchpoints(combined_skel)
        #
        # Odd case: when four branches meet like this, branchpoints are not
        # assigned because they are arbitrary. So assign them.
        #
        # .  .
        #  B.
        #  .B
        # .  .
        #
        odd_case = (combined_skel[:-1,:-1] & combined_skel[1:,:-1] &
                    combined_skel[:-1,1:] & combined_skel[1,1])
        branch_points[:-1,:-1][odd_case] = True
        branch_points[1:,1:][odd_case] = True
        #
        # Find the branching counts for the trunks (# of extra branches
        # eminating from a point other than the line it might be on).
        #
        branching_counts = morph.branchings(combined_skel)
        branching_counts = np.array([0,0,0,1,2])[branching_counts]
        #
        # Only take branches within 1 of the outside skeleton
        #
        dilated_skel = scind.binary_dilation(outside_skel, morph.eight_connect)
        branching_counts[~dilated_skel] = 0
        #
        # Find the endpoints
        #
        end_points = morph.endpoints(combined_skel)
        #
        # We use two ranges for classification here:
        # * anything within one pixel of the dilated image is a trunk
        # * anything outside of that range is a branch
        #
        nearby_labels = dlabels.copy()
        nearby_labels[distance_map > 1.5] = 0
        
        outside_labels = dlabels.copy()
        outside_labels[nearby_labels > 0] = 0
        #
        # The trunks are the branchpoints that lie within one pixel of
        # the dilated image.
        #
        if labels_count > 0:
            trunk_counts = fix(scind.sum(branching_counts, nearby_labels, 
                                         label_range)).astype(int)
        else:
            trunk_counts = np.zeros((0,),int)
        #
        # The branches are the branchpoints that lie outside the seed objects
        #
        if labels_count > 0:
            branch_counts = fix(scind.sum(branch_points, outside_labels, 
                                          label_range))
        else:
            branch_counts = np.zeros((0,),int)
        #
        # Save the endpoints
        #
        if labels_count > 0:
            end_counts = fix(scind.sum(end_points, outside_labels, label_range))
        else:
            end_counts = np.zeros((0,), int)
        #
        # Save measurements
        #
        m = workspace.measurements
        assert isinstance(m, cpmeas.Measurements)
        feature = "_".join((C_NEURON, F_NUMBER_TRUNKS, skeleton_name))
        m.add_measurement(seed_objects_name, feature, trunk_counts)
        feature = "_".join((C_NEURON, F_NUMBER_NON_TRUNK_BRANCHES, 
                            skeleton_name))
        m.add_measurement(seed_objects_name, feature, branch_counts)
        feature = "_".join((C_NEURON, F_NUMBER_BRANCH_ENDS, skeleton_name))
        m.add_measurement(seed_objects_name, feature, end_counts)
        #
        # Collect the graph information
        #
        if self.wants_neuron_graph:
            trunk_mask = (branching_counts > 0) & (nearby_labels != 0)
            intensity_image = workspace.image_set.get_image(
                self.intensity_image_name.value)
            edge_graph, vertex_graph = self.make_neuron_graph(
                combined_skel, dlabels, 
                trunk_mask,
                branch_points & ~trunk_mask,
                end_points,
                intensity_image.pixel_data)

            image_number = workspace.measurements.image_set_number
            
            edge_path, vertex_path = self.get_graph_file_paths(m, m.image_number)
            workspace.interaction_request(
                self, m.image_number, edge_path, edge_graph,
                vertex_path, vertex_graph, headless_ok = True)
            
            if self.show_window:
                workspace.display_data.edge_graph = edge_graph
                workspace.display_data.vertex_graph = vertex_graph
                workspace.display_data.intensity_image = intensity_image.pixel_data
        #
        # Make the display image
        #
        if self.show_window or self.wants_branchpoint_image:
            branchpoint_image = np.zeros((skeleton.shape[0],
                                          skeleton.shape[1],
                                          3))
            trunk_mask = (branching_counts > 0) & (nearby_labels != 0)
            branch_mask = branch_points & (outside_labels != 0)
            end_mask = end_points & (outside_labels != 0)
            branchpoint_image[outside_skel,:] = 1
            branchpoint_image[trunk_mask | branch_mask | end_mask,:] = 0
            branchpoint_image[trunk_mask,0] = 1
            branchpoint_image[branch_mask,1] = 1
            branchpoint_image[end_mask, 2] = 1
            branchpoint_image[dilated_labels != 0,:] *= .875
            branchpoint_image[dilated_labels != 0,:] += .1
            if self.show_window:
                workspace.display_data.branchpoint_image = branchpoint_image
            if self.wants_branchpoint_image:
                bi = cpi.Image(branchpoint_image,
                               parent_image = skeleton_image)
                workspace.image_set.add(self.branchpoint_image_name.value, bi)
コード例 #19
0
 def run_image_pair_objects(self, workspace, first_image_name,
                            second_image_name, object_name):
     '''Calculate per-object correlations between intensities in two images'''
     first_image = workspace.image_set.get_image(first_image_name,
                                                 must_be_grayscale=True)
     second_image = workspace.image_set.get_image(second_image_name,
                                                  must_be_grayscale=True)
     objects = workspace.object_set.get_objects(object_name)
     #
     # Crop both images to the size of the labels matrix
     #
     labels = objects.segmented
     try:
         first_pixels  = objects.crop_image_similarly(first_image.pixel_data)
         first_mask    = objects.crop_image_similarly(first_image.mask)
     except ValueError:
         first_pixels, m1 = cpo.size_similarly(labels, first_image.pixel_data)
         first_mask, m1 = cpo.size_similarly(labels, first_image.mask)
         first_mask[~m1] = False
     try:
         second_pixels = objects.crop_image_similarly(second_image.pixel_data)
         second_mask   = objects.crop_image_similarly(second_image.mask)
     except ValueError:
         second_pixels, m1 = cpo.size_similarly(labels, second_image.pixel_data)
         second_mask, m1 = cpo.size_similarly(labels, second_image.mask)
         second_mask[~m1] = False
     mask   = ((labels > 0) & first_mask & second_mask)
     first_pixels = first_pixels[mask]
     second_pixels = second_pixels[mask]
     labels = labels[mask]
     if len(labels)==0:
         n_objects = 0
     else:
         n_objects = np.max(labels)
     if n_objects == 0:
         corr = np.zeros((0,))
     else:
         #
         # The correlation is sum((x-mean(x))(y-mean(y)) /
         #                         ((n-1) * std(x) *std(y)))
         #
         lrange = np.arange(n_objects,dtype=np.int32)+1
         area  = fix(scind.sum(np.ones_like(labels), labels, lrange))
         mean1 = fix(scind.mean(first_pixels, labels, lrange))
         mean2 = fix(scind.mean(second_pixels, labels, lrange))
         #
         # Calculate the standard deviation times the population.
         #
         std1 = np.sqrt(fix(scind.sum((first_pixels-mean1[labels-1])**2,
                                      labels, lrange)))
         std2 = np.sqrt(fix(scind.sum((second_pixels-mean2[labels-1])**2,
                                      labels, lrange)))
         x = first_pixels - mean1[labels-1]  # x - mean(x)
         y = second_pixels - mean2[labels-1] # y - mean(y)
         corr = fix(scind.sum(x * y / (std1[labels-1] * std2[labels-1]),
                              labels, lrange))
         corr[~ np.isfinite(corr)] = 0
     measurement = ("Correlation_Correlation_%s_%s" %
                    (first_image_name, second_image_name))
     workspace.measurements.add_measurement(object_name, measurement, corr)
     if n_objects == 0:
         return [[first_image_name, second_image_name, object_name,
                  "Mean correlation","-"],
                 [first_image_name, second_image_name, object_name,
                  "Median correlation","-"],
                 [first_image_name, second_image_name, object_name,
                  "Min correlation","-"],
                 [first_image_name, second_image_name, object_name,
                  "Max correlation","-"]]
     else:
         return [[first_image_name, second_image_name, object_name,
                  "Mean correlation","%.2f"%np.mean(corr)],
                 [first_image_name, second_image_name, object_name,
                  "Median correlation","%.2f"%np.median(corr)],
                 [first_image_name, second_image_name, object_name,
                  "Min correlation","%.2f"%np.min(corr)],
                 [first_image_name, second_image_name, object_name,
                  "Max correlation","%.2f"%np.max(corr)]]
コード例 #20
0
    def run_one_tamura(self, image_name, object_name, workspace):
        """Run, computing the area measurements for a single map of objects"""
        statistics = []
        image = workspace.image_set.get_image(image_name,
                                              must_be_grayscale=True)
        objects = workspace.get_objects(object_name)
        pixel_data = image.pixel_data
        if image.has_mask:
            mask = image.mask
        else:
            mask = None
        labels = objects.segmented
        try:
            pixel_data = objects.crop_image_similarly(pixel_data)
        except ValueError:
            #
            # Recover by cropping the image to the labels
            #
            pixel_data, m1 = cpo.size_similarly(labels, pixel_data)
            if np.any(~m1):
                if mask is None:
                    mask = m1
                else:
                    mask, m2 = cpo.size_similarly(labels, mask)
                    mask[~m2] = False

        if np.all(labels == 0):
            for name in F_ALL:
                statistics += self.record_measurement(
                    workspace, image_name, object_name, "",
                    "%s_%s" % (F_TAMURA, name), np.zeros((0, )))
        else:
            labs = np.unique(labels)
            values = np.zeros([np.max(labs) + 1, 2])
            for l in labs:
                if l != 0:
                    px = pixel_data
                    px[np.where(labels != l)] = 0.0
                    values[l, 0] = self.contrast(px)
                    values[l, 1] = self.directionality(px)
                    statistics += self.record_measurement(
                        workspace, image_name, object_name, "-",
                        "%s_%s" % (F_TAMURA, F_2), values[:, 0])
                    statistics += self.record_measurement(
                        workspace, image_name, object_name, "-",
                        "%s_%s" % (F_TAMURA, F_3), values[:, 1])

            coars = np.zeros([np.max(labs) + 1])
            coars_hist = np.zeros([np.max(labs) + 1, HIST_COARS_BINS])
            for l in labs:
                if l != 0:
                    px = pixel_data
                    px[np.where(labels != l)] = 0.0
                    coars[l], coars_hist[l, :] = self.coarseness(px)
                    statistics += self.record_measurement(
                        workspace, image_name, object_name, "-",
                        "%s_%s" % (F_TAMURA, F_1), coars)
            for b in range(0, HIST_COARS_BINS):
                value = coars_hist[1:, b]
                name = "CoarsenessHist_%dBinsHist_Bin%d" % (HIST_COARS_BINS, b)
                statistics += self.record_measurement(
                    workspace, image_name, object_name, "-",
                    "%s_%s" % (F_TAMURA, name), value)

        return statistics
コード例 #21
0
    def run(self, workspace):
        '''Run the module on the image set'''
        seed_objects_name = self.seed_objects_name.value
        skeleton_name = self.image_name.value
        seed_objects = workspace.object_set.get_objects(seed_objects_name)
        labels = seed_objects.segmented
        labels_count = np.max(labels)
        label_range = np.arange(labels_count, dtype=np.int32) + 1

        skeleton_image = workspace.image_set.get_image(skeleton_name,
                                                       must_be_binary=True)
        skeleton = skeleton_image.pixel_data
        if skeleton_image.has_mask:
            skeleton = skeleton & skeleton_image.mask
        try:
            labels = skeleton_image.crop_image_similarly(labels)
        except:
            labels, m1 = cpo.size_similarly(skeleton, labels)
            labels[~m1] = 0
        #
        # The following code makes a ring around the seed objects with
        # the skeleton trunks sticking out of it.
        #
        # Create a new skeleton with holes at the seed objects
        # First combine the seed objects with the skeleton so
        # that the skeleton trunks come out of the seed objects.
        #
        # Erode the labels once so that all of the trunk branchpoints
        # will be within the labels
        #
        #
        # Dilate the objects, then subtract them to make a ring
        #
        my_disk = morph.strel_disk(1.5).astype(int)
        dilated_labels = grey_dilation(labels, footprint=my_disk)
        seed_mask = dilated_labels > 0
        combined_skel = skeleton | seed_mask

        closed_labels = grey_erosion(dilated_labels, footprint=my_disk)
        seed_center = closed_labels > 0
        combined_skel = combined_skel & (~seed_center)
        #
        # Fill in single holes (but not a one-pixel hole made by
        # a one-pixel image)
        #
        if self.wants_to_fill_holes:

            def size_fn(area, is_object):
                return (~is_object) and (area <= self.maximum_hole_size.value)

            combined_skel = morph.fill_labeled_holes(combined_skel,
                                                     ~seed_center, size_fn)
        #
        # Reskeletonize to make true branchpoints at the ring boundaries
        #
        combined_skel = morph.skeletonize(combined_skel)
        #
        # The skeleton outside of the labels
        #
        outside_skel = combined_skel & (dilated_labels == 0)
        #
        # Associate all skeleton points with seed objects
        #
        dlabels, distance_map = propagate.propagate(np.zeros(labels.shape),
                                                    dilated_labels,
                                                    combined_skel, 1)
        #
        # Get rid of any branchpoints not connected to seeds
        #
        combined_skel[dlabels == 0] = False
        #
        # Find the branchpoints
        #
        branch_points = morph.branchpoints(combined_skel)
        #
        # Odd case: when four branches meet like this, branchpoints are not
        # assigned because they are arbitrary. So assign them.
        #
        # .  .
        #  B.
        #  .B
        # .  .
        #
        odd_case = (combined_skel[:-1, :-1] & combined_skel[1:, :-1]
                    & combined_skel[:-1, 1:] & combined_skel[1, 1])
        branch_points[:-1, :-1][odd_case] = True
        branch_points[1:, 1:][odd_case] = True
        #
        # Find the branching counts for the trunks (# of extra branches
        # eminating from a point other than the line it might be on).
        #
        branching_counts = morph.branchings(combined_skel)
        branching_counts = np.array([0, 0, 0, 1, 2])[branching_counts]
        #
        # Only take branches within 1 of the outside skeleton
        #
        dilated_skel = scind.binary_dilation(outside_skel, morph.eight_connect)
        branching_counts[~dilated_skel] = 0
        #
        # Find the endpoints
        #
        end_points = morph.endpoints(combined_skel)
        #
        # We use two ranges for classification here:
        # * anything within one pixel of the dilated image is a trunk
        # * anything outside of that range is a branch
        #
        nearby_labels = dlabels.copy()
        nearby_labels[distance_map > 1.5] = 0

        outside_labels = dlabels.copy()
        outside_labels[nearby_labels > 0] = 0
        #
        # The trunks are the branchpoints that lie within one pixel of
        # the dilated image.
        #
        if labels_count > 0:
            trunk_counts = fix(
                scind.sum(branching_counts, nearby_labels,
                          label_range)).astype(int)
        else:
            trunk_counts = np.zeros((0, ), int)
        #
        # The branches are the branchpoints that lie outside the seed objects
        #
        if labels_count > 0:
            branch_counts = fix(
                scind.sum(branch_points, outside_labels, label_range))
        else:
            branch_counts = np.zeros((0, ), int)
        #
        # Save the endpoints
        #
        if labels_count > 0:
            end_counts = fix(scind.sum(end_points, outside_labels,
                                       label_range))
        else:
            end_counts = np.zeros((0, ), int)
        #
        # Save measurements
        #
        m = workspace.measurements
        assert isinstance(m, cpmeas.Measurements)
        feature = "_".join((C_NEURON, F_NUMBER_TRUNKS, skeleton_name))
        m.add_measurement(seed_objects_name, feature, trunk_counts)
        feature = "_".join(
            (C_NEURON, F_NUMBER_NON_TRUNK_BRANCHES, skeleton_name))
        m.add_measurement(seed_objects_name, feature, branch_counts)
        feature = "_".join((C_NEURON, F_NUMBER_BRANCH_ENDS, skeleton_name))
        m.add_measurement(seed_objects_name, feature, end_counts)
        #
        # Collect the graph information
        #
        if self.wants_neuron_graph:
            trunk_mask = (branching_counts > 0) & (nearby_labels != 0)
            intensity_image = workspace.image_set.get_image(
                self.intensity_image_name.value)
            edge_graph, vertex_graph = self.make_neuron_graph(
                combined_skel, dlabels, trunk_mask,
                branch_points & ~trunk_mask, end_points,
                intensity_image.pixel_data)
            #
            # Add an image number column to both and change vertex index
            # to vertex number (one-based)
            #
            image_number = workspace.measurements.image_set_number
            vertex_graph = np.rec.fromarrays(
                (np.ones(len(vertex_graph)) * image_number,
                 np.arange(1,
                           len(vertex_graph) + 1), vertex_graph['i'],
                 vertex_graph['j'], vertex_graph['labels'],
                 vertex_graph['kind']),
                names=("image_number", "vertex_number", "i", "j", "labels",
                       "kind"))

            edge_graph = np.rec.fromarrays(
                (np.ones(len(edge_graph)) * image_number, edge_graph["v1"],
                 edge_graph["v2"], edge_graph["length"],
                 edge_graph["total_intensity"]),
                names=("image_number", "v1", "v2", "length",
                       "total_intensity"))

            path = self.directory.get_absolute_path(m)
            edge_file = m.apply_metadata(self.edge_file_name.value)
            edge_path = os.path.abspath(os.path.join(path, edge_file))
            vertex_file = m.apply_metadata(self.vertex_file_name.value)
            vertex_path = os.path.abspath(os.path.join(path, vertex_file))
            d = self.get_dictionary(workspace.image_set_list)
            for file_path, table, fmt in ((edge_path, edge_graph,
                                           "%d,%d,%d,%d,%.4f"),
                                          (vertex_path, vertex_graph,
                                           "%d,%d,%d,%d,%d,%s")):
                #
                # Delete files first time through / otherwise append
                #
                if not d.has_key(file_path):
                    d[file_path] = True
                    if os.path.exists(file_path):
                        if workspace.frame is not None:
                            import wx
                            if wx.MessageBox(
                                    "%s already exists. Do you want to overwrite it?"
                                    % file_path,
                                    "Warning: overwriting file",
                                    style=wx.YES_NO,
                                    parent=workspace.frame) != wx.YES:
                                raise ValueError("Can't overwrite %s" %
                                                 file_path)
                        os.remove(file_path)
                    fd = open(file_path, 'wt')
                    header = ','.join(table.dtype.names)
                    fd.write(header + '\n')
                else:
                    fd = open(file_path, 'at')
                np.savetxt(fd, table, fmt)
                fd.close()
                if workspace.frame is not None:
                    workspace.display_data.edge_graph = edge_graph
                    workspace.display_data.vertex_graph = vertex_graph
        #
        # Make the display image
        #
        if workspace.frame is not None or self.wants_branchpoint_image:
            branchpoint_image = np.zeros(
                (skeleton.shape[0], skeleton.shape[1], 3))
            trunk_mask = (branching_counts > 0) & (nearby_labels != 0)
            branch_mask = branch_points & (outside_labels != 0)
            end_mask = end_points & (outside_labels != 0)
            branchpoint_image[outside_skel, :] = 1
            branchpoint_image[trunk_mask | branch_mask | end_mask, :] = 0
            branchpoint_image[trunk_mask, 0] = 1
            branchpoint_image[branch_mask, 1] = 1
            branchpoint_image[end_mask, 2] = 1
            branchpoint_image[dilated_labels != 0, :] *= .875
            branchpoint_image[dilated_labels != 0, :] += .1
            if workspace.frame:
                workspace.display_data.branchpoint_image = branchpoint_image
            if self.wants_branchpoint_image:
                bi = cpi.Image(branchpoint_image, parent_image=skeleton_image)
                workspace.image_set.add(self.branchpoint_image_name.value, bi)
コード例 #22
0
ファイル: maskobjects.py プロジェクト: refack/CellProfiler
 def run(self, workspace):
     '''Run the module on an image set'''
     
     object_name = self.object_name.value
     remaining_object_name = self.remaining_objects.value
     original_objects = workspace.object_set.get_objects(object_name)
     
     if self.mask_choice == MC_IMAGE:
         mask = workspace.image_set.get_image(self.masking_image.value,
                                              must_be_binary = True)
         mask = mask.pixel_data
     else:
         masking_objects = workspace.object_set.get_objects(
             self.masking_objects.value)
         mask = masking_objects.segmented > 0
     if self.wants_inverted_mask:
         mask = ~mask
     #
     # Load the labels
     #
     labels = original_objects.segmented.copy()
     nobjects = np.max(labels)
     #
     # Resize the mask to cover the objects
     #
     mask, m1 = cpo.size_similarly(labels, mask)
     mask[~m1] = False
     #
     # Apply the mask according to the overlap choice.
     #
     if nobjects == 0:
         pass
     elif self.overlap_choice == P_MASK:
         labels = labels * mask
     else:
         pixel_counts = fix(scind.sum(mask, labels, 
                                      np.arange(1, nobjects+1,dtype=np.int32)))
         if self.overlap_choice == P_KEEP:
             keep = pixel_counts > 0
         else:
             total_pixels = fix(scind.sum(np.ones(labels.shape), labels,
                                          np.arange(1, nobjects+1,dtype=np.int32)))
             if self.overlap_choice == P_REMOVE:
                 keep = pixel_counts == total_pixels
             elif self.overlap_choice == P_REMOVE_PERCENTAGE:
                 fraction = self.overlap_fraction.value
                 keep = pixel_counts / total_pixels >= fraction
             else:
                 raise NotImplementedError("Unknown overlap-handling choice: %s",
                                           self.overlap_choice.value)
         keep = np.hstack(([False], keep))
         labels[~ keep[labels]] = 0
     #
     # Renumber the labels matrix if requested
     #
     if self.retain_or_renumber == R_RENUMBER:
         unique_labels = np.unique(labels[labels!=0])
         indexer = np.zeros(nobjects+1, int)
         indexer[unique_labels] = np.arange(1, len(unique_labels)+1)
         labels = indexer[labels]
         parent_objects = unique_labels
     else:
         parent_objects = np.arange(1, nobjects+1)
     #
     # Add the objects
     #
     remaining_objects = cpo.Objects()
     remaining_objects.segmented = labels
     remaining_objects.unedited_segmented = original_objects.unedited_segmented
     workspace.object_set.add_objects(remaining_objects, 
                                      remaining_object_name)
     #
     # Add measurements
     #
     m = workspace.measurements
     m.add_measurement(remaining_object_name,
                       I.FF_PARENT % object_name,
                       parent_objects)
     if np.max(original_objects.segmented) == 0:
         child_count = np.array([],int)
     else:
         child_count = fix(scind.sum(labels, original_objects.segmented,
                                     np.arange(1, nobjects+1,dtype=np.int32)))
         child_count = (child_count > 0).astype(int)
     m.add_measurement(object_name,
                       I.FF_CHILDREN_COUNT % remaining_object_name,
                       child_count)
     if self.retain_or_renumber == R_RETAIN:
         remaining_object_count = nobjects
     else:
         remaining_object_count = len(unique_labels)
     I.add_object_count_measurements(m, remaining_object_name,
                                     remaining_object_count)
     I.add_object_location_measurements(m, remaining_object_name, labels)
     #
     # Add an outline if asked to do so
     #
     if self.wants_outlines.value:
         outline_image = cpi.Image(outline(labels) > 0,
                                   parent_image = original_objects.parent_image)
         workspace.image_set.add(self.outlines_name.value, outline_image)
     #
     # Save the input, mask and output images for display
     #
     if self.show_window:
         workspace.display_data.original_labels = original_objects.segmented
         workspace.display_data.final_labels = labels
         workspace.display_data.mask = mask
コード例 #23
0
    def run(self, workspace):
        """Run the module on the current data set
        
        workspace - has the current image set, object set, measurements
                    and the parent frame for the application if the module
                    is allowed to display. If the module should not display,
                    workspace.frame is None.
        """
        #
        # The object set holds "objects". Each of these is a container
        # for holding up to three kinds of image labels.
        #
        object_set = workspace.object_set
        #
        # Get the primary objects (the centers to be removed).
        # Get the string value out of primary_object_name.
        #
        primary_objects = object_set.get_objects(self.primary_objects_name.value)
        #
        # Get the cleaned-up labels image
        #
        primary_labels = primary_objects.segmented
        #
        # Do the same with the secondary object
        secondary_objects = object_set.get_objects(self.secondary_objects_name.value)
        secondary_labels = secondary_objects.segmented
        #
        # If one of the two label images is smaller than the other, we
        # try to find the cropping mask and we apply that mask to the larger
        #
        try:
            if any([p_size < s_size 
                    for p_size,s_size
                    in zip(primary_labels.shape, secondary_labels.shape)]):
                #
                # Look for a cropping mask associated with the primary_labels
                # and apply that mask to resize the secondary labels
                #
                secondary_labels = primary_objects.crop_image_similarly(secondary_labels)
                tertiary_image = primary_objects.parent_image
            elif any([p_size > s_size 
                    for p_size,s_size
                    in zip(primary_labels.shape, secondary_labels.shape)]):
                primary_labels = secondary_objects.crop_image_similarly(primary_labels)
                tertiary_image = secondary_objects.parent_image
            elif secondary_objects.parent_image is not None:
                tertiary_image = secondary_objects.parent_image
            else:
                tertiary_image = primary_objects.parent_image
        except ValueError:
            # No suitable cropping - resize all to fit the secondary
            # labels which are the most critical.
            #
            primary_labels, _ = cpo.size_similarly(secondary_labels, primary_labels)
            if secondary_objects.parent_image is not None:
                tertiary_image = secondary_objects.parent_image
            else:
                tertiary_image = primary_objects.parent_image
                if tertiary_image is not None:
                    tertiary_image, _ = cpo.size_similarly(secondary_labels, tertiary_image)
        #
        # Find the outlines of the primary image and use this to shrink the
        # primary image by one. This guarantees that there is something left
        # of the secondary image after subtraction
        #
        primary_outline = outline(primary_labels)
        tertiary_labels = secondary_labels.copy()
        if self.shrink_primary:
            primary_mask = np.logical_or(primary_labels == 0,
                                         primary_outline)
        else:
            primary_mask = primary_labels == 0
        tertiary_labels[primary_mask == False] = 0
        #
        # Get the outlines of the tertiary image
        #
        tertiary_outlines = outline(tertiary_labels)!=0
        #
        # Make the tertiary objects container
        #
        tertiary_objects = cpo.Objects()
        tertiary_objects.segmented = tertiary_labels
        tertiary_objects.parent_image = tertiary_image
        #
        # Relate tertiary objects to their parents & record
        #
        child_count_of_secondary, secondary_parents = \
            secondary_objects.relate_children(tertiary_objects)
        if self.shrink_primary:
            child_count_of_primary, primary_parents = \
                primary_objects.relate_children(tertiary_objects)
        else:
            # Primary and tertiary don't overlap.
            # Establish overlap between primary and secondary and commute
            _, secondary_of_primary = \
                secondary_objects.relate_children(primary_objects)
            mask = secondary_of_primary != 0
            child_count_of_primary = np.zeros(mask.shape, int)
            child_count_of_primary[mask] = child_count_of_secondary[
                secondary_of_primary[mask] - 1]
            primary_parents = np.zeros(secondary_parents.shape, 
                                       secondary_parents.dtype)
            primary_of_secondary = np.zeros(secondary_objects.count+1, int)
            primary_of_secondary[secondary_of_primary] = \
                np.arange(1, len(secondary_of_primary)+1)
            primary_of_secondary[0] = 0
            primary_parents = primary_of_secondary[secondary_parents]
        #
        # Write out the objects
        #
        workspace.object_set.add_objects(tertiary_objects,
                                         self.subregion_objects_name.value)
        #
        # Write out the measurements
        #
        m = workspace.measurements
        #
        # The parent/child associations
        #
        for parent_objects_name, parents_of, child_count, relationship in (
            (self.primary_objects_name, primary_parents, 
             child_count_of_primary, R_REMOVED),
            (self.secondary_objects_name, secondary_parents, 
             child_count_of_secondary, R_PARENT)):
            m.add_measurement(self.subregion_objects_name.value,
                              cpmi.FF_PARENT%(parent_objects_name.value),
                              parents_of)
            m.add_measurement(parent_objects_name.value,
                              cpmi.FF_CHILDREN_COUNT%(self.subregion_objects_name.value),
                              child_count)
            mask = parents_of != 0
            image_number = np.ones(np.sum(mask), int) * m.image_set_number
            child_object_number = np.argwhere(mask).flatten() + 1
            parent_object_number = parents_of[mask]
            m.add_relate_measurement(
                self.module_num, relationship,
                parent_objects_name.value, self.subregion_objects_name.value,
                image_number, parent_object_number,
                image_number, child_object_number)
            
        object_count = tertiary_objects.count
        #
        # The object count
        #
        cpmi.add_object_count_measurements(workspace.measurements,
                                           self.subregion_objects_name.value,
                                           object_count)
        #
        # The object locations
        #
        cpmi.add_object_location_measurements(workspace.measurements,
                                              self.subregion_objects_name.value,
                                              tertiary_labels)
        #
        # The outlines
        #
        if self.use_outlines.value:
            out_img = cpi.Image(tertiary_outlines.astype(bool),
                                parent_image = tertiary_image)
            workspace.image_set.add(self.outlines_name.value, out_img)

        if self.show_window:
            workspace.display_data.primary_labels = primary_labels
            workspace.display_data.secondary_labels = secondary_labels
            workspace.display_data.tertiary_labels = tertiary_labels
            workspace.display_data.tertiary_outlines = tertiary_outlines
コード例 #24
0
    def run(self, workspace):
        """Run the module on the current data set
        
        workspace - has the current image set, object set, measurements
                    and the parent frame for the application if the module
                    is allowed to display. If the module should not display,
                    workspace.frame is None.
        """
        #
        # The object set holds "objects". Each of these is a container
        # for holding up to three kinds of image labels.
        #
        object_set = workspace.object_set
        #
        # Get the primary objects (the centers to be removed).
        # Get the string value out of primary_object_name.
        #
        primary_objects = object_set.get_objects(
            self.primary_objects_name.value)
        #
        # Get the cleaned-up labels image
        #
        primary_labels = primary_objects.segmented
        #
        # Do the same with the secondary object
        secondary_objects = object_set.get_objects(
            self.secondary_objects_name.value)
        secondary_labels = secondary_objects.segmented
        #
        # If one of the two label images is smaller than the other, we
        # try to find the cropping mask and we apply that mask to the larger
        #
        try:
            if any([
                    p_size < s_size for p_size, s_size in zip(
                        primary_labels.shape, secondary_labels.shape)
            ]):
                #
                # Look for a cropping mask associated with the primary_labels
                # and apply that mask to resize the secondary labels
                #
                secondary_labels = primary_objects.crop_image_similarly(
                    secondary_labels)
                tertiary_image = primary_objects.parent_image
            elif any([
                    p_size > s_size for p_size, s_size in zip(
                        primary_labels.shape, secondary_labels.shape)
            ]):
                primary_labels = secondary_objects.crop_image_similarly(
                    primary_labels)
                tertiary_image = secondary_objects.parent_image
            elif secondary_objects.parent_image != None:
                tertiary_image = secondary_objects.parent_image
            else:
                tertiary_image = primary_objects.parent_image
        except ValueError:
            # No suitable cropping - resize all to fit the secondary
            # labels which are the most critical.
            #
            primary_labels, _ = cpo.size_similarly(secondary_labels,
                                                   primary_labels)
            if secondary_objects.parent_image != None:
                tertiary_image = secondary_objects.parent_image
            else:
                tertiary_image = primary_objects.parent_image
                if tertiary_image is not None:
                    tertiary_image, _ = cpo.size_similarly(
                        secondary_labels, tertiary_image)
        #
        # Find the outlines of the primary image and use this to shrink the
        # primary image by one. This guarantees that there is something left
        # of the secondary image after subtraction
        #
        primary_outline = outline(primary_labels)
        tertiary_labels = secondary_labels.copy()
        primary_mask = np.logical_or(primary_labels == 0, primary_outline)
        tertiary_labels[primary_mask == False] = 0
        #
        # Get the outlines of the tertiary image
        #
        tertiary_outlines = outline(tertiary_labels) != 0
        #
        # Make the tertiary objects container
        #
        tertiary_objects = cpo.Objects()
        tertiary_objects.segmented = tertiary_labels
        tertiary_objects.parent_image = tertiary_image
        #
        # Relate tertiary objects to their parents & record
        #
        child_count_of_secondary, secondary_parents = \
            secondary_objects.relate_children(tertiary_objects)
        child_count_of_primary, primary_parents = \
            primary_objects.relate_children(tertiary_objects)

        if workspace.frame != None:
            import cellprofiler.gui.cpfigure as cpf
            #
            # Draw the primary, secondary and tertiary labels
            # and the outlines
            #
            window_name = "CellProfiler:%s:%d" % (self.module_name,
                                                  self.module_num)
            my_frame = cpf.create_or_find(
                workspace.frame,
                title="IdentifyTertiaryObjects, image cycle #%d" %
                (workspace.measurements.image_set_number),
                name=window_name,
                subplots=(2, 2))

            title = "%s, cycle # %d" % (self.primary_objects_name.value,
                                        workspace.image_set.number + 1)
            my_frame.subplot_imshow_labels(0, 0, primary_labels, title)
            my_frame.subplot_imshow_labels(1,
                                           0,
                                           secondary_labels,
                                           self.secondary_objects_name.value,
                                           sharex=my_frame.subplot(0, 0),
                                           sharey=my_frame.subplot(0, 0))
            my_frame.subplot_imshow_labels(0,
                                           1,
                                           tertiary_labels,
                                           self.subregion_objects_name.value,
                                           sharex=my_frame.subplot(0, 0),
                                           sharey=my_frame.subplot(0, 0))
            my_frame.subplot_imshow_bw(1,
                                       1,
                                       tertiary_outlines,
                                       "Outlines",
                                       sharex=my_frame.subplot(0, 0),
                                       sharey=my_frame.subplot(0, 0))
            my_frame.Refresh()
        #
        # Write out the objects
        #
        workspace.object_set.add_objects(tertiary_objects,
                                         self.subregion_objects_name.value)
        #
        # Write out the measurements
        #
        m = workspace.measurements
        #
        # The parent/child associations
        #
        for parent_objects_name, parents_of, child_count\
         in ((self.primary_objects_name, primary_parents,child_count_of_primary),
             (self.secondary_objects_name, secondary_parents, child_count_of_secondary)):
            m.add_measurement(self.subregion_objects_name.value,
                              cpmi.FF_PARENT % (parent_objects_name.value),
                              parents_of)
            m.add_measurement(
                parent_objects_name.value,
                cpmi.FF_CHILDREN_COUNT % (self.subregion_objects_name.value),
                child_count)
        object_count = np.max(tertiary_labels)
        #
        # The object count
        #
        cpmi.add_object_count_measurements(workspace.measurements,
                                           self.subregion_objects_name.value,
                                           object_count)
        #
        # The object locations
        #
        cpmi.add_object_location_measurements(
            workspace.measurements, self.subregion_objects_name.value,
            tertiary_labels)
        #
        # The outlines
        #
        if self.use_outlines.value:
            out_img = cpi.Image(tertiary_outlines.astype(bool),
                                parent_image=tertiary_image)
            workspace.image_set.add(self.outlines_name.value, out_img)
コード例 #25
0
 def run(self, workspace):
     """Run the module on the current data set
     
     workspace - has the current image set, object set, measurements
                 and the parent frame for the application if the module
                 is allowed to display. If the module should not display,
                 workspace.frame is None.
     """
     #
     # The object set holds "objects". Each of these is a container
     # for holding up to three kinds of image labels.
     #
     object_set = workspace.object_set
     #
     # Get the primary objects (the centers to be removed).
     # Get the string value out of primary_object_name.
     #
     primary_objects = object_set.get_objects(self.primary_objects_name.value)
     #
     # Get the cleaned-up labels image
     #
     primary_labels = primary_objects.segmented
     #
     # Do the same with the secondary object
     secondary_objects = object_set.get_objects(self.secondary_objects_name.value)
     secondary_labels = secondary_objects.segmented
     #
     # If one of the two label images is smaller than the other, we
     # try to find the cropping mask and we apply that mask to the larger
     #
     try:
         if any([p_size < s_size 
                 for p_size,s_size
                 in zip(primary_labels.shape, secondary_labels.shape)]):
             #
             # Look for a cropping mask associated with the primary_labels
             # and apply that mask to resize the secondary labels
             #
             secondary_labels = primary_objects.crop_image_similarly(secondary_labels)
             tertiary_image = primary_objects.parent_image
         elif any([p_size > s_size 
                 for p_size,s_size
                 in zip(primary_labels.shape, secondary_labels.shape)]):
             primary_labels = secondary_objects.crop_image_similarly(primary_labels)
             tertiary_image = secondary_objects.parent_image
         elif secondary_objects.parent_image != None:
             tertiary_image = secondary_objects.parent_image
         else:
             tertiary_image = primary_objects.parent_image
     except ValueError:
         # No suitable cropping - resize all to fit the secondary
         # labels which are the most critical.
         #
         primary_labels, _ = cpo.size_similarly(secondary_labels, primary_labels)
         if secondary_objects.parent_image != None:
             tertiary_image = secondary_objects.parent_image
         else:
             tertiary_image = primary_objects.parent_image
             if tertiary_image is not None:
                 tertiary_image, _ = cpo.size_similarly(secondary_labels, tertiary_image)
     #
     # Find the outlines of the primary image and use this to shrink the
     # primary image by one. This guarantees that there is something left
     # of the secondary image after subtraction
     #
     primary_outline = outline(primary_labels)
     tertiary_labels = secondary_labels.copy()
     primary_mask = np.logical_or(primary_labels == 0,
                                  primary_outline)
     tertiary_labels[primary_mask == False] = 0
     #
     # Get the outlines of the tertiary image
     #
     tertiary_outlines = outline(tertiary_labels)!=0
     #
     # Make the tertiary objects container
     #
     tertiary_objects = cpo.Objects()
     tertiary_objects.segmented = tertiary_labels
     tertiary_objects.parent_image = tertiary_image
     #
     # Relate tertiary objects to their parents & record
     #
     child_count_of_secondary, secondary_parents = \
         secondary_objects.relate_children(tertiary_objects)
     child_count_of_primary, primary_parents = \
         primary_objects.relate_children(tertiary_objects)
     
     if workspace.frame != None:
         import cellprofiler.gui.cpfigure as cpf
         #
         # Draw the primary, secondary and tertiary labels
         # and the outlines
         #
         window_name = "CellProfiler:%s:%d"%(self.module_name,self.module_num)
         my_frame=cpf.create_or_find(workspace.frame, 
                                     title="IdentifyTertiaryObjects, image cycle #%d"%(
             workspace.measurements.image_set_number), 
                                     name=window_name, subplots=(2,2))
         
         title = "%s, cycle # %d"%(self.primary_objects_name.value,
                                   workspace.image_set.number+1)
         my_frame.subplot_imshow_labels(0,0,primary_labels,title)
         my_frame.subplot_imshow_labels(1,0,secondary_labels, 
                                        self.secondary_objects_name.value,
                                        sharex = my_frame.subplot(0,0),
                                        sharey = my_frame.subplot(0,0))
         my_frame.subplot_imshow_labels(0, 1,tertiary_labels, 
                                        self.subregion_objects_name.value,
                                        sharex = my_frame.subplot(0,0),
                                        sharey = my_frame.subplot(0,0))
         my_frame.subplot_imshow_bw(1,1,tertiary_outlines, 
                                    "Outlines",
                                    sharex = my_frame.subplot(0,0),
                                    sharey = my_frame.subplot(0,0))
         my_frame.Refresh()
     #
     # Write out the objects
     #
     workspace.object_set.add_objects(tertiary_objects,
                                      self.subregion_objects_name.value)
     #
     # Write out the measurements
     #
     m = workspace.measurements
     #
     # The parent/child associations
     #
     for parent_objects_name, parents_of, child_count\
      in ((self.primary_objects_name, primary_parents,child_count_of_primary),
          (self.secondary_objects_name, secondary_parents, child_count_of_secondary)):
         m.add_measurement(self.subregion_objects_name.value,
                           cpmi.FF_PARENT%(parent_objects_name.value),
                           parents_of)
         m.add_measurement(parent_objects_name.value,
                           cpmi.FF_CHILDREN_COUNT%(self.subregion_objects_name.value),
                           child_count)
     object_count = np.max(tertiary_labels)
     #
     # The object count
     #
     cpmi.add_object_count_measurements(workspace.measurements,
                                        self.subregion_objects_name.value,
                                        object_count)
     #
     # The object locations
     #
     cpmi.add_object_location_measurements(workspace.measurements,
                                           self.subregion_objects_name.value,
                                           tertiary_labels)
     #
     # The outlines
     #
     if self.use_outlines.value:
         out_img = cpi.Image(tertiary_outlines.astype(bool),
                             parent_image = tertiary_image)
         workspace.image_set.add(self.outlines_name.value, out_img)
コード例 #26
0
    def run(self, workspace):
        """Run the module on the current data set
        
        workspace - has the current image set, object set, measurements
                    and the parent frame for the application if the module
                    is allowed to display. If the module should not display,
                    workspace.frame is None.
        """
        #
        # The object set holds "objects". Each of these is a container
        # for holding up to three kinds of image labels.
        #
        object_set = workspace.object_set
        #
        # Get the primary objects (the centers to be removed).
        # Get the string value out of primary_object_name.
        #
        primary_objects = object_set.get_objects(
            self.primary_objects_name.value)
        #
        # Get the cleaned-up labels image
        #
        primary_labels = primary_objects.segmented
        #
        # Do the same with the secondary object
        secondary_objects = object_set.get_objects(
            self.secondary_objects_name.value)
        secondary_labels = secondary_objects.segmented
        #
        # If one of the two label images is smaller than the other, we
        # try to find the cropping mask and we apply that mask to the larger
        #
        try:
            if any([
                    p_size < s_size for p_size, s_size in zip(
                        primary_labels.shape, secondary_labels.shape)
            ]):
                #
                # Look for a cropping mask associated with the primary_labels
                # and apply that mask to resize the secondary labels
                #
                secondary_labels = primary_objects.crop_image_similarly(
                    secondary_labels)
                tertiary_image = primary_objects.parent_image
            elif any([
                    p_size > s_size for p_size, s_size in zip(
                        primary_labels.shape, secondary_labels.shape)
            ]):
                primary_labels = secondary_objects.crop_image_similarly(
                    primary_labels)
                tertiary_image = secondary_objects.parent_image
            elif secondary_objects.parent_image != None:
                tertiary_image = secondary_objects.parent_image
            else:
                tertiary_image = primary_objects.parent_image
        except ValueError:
            # No suitable cropping - resize all to fit the secondary
            # labels which are the most critical.
            #
            primary_labels, _ = cpo.size_similarly(secondary_labels,
                                                   primary_labels)
            if secondary_objects.parent_image != None:
                tertiary_image = secondary_objects.parent_image
            else:
                tertiary_image = primary_objects.parent_image
                if tertiary_image is not None:
                    tertiary_image, _ = cpo.size_similarly(
                        secondary_labels, tertiary_image)
        #
        # Find the outlines of the primary image and use this to shrink the
        # primary image by one. This guarantees that there is something left
        # of the secondary image after subtraction
        #
        primary_outline = outline(primary_labels)
        tertiary_labels = secondary_labels.copy()
        if self.shrink_primary:
            primary_mask = np.logical_or(primary_labels == 0, primary_outline)
        else:
            primary_mask = primary_labels == 0
        tertiary_labels[primary_mask == False] = 0
        #
        # Get the outlines of the tertiary image
        #
        tertiary_outlines = outline(tertiary_labels) != 0
        #
        # Make the tertiary objects container
        #
        tertiary_objects = cpo.Objects()
        tertiary_objects.segmented = tertiary_labels
        tertiary_objects.parent_image = tertiary_image
        #
        # Relate tertiary objects to their parents & record
        #
        child_count_of_secondary, secondary_parents = \
            secondary_objects.relate_children(tertiary_objects)
        if self.shrink_primary:
            child_count_of_primary, primary_parents = \
                primary_objects.relate_children(tertiary_objects)
        else:
            # Primary and tertiary don't overlap. If tertiary object
            # disappeared, have primary disavow knowledge of it.
            child_count_of_primary = np.zeros(primary_objects.count)
            child_count_of_primary[tertiary_objects.areas > 0] = 1
            primary_parents = np.arange(1, tertiary_objects.count + 1)

        #
        # Write out the objects
        #
        workspace.object_set.add_objects(tertiary_objects,
                                         self.subregion_objects_name.value)
        #
        # Write out the measurements
        #
        m = workspace.measurements
        #
        # The parent/child associations
        #
        for parent_objects_name, parents_of, child_count\
         in ((self.primary_objects_name, primary_parents,child_count_of_primary),
             (self.secondary_objects_name, secondary_parents, child_count_of_secondary)):
            m.add_measurement(self.subregion_objects_name.value,
                              cpmi.FF_PARENT % (parent_objects_name.value),
                              parents_of)
            m.add_measurement(
                parent_objects_name.value,
                cpmi.FF_CHILDREN_COUNT % (self.subregion_objects_name.value),
                child_count)
        object_count = tertiary_objects.count
        #
        # The object count
        #
        cpmi.add_object_count_measurements(workspace.measurements,
                                           self.subregion_objects_name.value,
                                           object_count)
        #
        # The object locations
        #
        cpmi.add_object_location_measurements(
            workspace.measurements, self.subregion_objects_name.value,
            tertiary_labels)
        #
        # The outlines
        #
        if self.use_outlines.value:
            out_img = cpi.Image(tertiary_outlines.astype(bool),
                                parent_image=tertiary_image)
            workspace.image_set.add(self.outlines_name.value, out_img)

        if self.show_window:
            workspace.display_data.primary_labels = primary_labels
            workspace.display_data.secondary_labels = secondary_labels
            workspace.display_data.tertiary_labels = tertiary_labels
            workspace.display_data.tertiary_outlines = tertiary_outlines
コード例 #27
0
 def run(self, workspace):
     '''Run the module on the image set'''
     seed_objects_name = self.seed_objects_name.value
     skeleton_name = self.image_name.value
     seed_objects = workspace.object_set.get_objects(seed_objects_name)
     labels = seed_objects.segmented
     labels_count = np.max(labels)
     label_range = np.arange(labels_count,dtype=np.int32)+1
     
     skeleton_image = workspace.image_set.get_image(
         skeleton_name, must_be_binary = True)
     skeleton = skeleton_image.pixel_data
     if skeleton_image.has_mask:
         skeleton = skeleton & skeleton_image.mask
     try:
         labels = skeleton_image.crop_image_similarly(labels)
     except:
         labels, m1 = cpo.size_similarly(skeleton, labels)
         labels[~m1] = 0
     #
     # The following code makes a ring around the seed objects with
     # the skeleton trunks sticking out of it.
     #
     # Create a new skeleton with holes at the seed objects
     # First combine the seed objects with the skeleton so
     # that the skeleton trunks come out of the seed objects.
     #
     # Erode the labels once so that all of the trunk branchpoints
     # will be within the labels
     #
     #
     # Dilate the objects, then subtract them to make a ring
     #
     my_disk = morph.strel_disk(1.5).astype(int)
     dilated_labels = grey_dilation(labels, footprint=my_disk)
     seed_mask = dilated_labels > 0
     combined_skel = skeleton | seed_mask
     
     closed_labels = grey_erosion(dilated_labels,
                                  footprint = my_disk)
     seed_center = closed_labels > 0
     combined_skel = combined_skel & (~seed_center)
     #
     # Fill in single holes (but not a one-pixel hole made by
     # a one-pixel image)
     #
     if self.wants_to_fill_holes:
         def size_fn(area, is_object):
             return (~ is_object) and (area <= self.maximum_hole_size.value)
         combined_skel = morph.fill_labeled_holes(
             combined_skel, ~seed_center, size_fn)
     #
     # Reskeletonize to make true branchpoints at the ring boundaries
     #
     combined_skel = morph.skeletonize(combined_skel)
     #
     # The skeleton outside of the labels
     #
     outside_skel = combined_skel & (dilated_labels == 0)
     #
     # Associate all skeleton points with seed objects
     #
     dlabels, distance_map = propagate.propagate(np.zeros(labels.shape),
                                                 dilated_labels,
                                                 combined_skel, 1)
     #
     # Get rid of any branchpoints not connected to seeds
     #
     combined_skel[dlabels == 0] = False
     #
     # Find the branchpoints
     #
     branch_points = morph.branchpoints(combined_skel)
     #
     # Odd case: when four branches meet like this, branchpoints are not
     # assigned because they are arbitrary. So assign them.
     #
     # .  .
     #  B.
     #  .B
     # .  .
     #
     odd_case = (combined_skel[:-1,:-1] & combined_skel[1:,:-1] &
                 combined_skel[:-1,1:] & combined_skel[1,1])
     branch_points[:-1,:-1][odd_case] = True
     branch_points[1:,1:][odd_case] = True
     #
     # Find the branching counts for the trunks (# of extra branches
     # eminating from a point other than the line it might be on).
     #
     branching_counts = morph.branchings(combined_skel)
     branching_counts = np.array([0,0,0,1,2])[branching_counts]
     #
     # Only take branches within 1 of the outside skeleton
     #
     dilated_skel = scind.binary_dilation(outside_skel, morph.eight_connect)
     branching_counts[~dilated_skel] = 0
     #
     # Find the endpoints
     #
     end_points = morph.endpoints(combined_skel)
     #
     # We use two ranges for classification here:
     # * anything within one pixel of the dilated image is a trunk
     # * anything outside of that range is a branch
     #
     nearby_labels = dlabels.copy()
     nearby_labels[distance_map > 1.5] = 0
     
     outside_labels = dlabels.copy()
     outside_labels[nearby_labels > 0] = 0
     #
     # The trunks are the branchpoints that lie within one pixel of
     # the dilated image.
     #
     if labels_count > 0:
         trunk_counts = fix(scind.sum(branching_counts, nearby_labels, 
                                      label_range)).astype(int)
     else:
         trunk_counts = np.zeros((0,),int)
     #
     # The branches are the branchpoints that lie outside the seed objects
     #
     if labels_count > 0:
         branch_counts = fix(scind.sum(branch_points, outside_labels, 
                                       label_range))
     else:
         branch_counts = np.zeros((0,),int)
     #
     # Save the endpoints
     #
     if labels_count > 0:
         end_counts = fix(scind.sum(end_points, outside_labels, label_range))
     else:
         end_counts = np.zeros((0,), int)
     #
     # Save measurements
     #
     m = workspace.measurements
     assert isinstance(m, cpmeas.Measurements)
     feature = "_".join((C_NEURON, F_NUMBER_TRUNKS, skeleton_name))
     m.add_measurement(seed_objects_name, feature, trunk_counts)
     feature = "_".join((C_NEURON, F_NUMBER_NON_TRUNK_BRANCHES, 
                         skeleton_name))
     m.add_measurement(seed_objects_name, feature, branch_counts)
     feature = "_".join((C_NEURON, F_NUMBER_BRANCH_ENDS, skeleton_name))
     m.add_measurement(seed_objects_name, feature, end_counts)
     #
     # Collect the graph information
     #
     if self.wants_neuron_graph:
         trunk_mask = (branching_counts > 0) & (nearby_labels != 0)
         intensity_image = workspace.image_set.get_image(
             self.intensity_image_name.value)
         edge_graph, vertex_graph = self.make_neuron_graph(
             combined_skel, dlabels, 
             trunk_mask,
             branch_points & ~trunk_mask,
             end_points,
             intensity_image.pixel_data)
         #
         # Add an image number column to both and change vertex index
         # to vertex number (one-based)
         #
         image_number = workspace.measurements.image_set_number
         vertex_graph = np.rec.fromarrays(
             (np.ones(len(vertex_graph)) * image_number,
              np.arange(1, len(vertex_graph) + 1),
              vertex_graph['i'],
              vertex_graph['j'],
              vertex_graph['labels'],
              vertex_graph['kind']),
             names = ("image_number", "vertex_number", "i", "j",
                      "labels", "kind"))
         
         edge_graph = np.rec.fromarrays(
             (np.ones(len(edge_graph)) * image_number,
              edge_graph["v1"],
              edge_graph["v2"],
              edge_graph["length"],
              edge_graph["total_intensity"]),
             names = ("image_number", "v1", "v2", "length", 
                      "total_intensity"))
         
         path = self.directory.get_absolute_path(m)
         edge_file = m.apply_metadata(self.edge_file_name.value)
         edge_path = os.path.abspath(os.path.join(path, edge_file))
         vertex_file = m.apply_metadata(self.vertex_file_name.value)
         vertex_path = os.path.abspath(os.path.join(path, vertex_file))
         d = self.get_dictionary(workspace.image_set_list)
         for file_path, table, fmt in (
             (edge_path, edge_graph, "%d,%d,%d,%d,%.4f"),
             (vertex_path, vertex_graph, "%d,%d,%d,%d,%d,%s")):
             #
             # Delete files first time through / otherwise append
             #
             if not d.has_key(file_path):
                 d[file_path] = True
                 if os.path.exists(file_path):
                     if workspace.frame is not None:
                         import wx
                         if wx.MessageBox(
                             "%s already exists. Do you want to overwrite it?" %
                             file_path, "Warning: overwriting file",
                             style = wx.YES_NO, 
                             parent = workspace.frame) != wx.YES:
                             raise ValueError("Can't overwrite %s" % file_path)
                     os.remove(file_path)
                 fd = open(file_path, 'wt')
                 header = ','.join(table.dtype.names)
                 fd.write(header + '\n')
             else:
                 fd = open(file_path, 'at')
             np.savetxt(fd, table, fmt)
             fd.close()
             if workspace.frame is not None:
                 workspace.display_data.edge_graph = edge_graph
                 workspace.display_data.vertex_graph = vertex_graph
     #
     # Make the display image
     #
     if workspace.frame is not None or self.wants_branchpoint_image:
         branchpoint_image = np.zeros((skeleton.shape[0],
                                       skeleton.shape[1],
                                       3))
         trunk_mask = (branching_counts > 0) & (nearby_labels != 0)
         branch_mask = branch_points & (outside_labels != 0)
         end_mask = end_points & (outside_labels != 0)
         branchpoint_image[outside_skel,:] = 1
         branchpoint_image[trunk_mask | branch_mask | end_mask,:] = 0
         branchpoint_image[trunk_mask,0] = 1
         branchpoint_image[branch_mask,1] = 1
         branchpoint_image[end_mask, 2] = 1
         branchpoint_image[dilated_labels != 0,:] *= .875
         branchpoint_image[dilated_labels != 0,:] += .1
         if workspace.frame:
             workspace.display_data.branchpoint_image = branchpoint_image
         if self.wants_branchpoint_image:
             bi = cpi.Image(branchpoint_image,
                            parent_image = skeleton_image)
             workspace.image_set.add(self.branchpoint_image_name.value, bi)
コード例 #28
0
 def run_image_pair_objects(self, workspace, first_image_name,
                            second_image_name, object_name):
     '''Calculate per-object correlations between intensities in two images'''
     first_image = workspace.image_set.get_image(first_image_name,
                                                 must_be_grayscale=True)
     second_image = workspace.image_set.get_image(second_image_name,
                                                  must_be_grayscale=True)
     objects = workspace.object_set.get_objects(object_name)
     #
     # Crop both images to the size of the labels matrix
     #
     labels = objects.segmented
     try:
         first_pixels  = objects.crop_image_similarly(first_image.pixel_data)
         first_mask    = objects.crop_image_similarly(first_image.mask)
     except ValueError:
         first_pixels, m1 = cpo.size_similarly(labels, first_image.pixel_data)
         first_mask, m1 = cpo.size_similarly(labels, first_image.mask)
         first_mask[~m1] = False
     try:
         second_pixels = objects.crop_image_similarly(second_image.pixel_data)
         second_mask   = objects.crop_image_similarly(second_image.mask)
     except ValueError:
         second_pixels, m1 = cpo.size_similarly(labels, second_image.pixel_data)
         second_mask, m1 = cpo.size_similarly(labels, second_image.mask)
         second_mask[~m1] = False
     mask   = ((labels > 0) & first_mask & second_mask)
     first_pixels = first_pixels[mask]
     second_pixels = second_pixels[mask]
     labels = labels[mask]
     if len(labels)==0:
         n_objects = 0
     else:
         n_objects = np.max(labels)
     if n_objects == 0:
         corr = np.zeros((0,))
     else:
         #
         # The correlation is sum((x-mean(x))(y-mean(y)) /
         #                         ((n-1) * std(x) *std(y)))
         #
         lrange = np.arange(n_objects,dtype=np.int32)+1
         area  = fix(scind.sum(np.ones_like(labels), labels, lrange))
         mean1 = fix(scind.mean(first_pixels, labels, lrange))
         mean2 = fix(scind.mean(second_pixels, labels, lrange))
         #
         # Calculate the standard deviation times the population.
         #
         std1 = np.sqrt(fix(scind.sum((first_pixels-mean1[labels-1])**2,
                                      labels, lrange)))
         std2 = np.sqrt(fix(scind.sum((second_pixels-mean2[labels-1])**2,
                                      labels, lrange)))
         x = first_pixels - mean1[labels-1]  # x - mean(x)
         y = second_pixels - mean2[labels-1] # y - mean(y)
         corr = fix(scind.sum(x * y / (std1[labels-1] * std2[labels-1]),
                              labels, lrange))
         corr[~ np.isfinite(corr)] = 0
     measurement = ("Correlation_Correlation_%s_%s" %
                    (first_image_name, second_image_name))
     workspace.measurements.add_measurement(object_name, measurement, corr)
     if n_objects == 0:
         return [[first_image_name, second_image_name, object_name,
                  "Mean correlation","-"],
                 [first_image_name, second_image_name, object_name,
                  "Median correlation","-"],
                 [first_image_name, second_image_name, object_name,
                  "Min correlation","-"],
                 [first_image_name, second_image_name, object_name,
                  "Max correlation","-"]]
     else:
         return [[first_image_name, second_image_name, object_name,
                  "Mean correlation","%.2f"%np.mean(corr)],
                 [first_image_name, second_image_name, object_name,
                  "Median correlation","%.2f"%np.median(corr)],
                 [first_image_name, second_image_name, object_name,
                  "Min correlation","%.2f"%np.min(corr)],
                 [first_image_name, second_image_name, object_name,
                  "Max correlation","%.2f"%np.max(corr)]]
コード例 #29
0
    def run_image_pair_objects(self, workspace, first_image_name,
                               second_image_name, object_name):
        '''Calculate per-object correlations between intensities in two images'''
        first_image = workspace.image_set.get_image(first_image_name,
                                                    must_be_grayscale=True)
        second_image = workspace.image_set.get_image(second_image_name,
                                                     must_be_grayscale=True)
        objects = workspace.object_set.get_objects(object_name)
        #
        # Crop both images to the size of the labels matrix
        #
        labels = objects.segmented
        try:
            first_pixels = objects.crop_image_similarly(first_image.pixel_data)
            first_mask = objects.crop_image_similarly(first_image.mask)
        except ValueError:
            first_pixels, m1 = cpo.size_similarly(labels,
                                                  first_image.pixel_data)
            first_mask, m1 = cpo.size_similarly(labels, first_image.mask)
            first_mask[~m1] = False
        try:
            second_pixels = objects.crop_image_similarly(
                second_image.pixel_data)
            second_mask = objects.crop_image_similarly(second_image.mask)
        except ValueError:
            second_pixels, m1 = cpo.size_similarly(labels,
                                                   second_image.pixel_data)
            second_mask, m1 = cpo.size_similarly(labels, second_image.mask)
            second_mask[~m1] = False
        mask = ((labels > 0) & first_mask & second_mask)
        first_pixels = first_pixels[mask]
        second_pixels = second_pixels[mask]
        labels = labels[mask]
        if len(labels) == 0:
            n_objects = 0
        else:
            n_objects = np.max(labels)
        if n_objects == 0:
            rwc1 = np.zeros((0, ))
            rwc2 = np.zeros((0, ))
        else:
            object_labels = np.unique(labels)
            rwc1 = np.zeros(np.shape(object_labels))
            rwc2 = np.zeros(np.shape(object_labels))
            for oindex in object_labels:
                fi = first_pixels[labels == oindex]
                si = second_pixels[labels == oindex]
                #corr = np.corrcoef((fi,si))[1,0]

                # Do the ranking
                au, arank = np.unique(fi, return_inverse=True)
                bu, brank = np.unique(si, return_inverse=True)

                # Reverse ranking
                amax = np.max(arank) + 1
                bmax = np.max(brank) + 1
                arank = -(arank.astype(float) - amax)
                brank = -(brank.astype(float) - bmax)

                # Measure absolute difference in ranks
                d = np.absolute(arank - brank)

                # Get the maximal ranking
                rn = np.max(np.hstack((arank, brank)))

                # Calculate weights matrix
                w = (rn - d) / rn

                # Thresholding and RWC calculations
                t = self.manual_threshold.value
                #t=0.15
                ta = t * np.max(fi)
                tb = t * np.max(si)
                a1 = np.array(fi, copy=True)
                b1 = np.array(si, copy=True)
                a1[fi <= ta] = 0
                asum = np.sum(a1)
                a1[si <= tb] = 0
                rwc1_temp = np.sum(a1.flatten() * w) / asum

                b1[si <= tb] = 0
                bsum = np.sum(b1)
                b1[fi <= ta] = 0
                rwc2_temp = np.sum(b1.flatten() * w) / bsum

                # And RWC values are...
                rwc1[oindex - 1] = rwc1_temp
                rwc2[oindex - 1] = rwc2_temp

        rwc1_measurement = ("Correlation_RWC_%s_%s" %
                            (first_image_name, second_image_name))
        rwc2_measurement = ("Correlation_RWC_%s_%s" %
                            (second_image_name, first_image_name))
        workspace.measurements.add_measurement(object_name, rwc1_measurement,
                                               rwc1)
        workspace.measurements.add_measurement(object_name, rwc2_measurement,
                                               rwc2)
        if n_objects == 0:
            return [[
                first_image_name, second_image_name, object_name,
                "Mean correlation", "-"
            ],
                    [
                        first_image_name, second_image_name, object_name,
                        "Median correlation", "-"
                    ],
                    [
                        first_image_name, second_image_name, object_name,
                        "Min correlation", "-"
                    ],
                    [
                        first_image_name, second_image_name, object_name,
                        "Max correlation", "-"
                    ]]
        else:
            return [[
                first_image_name, second_image_name, object_name,
                "Mean correlation",
                "%.2f" % np.mean(rwc1)
            ],
                    [
                        first_image_name, second_image_name, object_name,
                        "Median correlation",
                        "%.2f" % np.median(rwc1)
                    ],
                    [
                        first_image_name, second_image_name, object_name,
                        "Min correlation",
                        "%.2f" % np.min(rwc1)
                    ],
                    [
                        first_image_name, second_image_name, object_name,
                        "Max correlation",
                        "%.2f" % np.max(rwc1)
                    ]]
コード例 #30
0
 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)
     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)
             if center_choice == C_CENTERS_OF_OTHER:
                 #
                 # Reduce the propagation labels to the centers of
                 # the centering objects
                 #
                 ig = i[good]
                 jg = j[good]
                 lg = np.arange(1, len(i)+1)[good]
                 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.lexsort((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)
         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
コード例 #31
0
    def run_image_pair_objects(self, workspace, first_image_name,
                               second_image_name, object_name):
        '''Calculate per-object correlations between intensities in two images'''
        first_image = workspace.image_set.get_image(first_image_name,
                                                    must_be_grayscale=True)
        second_image = workspace.image_set.get_image(second_image_name,
                                                     must_be_grayscale=True)
        objects = workspace.object_set.get_objects(object_name)
        #
        # Crop both images to the size of the labels matrix
        #
        labels = objects.segmented
        try:
            first_pixels  = objects.crop_image_similarly(first_image.pixel_data)
            first_mask    = objects.crop_image_similarly(first_image.mask)
        except ValueError:
            first_pixels, m1 = cpo.size_similarly(labels, first_image.pixel_data)
            first_mask, m1 = cpo.size_similarly(labels, first_image.mask)
            first_mask[~m1] = False
        try:
            second_pixels = objects.crop_image_similarly(second_image.pixel_data)
            second_mask   = objects.crop_image_similarly(second_image.mask)
        except ValueError:
            second_pixels, m1 = cpo.size_similarly(labels, second_image.pixel_data)
            second_mask, m1 = cpo.size_similarly(labels, second_image.mask)
            second_mask[~m1] = False
        mask   = ((labels > 0) & first_mask & second_mask)
        first_pixels = first_pixels[mask]
        second_pixels = second_pixels[mask]
        labels = labels[mask]
        result = []
        first_pixel_data = first_image.pixel_data
        first_mask = first_image.mask
        first_pixel_count = np.product(first_pixel_data.shape)
        second_pixel_data = second_image.pixel_data
        second_mask = second_image.mask
        second_pixel_count = np.product(second_pixel_data.shape)
        #
        # Crop the larger image similarly to the smaller one
        #
        if first_pixel_count < second_pixel_count:
            second_pixel_data = first_image.crop_image_similarly(second_pixel_data)
            second_mask = first_image.crop_image_similarly(second_mask)
        elif second_pixel_count < first_pixel_count:
            first_pixel_data = second_image.crop_image_similarly(first_pixel_data)
            first_mask = second_image.crop_image_similarly(first_mask)
        mask = (first_mask & second_mask &
                (~ np.isnan(first_pixel_data)) &
                (~ np.isnan(second_pixel_data)))
        if np.any(mask):
            #
            # Perform the correlation, which returns:
            # [ [ii, ij],
            #   [ji, jj] ]
            #
            fi = first_pixel_data[mask]
            si = second_pixel_data[mask]
                            
        n_objects = objects.count
        if n_objects == 0:
            corr = np.zeros((0,))
            overlap = np.zeros((0,))
            K1 = np.zeros((0,))
            K2 = np.zeros((0,))
            M1 = np.zeros((0,))
            M2 = np.zeros((0,))
            RWC1 = np.zeros((0,))
            RWC2 = np.zeros((0,))
            C1 = np.zeros((0,))
            C2 = np.zeros((0,))
        else:
            #
            # The correlation is sum((x-mean(x))(y-mean(y)) /
            #                         ((n-1) * std(x) *std(y)))
            #
            lrange = np.arange(n_objects,dtype=np.int32)+1
            area  = fix(scind.sum(np.ones_like(labels), labels, lrange))
            mean1 = fix(scind.mean(first_pixels, labels, lrange))
            mean2 = fix(scind.mean(second_pixels, labels, lrange))
            #
            # Calculate the standard deviation times the population.
            #
            std1 = np.sqrt(fix(scind.sum((first_pixels-mean1[labels-1])**2,
                                         labels, lrange)))
            std2 = np.sqrt(fix(scind.sum((second_pixels-mean2[labels-1])**2,
                                         labels, lrange)))
            x = first_pixels - mean1[labels-1]  # x - mean(x)
            y = second_pixels - mean2[labels-1] # y - mean(y)
            corr = fix(scind.sum(x * y / (std1[labels-1] * std2[labels-1]),
                                 labels, lrange))
            # Explicitly set the correlation to NaN for masked objects
            corr[scind.sum(1, labels, lrange) == 0] = np.NaN
            result += [[first_image_name, second_image_name, object_name,"Mean Correlation coeff","%.3f"%np.mean(corr)],
                       [first_image_name, second_image_name, object_name,"Median Correlation coeff","%.3f"%np.median(corr)],
                       [first_image_name, second_image_name, object_name,"Min Correlation coeff","%.3f"%np.min(corr)],
                       [first_image_name, second_image_name, object_name,"Max Correlation coeff","%.3f"%np.max(corr)]]

            # Threshold as percentage of maximum intensity of objects in each channel
            tff = (self.thr.value/100) * fix(scind.maximum(first_pixels,labels, lrange))
            tss = (self.thr.value/100) * fix(scind.maximum(second_pixels,labels, lrange))
        
            combined_thresh = (first_pixels> tff[labels-1]) & (second_pixels > tss[labels-1])
            fi_thresh = first_pixels[combined_thresh]
            si_thresh = second_pixels[combined_thresh]
            tot_fi_thr = scind.sum(first_pixels[first_pixels > tff[labels-1]], labels[first_pixels > tff[labels-1]],lrange)
            tot_si_thr = scind.sum(second_pixels[second_pixels > tss[labels-1]], labels[second_pixels > tss[labels-1]],lrange)
            
            
            nonZero = (fi > 0) | (si > 0)
            xvar = np.var(fi[nonZero],axis=0,ddof=1)
            yvar = np.var(si[nonZero],axis=0,ddof=1)
            
            xmean = np.mean(fi[nonZero], axis=0)
            ymean = np.mean(si[nonZero], axis=0)
            
            z = fi[nonZero] + si[nonZero]
            zvar = np.var(z,axis=0,ddof=1)
            
            covar = 0.5 * (zvar - (xvar+yvar))
            
            denom = 2 * covar
            num = (yvar-xvar) + np.sqrt((yvar-xvar)*(yvar-xvar)+4*(covar*covar))
            a = (num/denom)
            b = (ymean - a*xmean)
            
            i = 1
            while(i > 0.003921568627):
                thr_fi_c = i
                thr_si_c = (a*i)+b
                combt = (fi < thr_fi_c) | (si < thr_si_c)
                costReg = scistat.pearsonr(fi[combt], si[combt])
                if(costReg[0] <= 0):
                    break
                i= i-0.003921568627
            
            # Costes' thershold for entire image is applied to each object
            fi_above_thr = first_pixels > thr_fi_c
            si_above_thr = second_pixels > thr_si_c
            combined_thresh_c = fi_above_thr & si_above_thr
            fi_thresh_c = first_pixels[combined_thresh_c]
            si_thresh_c = second_pixels[combined_thresh_c]
            if np.any(fi_above_thr):
                tot_fi_thr_c = scind.sum(first_pixels[first_pixels > thr_fi_c],labels[first_pixels > thr_fi_c],lrange)
            else:
                tot_fi_thr_c = np.zeros(len(lrange))
            if np.any(si_above_thr):
                tot_si_thr_c = scind.sum(second_pixels[second_pixels > thr_si_c],labels[second_pixels > thr_si_c],lrange)
            else:
                tot_si_thr_c = np.zeros(len(lrange))
            
            # Manders Coefficient
            M1 = np.zeros(len(lrange))
            M2 = np.zeros(len(lrange))
            
            if np.any(combined_thresh):
                M1 = np.array(scind.sum(fi_thresh,labels[combined_thresh],lrange)) / np.array(tot_fi_thr)
                M2 = np.array(scind.sum(si_thresh,labels[combined_thresh],lrange)) / np.array(tot_si_thr)
            result += [[first_image_name, second_image_name, object_name,"Mean Manders coeff","%.3f"%np.mean(M1)],
                       [first_image_name, second_image_name, object_name,"Median Manders coeff","%.3f"%np.median(M1)],
                       [first_image_name, second_image_name, object_name,"Min Manders coeff","%.3f"%np.min(M1)],
                       [first_image_name, second_image_name, object_name,"Max Manders coeff","%.3f"%np.max(M1)]]
            result += [[second_image_name, first_image_name, object_name,"Mean Manders coeff","%.3f"%np.mean(M2)],
                       [second_image_name, first_image_name, object_name,"Median Manders coeff","%.3f"%np.median(M2)],
                       [second_image_name, first_image_name, object_name,"Min Manders coeff","%.3f"%np.min(M2)],
                       [second_image_name, first_image_name, object_name,"Max Manders coeff","%.3f"%np.max(M2)]]
            
            # RWC Coefficient
            RWC1 = np.zeros(len(lrange))
            RWC2 = np.zeros(len(lrange))
            [Rank1] = np.lexsort(([labels], [first_pixels]))
            [Rank2] = np.lexsort(([labels], [second_pixels]))
            Rank1_U = np.hstack([[False],first_pixels[Rank1[:-1]] != first_pixels[Rank1[1:]]])
            Rank2_U = np.hstack([[False],second_pixels[Rank2[:-1]] != second_pixels[Rank2[1:]]])
            Rank1_S = np.cumsum(Rank1_U)
            Rank2_S = np.cumsum(Rank2_U)
            Rank_im1 = np.zeros(first_pixels.shape, dtype=int)
            Rank_im2 = np.zeros(second_pixels.shape, dtype=int)
            Rank_im1[Rank1] = Rank1_S
            Rank_im2[Rank2] = Rank2_S
            
            R = max(Rank_im1.max(), Rank_im2.max()) + 1
            Di = abs(Rank_im1 - Rank_im2)
            weight = (R-Di) * 1.0 / R
            weight_thresh = weight[combined_thresh]
            if np.any(combined_thresh_c):
                RWC1 = np.array(scind.sum(fi_thresh * weight_thresh,labels[combined_thresh],lrange)) / np.array(tot_fi_thr)
                RWC2 = np.array(scind.sum(si_thresh * weight_thresh,labels[combined_thresh],lrange)) / np.array(tot_si_thr)
                
            result += [[first_image_name, second_image_name, object_name,"Mean RWC coeff","%.3f"%np.mean(RWC1)],
                       [first_image_name, second_image_name, object_name,"Median RWC coeff","%.3f"%np.median(RWC1)],
                       [first_image_name, second_image_name, object_name,"Min RWC coeff","%.3f"%np.min(RWC1)],
                       [first_image_name, second_image_name, object_name,"Max RWC coeff","%.3f"%np.max(RWC1)]]
            result += [[second_image_name, first_image_name, object_name,"Mean RWC coeff","%.3f"%np.mean(RWC2)],
                       [second_image_name, first_image_name, object_name,"Median RWC coeff","%.3f"%np.median(RWC2)],
                       [second_image_name, first_image_name, object_name,"Min RWC coeff","%.3f"%np.min(RWC2)],
                       [second_image_name, first_image_name, object_name,"Max RWC coeff","%.3f"%np.max(RWC2)]]
            
            
            #Costes Automated Threshold
            C1 = np.zeros(len(lrange))
            C2 = np.zeros(len(lrange))
            if np.any(combined_thresh_c):
                C1 = np.array(scind.sum(fi_thresh_c,labels[combined_thresh_c],lrange)) / np.array(tot_fi_thr_c)
                C2 = np.array(scind.sum(si_thresh_c,labels[combined_thresh_c],lrange)) / np.array(tot_si_thr_c)
            result += [[first_image_name, second_image_name, object_name,"Mean Manders coeff (Costes)","%.3f"%np.mean(C1)],
                       [first_image_name, second_image_name, object_name,"Median Manders coeff (Costes)","%.3f"%np.median(C1)],
                       [first_image_name, second_image_name, object_name,"Min Manders coeff (Costes)","%.3f"%np.min(C1)],
                       [first_image_name, second_image_name, object_name,"Max Manders coeff (Costes)","%.3f"%np.max(C1)]
                       ]
            result += [[second_image_name, first_image_name, object_name,"Mean Manders coeff (Costes)","%.3f"%np.mean(C2)],
                       [second_image_name, first_image_name, object_name,"Median Manders coeff (Costes)","%.3f"%np.median(C2)],
                       [second_image_name, first_image_name, object_name,"Min Manders coeff (Costes)","%.3f"%np.min(C2)],
                       [second_image_name, first_image_name, object_name,"Max Manders coeff (Costes)","%.3f"%np.max(C2)]
                       ]
            
            
            # Overlap Coefficient
            fpsq = scind.sum(first_pixels[combined_thresh]**2,labels[combined_thresh],lrange)
            spsq = scind.sum(second_pixels[combined_thresh]**2,labels[combined_thresh],lrange)
            pdt = np.sqrt(np.array(fpsq) * np.array(spsq))
            
            if np.any(combined_thresh):
                overlap = fix(scind.sum(first_pixels[combined_thresh] * second_pixels[combined_thresh], labels[combined_thresh], lrange) / pdt)
                K1 = fix((scind.sum(first_pixels[combined_thresh] * second_pixels[combined_thresh], labels[combined_thresh], lrange)) / (np.array(fpsq)))
                K2 = fix(scind.sum(first_pixels[combined_thresh] * second_pixels[combined_thresh], labels[combined_thresh], lrange) / np.array(spsq))
            else:
                overlap = K1 = K2 = np.zeros(len(lrange))
            result += [[first_image_name, second_image_name, object_name,"Mean Overlap coeff","%.3f"%np.mean(overlap)],
                       [first_image_name, second_image_name, object_name,"Median Overlap coeff","%.3f"%np.median(overlap)],
                       [first_image_name, second_image_name, object_name,"Min Overlap coeff","%.3f"%np.min(overlap)],
                       [first_image_name, second_image_name, object_name,"Max Overlap coeff","%.3f"%np.max(overlap)]]

        measurement = ("Correlation_Correlation_%s_%s" %
                       (first_image_name, second_image_name))
        overlap_measurement = (F_OVERLAP_FORMAT%(first_image_name,
                                                 second_image_name))
        k_measurement_1 = (F_K_FORMAT%(first_image_name,
                                       second_image_name))
        k_measurement_2 = (F_K_FORMAT%(second_image_name,
                                       first_image_name))
        manders_measurement_1 = (F_MANDERS_FORMAT%(first_image_name,
                                                   second_image_name))
        manders_measurement_2 = (F_MANDERS_FORMAT%(second_image_name,
                                                   first_image_name))
        rwc_measurement_1 = (F_RWC_FORMAT%(first_image_name,
                                           second_image_name))
        rwc_measurement_2 = (F_RWC_FORMAT%(second_image_name,
                                           first_image_name))
        costes_measurement_1 = (F_COSTES_FORMAT%(first_image_name,
                                                 second_image_name))
        costes_measurement_2 = (F_COSTES_FORMAT%(second_image_name,
                                                 first_image_name))
        
        workspace.measurements.add_measurement(object_name, measurement, corr)
        workspace.measurements.add_measurement(object_name,overlap_measurement, overlap)
        workspace.measurements.add_measurement(object_name,k_measurement_1, K1)
        workspace.measurements.add_measurement(object_name,k_measurement_2, K2)
        workspace.measurements.add_measurement(object_name,manders_measurement_1, M1)
        workspace.measurements.add_measurement(object_name,manders_measurement_2, M2)
        workspace.measurements.add_measurement(object_name,rwc_measurement_1, RWC1)
        workspace.measurements.add_measurement(object_name,rwc_measurement_2, RWC2)
        workspace.measurements.add_measurement(object_name,costes_measurement_1, C1)
        workspace.measurements.add_measurement(object_name,costes_measurement_2, C2)
        
        if n_objects == 0:
            return [[first_image_name, second_image_name, object_name,
                     "Mean correlation","-"],
                    [first_image_name, second_image_name, object_name,
                     "Median correlation","-"],
                    [first_image_name, second_image_name, object_name,
                     "Min correlation","-"],
                    [first_image_name, second_image_name, object_name,
                     "Max correlation","-"]]
        else:
            return result
コード例 #32
0
 def run(self, workspace):
     '''Run the module on an image set'''
     
     object_name = self.object_name.value
     remaining_object_name = self.remaining_objects.value
     original_objects = workspace.object_set.get_objects(object_name)
     
     if self.mask_choice == MC_IMAGE:
         mask = workspace.image_set.get_image(self.masking_image.value,
                                              must_be_binary = True)
         mask = mask.pixel_data
     else:
         masking_objects = workspace.object_set.get_objects(
             self.masking_objects.value)
         mask = masking_objects.segmented > 0
     if self.wants_inverted_mask:
         mask = ~mask
     #
     # Load the labels
     #
     labels = original_objects.segmented.copy()
     nobjects = np.max(labels)
     #
     # Resize the mask to cover the objects
     #
     mask, m1 = cpo.size_similarly(labels, mask)
     mask[~m1] = False
     #
     # Apply the mask according to the overlap choice.
     #
     if nobjects == 0:
         pass
     elif self.overlap_choice == P_MASK:
         labels = labels * mask
     else:
         pixel_counts = fix(scind.sum(mask, labels, 
                                      np.arange(1, nobjects+1,dtype=np.int32)))
         if self.overlap_choice == P_KEEP:
             keep = pixel_counts > 0
         else:
             total_pixels = fix(scind.sum(np.ones(labels.shape), labels,
                                          np.arange(1, nobjects+1,dtype=np.int32)))
             if self.overlap_choice == P_REMOVE:
                 keep = pixel_counts == total_pixels
             elif self.overlap_choice == P_REMOVE_PERCENTAGE:
                 fraction = self.overlap_fraction.value
                 keep = pixel_counts / total_pixels >= fraction
             else:
                 raise NotImplementedError("Unknown overlap-handling choice: %s",
                                           self.overlap_choice.value)
         keep = np.hstack(([False], keep))
         labels[~ keep[labels]] = 0
     #
     # Renumber the labels matrix if requested
     #
     if self.retain_or_renumber == R_RENUMBER:
         unique_labels = np.unique(labels[labels!=0])
         indexer = np.zeros(nobjects+1, int)
         indexer[unique_labels] = np.arange(1, len(unique_labels)+1)
         labels = indexer[labels]
         parent_objects = unique_labels
     else:
         parent_objects = np.arange(1, nobjects+1)
     #
     # Add the objects
     #
     remaining_objects = cpo.Objects()
     remaining_objects.segmented = labels
     remaining_objects.unedited_segmented = original_objects.unedited_segmented
     workspace.object_set.add_objects(remaining_objects, 
                                      remaining_object_name)
     #
     # Add measurements
     #
     m = workspace.measurements
     m.add_measurement(remaining_object_name,
                       I.FF_PARENT % object_name,
                       parent_objects)
     if np.max(original_objects.segmented) == 0:
         child_count = np.array([],int)
     else:
         child_count = fix(scind.sum(labels, original_objects.segmented,
                                     np.arange(1, nobjects+1,dtype=np.int32)))
         child_count = (child_count > 0).astype(int)
     m.add_measurement(object_name,
                       I.FF_CHILDREN_COUNT % remaining_object_name,
                       child_count)
     if self.retain_or_renumber == R_RETAIN:
         remaining_object_count = nobjects
     else:
         remaining_object_count = len(unique_labels)
     I.add_object_count_measurements(m, remaining_object_name,
                                     remaining_object_count)
     I.add_object_location_measurements(m, remaining_object_name, labels)
     #
     # Add an outline if asked to do so
     #
     if self.wants_outlines.value:
         outline_image = cpi.Image(outline(labels) > 0,
                                   parent_image = original_objects.parent_image)
         workspace.image_set.add(self.outlines_name.value, outline_image)
     #
     # Save the input, mask and output images for display
     #
     if self.show_window:
         workspace.display_data.original_labels = original_objects.segmented
         workspace.display_data.final_labels = labels
         workspace.display_data.mask = mask
コード例 #33
0
 def do_measurements(self, workspace, image_name, object_name, 
                     center_object_name, bin_count,
                     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.
     bin_count - bin the object into this many concentric rings
     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)
     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)
     if nobjects == 0:
         for bin in range(1, bin_count+1):
             for feature in (FF_FRAC_AT_D, FF_MEAN_FRAC, FF_RADIAL_CV):
                 measurements.add_measurement(object_name,
                                              M_CATEGORY + "_" + feature % 
                                              (image_name, bin, bin_count),
                                              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:
             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]
             center_labels = np.zeros(center_labels.shape, int)
             center_labels[ig,jg] = labels[ig,jg] ## TODO: This is incorrect when objects are annular.  Retrieves label# = 0
             cl,d_from_center = propagate(np.zeros(center_labels.shape),
                                          center_labels,
                                          labels != 0, 1)
         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
         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)
         total_distance = d_from_center + d_to_edge
         normalized_distance[good_mask] = (d_from_center[good_mask] /
                                           (total_distance[good_mask] + .001))
         dd[name] = [normalized_distance, i_center, j_center, good_mask]
     ngood_pixels = np.sum(good_mask)
     good_labels = objects.segmented[good_mask]
     bin_indexes = (normalized_distance * bin_count).astype(int)
     labels_and_bins = (good_labels-1,bin_indexes[good_mask])
     histogram = coo_matrix((image.pixel_data[good_mask], labels_and_bins),
                            (nobjects, bin_count)).toarray()
     sum_by_object = np.sum(histogram, 1)
     sum_by_object_per_bin = np.dstack([sum_by_object]*bin_count)[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)).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)[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):
         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 in ((fraction_at_distance[:,bin], MF_FRAC_AT_D),
                                      (mean_pixel_fraction[:,bin], MF_MEAN_FRAC),
                                      (np.array(radial_cv), MF_RADIAL_CV)):
                                      
             measurements.add_measurement(object_name,
                                          feature % 
                                          (image_name, bin+1, bin_count),
                                          measurement)
         radial_cv.mask = np.sum(~mask,1)==0
         statistics += [(image_name, object_name, str(bin+1), 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