Beispiel #1
0
    def display(self, workspace, figure):
        orig_pixels = workspace.display_data.orig_pixels
        output_pixels = workspace.display_data.output_pixels

        figure.set_subplots((2, 2))
        figure.subplot_imshow_grayscale(0, 0, orig_pixels,
                                        "Original: %s" % self.image_name.value)
        if self.method == M_CANNY:
            # Canny is binary
            figure.subplot_imshow_bw(0,
                                     1,
                                     output_pixels,
                                     self.output_image_name.value,
                                     sharexy=figure.subplot(0, 0))
        else:
            figure.subplot_imshow_grayscale(0,
                                            1,
                                            output_pixels,
                                            self.output_image_name.value,
                                            sharexy=figure.subplot(0, 0))
        color_image = np.zeros(
            (output_pixels.shape[0], output_pixels.shape[1], 3))
        color_image[:, :, 0] = stretch(orig_pixels)
        color_image[:, :, 1] = stretch(output_pixels)
        figure.subplot_imshow(1,
                              0,
                              color_image,
                              "Composite image",
                              sharexy=figure.subplot(0, 0))
Beispiel #2
0
    def display(self, workspace, figure):
        '''Display the results of relabeling
        
        workspace - workspace containing saved display data
        '''
        from cellprofiler.gui.cpfigure import renumber_labels_for_display
        import matplotlib.cm as cm

        figure.set_subplots((1, 2))
        figure.subplot_imshow_labels(0,
                                     0,
                                     workspace.display_data.orig_labels,
                                     title=self.objects_name.value)

        output_labels = renumber_labels_for_display(
            workspace.display_data.output_labels)
        if self.relabel_option == OPTION_UNIFY and (
            (self.unify_option == UNIFY_DISTANCE and self.wants_image) or
            (self.unify_option == UNIFY_PARENT)):
            if self.unify_option == UNIFY_DISTANCE and self.wants_image:
                #
                # Make a nice picture which superimposes the labels on the
                # guiding image
                #
                image = (stretch(workspace.display_data.image) * 255).astype(
                    np.uint8)
            elif self.unify_option == UNIFY_PARENT:
                parent_objects = workspace.object_set.get_objects(
                    self.parent_object.value)
                labels = parent_objects.segmented
                image = labels.astype(float) / (1.0 if np.max(labels) == 0 else
                                                np.max(labels))
                image = (stretch(image) * 255).astype(np.uint8)

            image = np.dstack((image, image, image))
            my_cm = cm.get_cmap(cpprefs.get_default_colormap())
            my_cm.set_bad((0, 0, 0))
            sm = cm.ScalarMappable(cmap=my_cm)
            m_output_labels = np.ma.array(output_labels,
                                          mask=output_labels == 0)
            output_image = sm.to_rgba(m_output_labels, bytes=True)[:, :, :3]
            image[output_labels > 0] = (image[output_labels > 0] / 4 * 3 +
                                        output_image[output_labels > 0, :] / 4)

            figure.subplot_imshow(0,
                                  1,
                                  image,
                                  title=self.output_objects_name.value,
                                  sharexy=figure.subplot(0, 0))
        else:
            figure.subplot_imshow_labels(0,
                                         1,
                                         workspace.display_data.output_labels,
                                         title=self.output_objects_name.value,
                                         sharexy=figure.subplot(0, 0))
    def display(self, workspace):
        """Display the results of relabeling
        
        workspace - workspace containing saved display data
        """
        from cellprofiler.gui.cpfigure import renumber_labels_for_display
        import matplotlib.cm as cm

        figure = workspace.create_or_find_figure(
            title="ReassignObjectNumbers, image cycle #%d" % (workspace.measurements.image_set_number), subplots=(1, 2)
        )
        figure.subplot_imshow_labels(0, 0, workspace.display_data.orig_labels, title=self.objects_name.value)

        output_labels = renumber_labels_for_display(workspace.display_data.output_labels)
        if self.relabel_option == OPTION_UNIFY:
            if self.unify_option == UNIFY_DISTANCE and self.wants_image:
                #
                # Make a nice picture which superimposes the labels on the
                # guiding image
                #
                image = (stretch(workspace.display_data.image) * 255).astype(np.uint8)
            elif self.unify_option == UNIFY_PARENT:
                parent_objects = workspace.object_set.get_objects(self.parent_object.value)
                labels = parent_objects.segmented
                image = labels.astype(float) / (1.0 if np.max(labels) == 0 else np.max(labels))
                image = (stretch(image) * 255).astype(np.uint8)

            image = np.dstack((image, image, image))
            my_cm = cm.get_cmap(cpprefs.get_default_colormap())
            my_cm.set_bad((0, 0, 0))
            sm = cm.ScalarMappable(cmap=my_cm)
            m_output_labels = np.ma.array(output_labels, mask=output_labels == 0)
            output_image = sm.to_rgba(m_output_labels, bytes=True)[:, :, :3]
            image[output_labels > 0] = image[output_labels > 0] / 4 * 3 + output_image[output_labels > 0, :] / 4

            figure.subplot_imshow(
                0,
                1,
                image,
                title=self.output_objects_name.value,
                sharex=figure.subplot(0, 0),
                sharey=figure.subplot(0, 0),
            )
        else:
            figure.subplot_imshow_labels(
                0,
                1,
                workspace.display_data.output_labels,
                title=self.output_objects_name.value,
                sharex=figure.subplot(0, 0),
                sharey=figure.subplot(0, 0),
            )
 def display(self, workspace):
     '''Display the results of relabeling
     
     workspace - workspace containing saved display data
     '''
     from cellprofiler.gui.cpfigure import renumber_labels_for_display
     import matplotlib.cm as cm
     
     figure = workspace.create_or_find_figure(title="UnifyObjectsByShape, image cycle #%d"%(
             workspace.measurements.image_set_number),subplots=(1,2))
     figure.subplot_imshow_labels(0,0, workspace.display_data.orig_labels,
                                  title = self.objects_name.value)
     
     output_labels = renumber_labels_for_display(
             workspace.display_data.output_labels)
     objects = workspace.object_set.get_objects(self.objects_name.value)
     labels = objects.segmented
     image = labels.astype(float) / (1.0 if np.max(labels) == 0 else np.max(labels))
     image = (stretch(image) * 255).astype(np.uint8)  
     
     image = np.dstack((image,image,image))
     my_cm = cm.get_cmap(cpprefs.get_default_colormap())
     my_cm.set_bad((0,0,0))
     sm = cm.ScalarMappable(cmap=my_cm)
     m_output_labels = np.ma.array(output_labels,
                                 mask = output_labels == 0)
     output_image = sm.to_rgba(m_output_labels, bytes=True)[:,:,:3]
     image[output_labels > 0 ] = (
         image[output_labels > 0] / 4 * 3 +
         output_image[output_labels > 0,:] / 4)
 
     figure.subplot_imshow(0,1, image,
                           title = self.output_objects_name.value,
                           sharex = figure.subplot(0,0),
                           sharey = figure.subplot(0,0))
Beispiel #5
0
    def display(self, workspace, figure):
        orig_pixels = workspace.display_data.orig_pixels
        output_pixels = workspace.display_data.output_pixels

        figure.set_subplots((2, 2))
        figure.subplot_imshow_grayscale(0, 0, orig_pixels, "Original: %s" % self.image_name.value)
        if self.method == M_CANNY:
            # Canny is binary
            figure.subplot_imshow_bw(0, 1, output_pixels, self.output_image_name.value, sharexy=figure.subplot(0, 0))
        else:
            figure.subplot_imshow_grayscale(
                0, 1, output_pixels, self.output_image_name.value, sharexy=figure.subplot(0, 0)
            )
        color_image = np.zeros((output_pixels.shape[0], output_pixels.shape[1], 3))
        color_image[:, :, 0] = stretch(orig_pixels)
        color_image[:, :, 1] = stretch(output_pixels)
        figure.subplot_imshow(1, 0, color_image, "Composite image", sharexy=figure.subplot(0, 0))
    def display(self, workspace, figure):
        from identify import TS_BINARY_IMAGE
        
        object_pct = workspace.display_data.object_pct
        img = workspace.display_data.img
        primary_outline = workspace.display_data.primary_outline
        secondary_outline = workspace.display_data.secondary_outline
        segmented_out = workspace.display_data.segmented_out
        global_threshold = workspace.display_data.global_threshold
        object_count = workspace.display_data.object_count
        statistics = workspace.display_data.statistics
        
        if global_threshold is not None:
            statistics.append(["Threshold","%.3f" % global_threshold])

        if object_count > 0:
            areas = scind.sum(np.ones(segmented_out.shape), segmented_out, np.arange(1, object_count + 1))
            areas.sort()
            low_diameter  = (np.sqrt(float(areas[object_count / 10]) / np.pi) * 2)
            median_diameter = (np.sqrt(float(areas[object_count / 2]) / np.pi) * 2)
            high_diameter = (np.sqrt(float(areas[object_count * 9 / 10]) / np.pi) * 2)
            statistics.append(["10th pctile diameter",
                               "%.1f pixels" % (low_diameter)])
            statistics.append(["Median diameter",
                               "%.1f pixels" % (median_diameter)])
            statistics.append(["90th pctile diameter",
                               "%.1f pixels" % (high_diameter)])
            if self.method != M_DISTANCE_N and self.threshold_scope != TS_BINARY_IMAGE:
                statistics.append(["Thresholding filter size",
                                "%.1f"%(workspace.display_data.threshold_sigma)])            
            statistics.append(["Area covered by objects", "%.1f %%" % object_pct])
        workspace.display_data.statistics = statistics
        
        figure.set_subplots((2, 2))
        title = "Input image, cycle #%d" % (workspace.measurements.image_number)
        figure.subplot_imshow_grayscale(0, 0, img, title)
        figure.subplot_imshow_labels(1, 0, segmented_out, "%s objects" % self.objects_name.value,
                                       sharexy = figure.subplot(0, 0))

        primary_img = np.dstack((img, img, img))
        #
        # Stretch the outline image to the full scale
        #
        primary_img = stretch(primary_img)        
        # Outline the primary objects
        cpmi.draw_outline(primary_img, primary_outline > 0,
                          cpprefs.get_primary_outline_color())
        # Outline the secondary objects
        cpmi.draw_outline(primary_img, secondary_outline > 0,
                          cpprefs.get_secondary_outline_color())
        figure.subplot_imshow(0, 1, primary_img,
                                "%s and %s outlines"%(self.primary_objects.value,self.objects_name.value),
                                normalize=False,
                                sharexy = figure.subplot(0, 0))
        figure.subplot_table(
            1, 1, 
            [[x[1]] for x in workspace.display_data.statistics],
            row_labels = [x[0] for x in workspace.display_data.statistics])        
Beispiel #7
0
def entropy2(x,y):
    '''Joint entropy of paired samples X and Y'''
    #
    # Bin each image into 256 gray levels
    #
    x = (stretch(x) * 255).astype(int)
    y = (stretch(y) * 255).astype(int)
    #
    # create an image where each pixel with the same X & Y gets
    # the same value
    #
    xy = 256*x+y
    xy = xy.flatten()
    sparse = scipy.sparse.coo_matrix((np.ones(xy.shape), 
                                      (xy,np.zeros(xy.shape))))
    histogram = sparse.toarray()
    n=np.sum(histogram)
    if n > 0 and np.max(histogram) > 0:
        histogram = histogram[histogram>0]
        return np.log2(n) - np.sum(histogram * np.log2(histogram)) / n
    else:
        return 0
Beispiel #8
0
    def display(self, workspace):
        '''Display the results of relabeling
        
        workspace - workspace containing saved display data
        '''
        from cellprofiler.gui.cpfigure import renumber_labels_for_display
        import matplotlib.cm as cm

        figure = workspace.create_or_find_figure(
            title="ReassignObjectNumbers, image cycle #%d" %
            (workspace.measurements.image_set_number),
            subplots=(1, 2))
        figure.subplot_imshow_labels(0,
                                     0,
                                     workspace.display_data.orig_labels,
                                     title=self.objects_name.value)
        if self.wants_image:
            #
            # Make a nice picture which superimposes the labels on the
            # guiding image
            #
            output_labels = renumber_labels_for_display(
                workspace.display_data.output_labels)
            image = (stretch(workspace.display_data.image) * 255).astype(
                np.uint8)
            image = np.dstack((image, image, image))
            my_cm = cm.get_cmap(cpprefs.get_default_colormap())
            my_cm.set_bad((0, 0, 0))
            sm = cm.ScalarMappable(cmap=my_cm)
            m_output_labels = np.ma.array(output_labels,
                                          mask=output_labels == 0)
            output_image = sm.to_rgba(m_output_labels, bytes=True)[:, :, :3]
            image[output_labels > 0] = (image[output_labels > 0] / 4 * 3 +
                                        output_image[output_labels > 0, :] / 4)
            figure.subplot_imshow(0,
                                  1,
                                  image,
                                  title=self.output_objects_name.value,
                                  sharex=figure.subplot(0, 0),
                                  sharey=figure.subplot(0, 0))
        else:
            figure.subplot_imshow_labels(0,
                                         1,
                                         workspace.display_data.output_labels,
                                         title=self.output_objects_name.value,
                                         sharex=figure.subplot(0, 0),
                                         sharey=figure.subplot(0, 0))
Beispiel #9
0
 def on_file_open(self, event):
     dlg = wx.FileDialog(self.frame, style=wx.FD_OPEN)
     if dlg.ShowModal() == wx.ID_OK:
         img = pil_to_array(
             PILImage.open(
                 os.path.join(dlg.GetDirectory(), dlg.GetFilename())))
         if img.ndim == 3:
             img = img[:, :, 0] + img[:, :, 1] + img[:, :, 2]
         img = stretch(img.astype(float))
         lt = self.frame.MenuBar.Menus[0][0].MenuItems[7].IsChecked()
         if lt:
             limg, d = log_transform(img)
         else:
             limg = img
         self.frame.subplot_imshow_grayscale(0, 0, limg)
         limg = limg.flatten()
         menu_items = self.frame.MenuBar.Menus[0][0].MenuItems
         if menu_items[2].IsChecked():
             t1 = t2 = otsu(limg)
         elif menu_items[3].IsChecked():
             t1 = t2 = entropy(limg)
         elif menu_items[4].IsChecked():
             t1, t2 = otsu3slow(limg)
         elif menu_items[5].IsChecked():
             t1, t2 = entropy3(limg)
         else:
             t1, t2 = otsu3(limg)
         if lt:
             t1, t2 = inverse_log_transform(np.array([t1, t2]), d)
         m1 = img < t1
         m2 = np.logical_and(img >= t1, img < t2)
         m3 = img > t2
         cimg = np.zeros((m1.shape[0], m1.shape[1], 3))
         cimg[:, :, 0][m1] = img[m1]
         cimg[:, :, 1][m2] = img[m2]
         cimg[:, :, 2][m3] = img[m3]
         self.frame.subplot_imshow(1,
                                   0,
                                   cimg,
                                   sharex=self.frame.subplot(0, 0),
                                   sharey=self.frame.subplot(0, 0))
         self.frame.Refresh()
         wx.MessageBox("Low threshold = %f, high threshold = %f" %
                       (t1, t2),
                       parent=self.frame)
 def test_05_02_otsu_entropy(self):
     '''Test the entropy version of Otsu'''
     np.random.seed(0)
     image = np.hstack((np.random.exponential(1.5,size=600),
                        np.random.poisson(15,size=300)))
     image.shape=(30,30)
     image = stretch(image)
     limage, d = T.log_transform(image)
     threshold = entropy(limage)
     threshold = T.inverse_log_transform(threshold, d)
     expected = image > threshold
     workspace, module = self.make_workspace(image)
     module.binary.value = A.BINARY
     module.threshold_method.value = T.TM_OTSU_GLOBAL
     module.use_weighted_variance.value = I.O_ENTROPY
     module.two_class_otsu.value = I.O_TWO_CLASS
     module.run(workspace)
     output = workspace.image_set.get_image(OUTPUT_IMAGE_NAME)
     self.assertTrue(np.all(output.pixel_data == expected))
Beispiel #11
0
 def run_image_gabor(self, image_name, scale, workspace):
     image = workspace.image_set.get_image(image_name,
                                           must_be_grayscale=True)
     pixel_data = image.pixel_data
     labels = np.ones(pixel_data.shape, int)
     if image.has_mask:
         labels[~image.mask] = 0
     pixel_data = stretch(pixel_data, labels > 0)
     best_score = 0
     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 = np.sum(g.real)
         score_i = np.sum(g.imag)
         score = np.sqrt(score_r**2 + score_i**2)
         best_score = max(best_score, score)
     statistics = self.record_image_measurement(workspace, image_name,
                                                scale, F_GABOR, best_score)
     return statistics
Beispiel #12
0
 def test_05_02_otsu_entropy(self):
     '''Test the entropy version of Otsu'''
     np.random.seed(0)
     image = np.hstack((np.random.exponential(1.5,size=600),
                        np.random.poisson(15,size=300)))
     image.shape=(30,30)
     image = stretch(image)
     limage, d = T.log_transform(image)
     threshold = entropy(limage)
     threshold = T.inverse_log_transform(threshold, d)
     expected = image > threshold
     workspace, module = self.make_workspace(image)
     module.binary.value = A.BINARY
     module.threshold_method.value = T.TM_OTSU_GLOBAL
     module.use_weighted_variance.value = I.O_ENTROPY
     module.two_class_otsu.value = I.O_TWO_CLASS
     module.run(workspace)
     output = workspace.image_set.get_image(OUTPUT_IMAGE_NAME)
     self.assertTrue(np.all(output.pixel_data == expected))
 def test_05_06_otsu3_entropy_high(self):
     '''Test the three-class otsu, entropy, middle = background'''
     np.random.seed(0)
     image = np.hstack((np.random.exponential(1.5,size=300),
                        np.random.poisson(15,size=300),
                        np.random.poisson(30,size=300)))
     image.shape=(30,30)
     image = stretch(image)
     limage, d = T.log_transform(image)
     t1,t2 = entropy3(limage)
     threshold = T.inverse_log_transform(t1, d)
     expected = image > threshold
     workspace, module = self.make_workspace(image)
     module.binary.value = A.BINARY
     module.threshold_method.value = T.TM_OTSU_GLOBAL
     module.use_weighted_variance.value = I.O_ENTROPY
     module.two_class_otsu.value = I.O_THREE_CLASS
     module.assign_middle_to_foreground.value = I.O_FOREGROUND
     module.run(workspace)
     output = workspace.image_set.get_image(OUTPUT_IMAGE_NAME)
     self.assertTrue(np.all(output.pixel_data == expected))
Beispiel #14
0
 def test_05_06_otsu3_entropy_high(self):
     '''Test the three-class otsu, entropy, middle = background'''
     np.random.seed(0)
     image = np.hstack(
         (np.random.exponential(1.5, size=300),
          np.random.poisson(15, size=300), np.random.poisson(30, size=300)))
     image.shape = (30, 30)
     image = stretch(image)
     limage, d = T.log_transform(image)
     t1, t2 = entropy3(limage)
     threshold = T.inverse_log_transform(t1, d)
     expected = image > threshold
     workspace, module = self.make_workspace(image)
     module.binary.value = A.BINARY
     module.threshold_method.value = T.TM_OTSU_GLOBAL
     module.use_weighted_variance.value = I.O_ENTROPY
     module.two_class_otsu.value = I.O_THREE_CLASS
     module.assign_middle_to_foreground.value = I.O_FOREGROUND
     module.run(workspace)
     output = workspace.image_set.get_image(OUTPUT_IMAGE_NAME)
     self.assertTrue(np.all(output.pixel_data == expected))
Beispiel #15
0
def log_transform(image):
    '''Renormalize image intensities to log space
    
    Returns a tuple of transformed image and a dictionary to be passed into
    inverse_log_transform. The minimum and maximum from the dictionary
    can be applied to an image by the inverse_log_transform to 
    convert it back to its former intensity values.
    '''
    orig_min, orig_max = scipy.ndimage.extrema(image)[:2]
    #
    # We add 1/2 bit noise to an 8 bit image to give the log a bottom
    #
    limage = image.copy()
    noise_min = orig_min + (orig_max-orig_min)/256.0+np.finfo(image.dtype).eps
    limage[limage < noise_min] = noise_min
    d = { "noise_min":noise_min}
    limage = np.log(limage)
    log_min, log_max = scipy.ndimage.extrema(limage)[:2]
    d["log_min"] = log_min
    d["log_max"] = log_max
    return stretch(limage), d
Beispiel #16
0
def log_transform(image):
    '''Renormalize image intensities to log space
    
    Returns a tuple of transformed image and a dictionary to be passed into
    inverse_log_transform. The minimum and maximum from the dictionary
    can be applied to an image by the inverse_log_transform to 
    convert it back to its former intensity values.
    '''
    orig_min, orig_max = scipy.ndimage.extrema(image)[:2]
    #
    # We add 1/2 bit noise to an 8 bit image to give the log a bottom
    #
    limage = image.copy()
    noise_min = orig_min + (orig_max-orig_min)/256.0+np.finfo(image.dtype).eps
    limage[limage < noise_min] = noise_min
    d = { "noise_min":noise_min}
    limage = np.log(limage)
    log_min, log_max = scipy.ndimage.extrema(limage)[:2]
    d["log_min"] = log_min
    d["log_max"] = log_max
    return stretch(limage), d
Beispiel #17
0
 def on_file_open(self, event):
     dlg = wx.FileDialog(self.frame,style=wx.FD_OPEN)
     if dlg.ShowModal() == wx.ID_OK:
         img = pil_to_array(PILImage.open(os.path.join(dlg.GetDirectory(),dlg.GetFilename())))
         if img.ndim == 3:
             img = img[:,:,0]+img[:,:,1]+img[:,:,2]
         img = stretch(img.astype(float))
         lt = self.frame.MenuBar.Menus[0][0].MenuItems[7].IsChecked()
         if lt:
             limg, d = log_transform(img)
         else:
             limg = img
         self.frame.subplot_imshow_grayscale(0, 0, limg)
         limg = limg.flatten()
         menu_items = self.frame.MenuBar.Menus[0][0].MenuItems
         if menu_items[2].IsChecked():
             t1 = t2 = otsu(limg)
         elif menu_items[3].IsChecked():
             t1 = t2 = entropy(limg)
         elif menu_items[4].IsChecked():
             t1, t2 = otsu3slow(limg)
         elif menu_items[5].IsChecked():
             t1, t2 = entropy3(limg)
         else:
             t1, t2 = otsu3(limg)
         if lt:
             t1,t2 = inverse_log_transform(np.array([t1,t2]), d)
         m1 = img < t1
         m2 = np.logical_and(img >= t1, img < t2)
         m3 = img > t2
         cimg = np.zeros((m1.shape[0],m1.shape[1],3))
         cimg[:,:,0][m1]=img[m1]
         cimg[:,:,1][m2]=img[m2]
         cimg[:,:,2][m3]=img[m3]
         self.frame.subplot_imshow(1, 0, cimg,
                                   sharex = self.frame.subplot(0,0),
                                   sharey = self.frame.subplot(0,0))
         self.frame.Refresh()
         wx.MessageBox("Low threshold = %f, high threshold = %f"%(t1,t2),
                       parent=self.frame)
 def display(self, workspace):
     '''Display the results of relabeling
     
     workspace - workspace containing saved display data
     '''
     from cellprofiler.gui.cpfigure import renumber_labels_for_display
     import matplotlib.cm as cm
     
     figure = workspace.create_or_find_figure(title="ReassignObjectNumbers, image cycle #%d"%(
             workspace.measurements.image_set_number),subplots=(1,2))
     figure.subplot_imshow_labels(0,0, workspace.display_data.orig_labels,
                                  title = self.objects_name.value)
     if self.wants_image:
         #
         # Make a nice picture which superimposes the labels on the
         # guiding image
         #
         output_labels = renumber_labels_for_display(
             workspace.display_data.output_labels)
         image = (stretch(workspace.display_data.image) * 255).astype(np.uint8)
         image = np.dstack((image,image,image))
         my_cm = cm.get_cmap(cpprefs.get_default_colormap())
         my_cm.set_bad((0,0,0))
         sm = cm.ScalarMappable(cmap=my_cm)
         m_output_labels = np.ma.array(output_labels,
                                     mask = output_labels == 0)
         output_image = sm.to_rgba(m_output_labels, bytes=True)[:,:,:3]
         image[output_labels > 0 ] = (
             image[output_labels > 0] / 4 * 3 +
             output_image[output_labels > 0,:] / 4)
         figure.subplot_imshow(0,1, image,
                               title = self.output_objects_name.value,
                               sharex = figure.subplot(0,0),
                               sharey = figure.subplot(0,0))
     else:
         figure.subplot_imshow_labels(0,1, 
                                      workspace.display_data.output_labels,
                                      title = self.output_objects_name.value,
                                      sharex = figure.subplot(0,0),
                                      sharey = figure.subplot(0,0))
Beispiel #19
0
 def run_image_gabor(self, image_name, scale, workspace):
     image = workspace.image_set.get_image(image_name,
                                           must_be_grayscale=True)
     pixel_data = image.pixel_data
     labels = np.ones(pixel_data.shape, int)
     if image.has_mask:
         labels[~image.mask] = 0
     pixel_data = stretch(pixel_data, labels > 0)
     best_score = 0
     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 = np.sum(g.real)
         score_i = np.sum(g.imag)
         score = np.sqrt(score_r**2+score_i**2)
         best_score = max(best_score, score)
     statistics = self.record_image_measurement(workspace, 
                                                image_name, 
                                                scale,
                                                F_GABOR, 
                                                best_score)
     return statistics
 def test_05_04_otsu3_wv_high(self):
     '''Test the three-class otsu, weighted variance middle = foreground'''
     np.random.seed(0)
     image = np.hstack((np.random.exponential(1.5,size=300),
                        np.random.poisson(15,size=300),
                        np.random.poisson(30,size=300)))
     image.shape=(30,30)
     image = stretch(image)
     limage, d = T.log_transform(image)
     t1,t2 = otsu3(limage)
     threshold = T.inverse_log_transform(t1, d)
     workspace, module = self.make_workspace(image)
     module.binary.value = A.BINARY
     module.threshold_scope.value = I.TS_GLOBAL
     module.threshold_method.value = T.TM_OTSU
     module.use_weighted_variance.value = I.O_WEIGHTED_VARIANCE
     module.two_class_otsu.value = I.O_THREE_CLASS
     module.assign_middle_to_foreground.value = I.O_FOREGROUND
     module.run(workspace)
     m = workspace.measurements
     m_threshold = m[cpmeas.IMAGE, I.FF_ORIG_THRESHOLD % module.get_measurement_objects_name()]
     self.assertAlmostEqual(m_threshold, threshold)
 def test_05_05_otsu3_entropy_low(self):
     '''Test the three-class otsu, entropy, middle = background'''
     np.random.seed(0)
     image = np.hstack((np.random.exponential(1.5,size=300),
                        np.random.poisson(15,size=300),
                        np.random.poisson(30,size=300)))
     image.shape=(30,30)
     image = stretch(image)
     limage, d = T.log_transform(image)
     t1,t2 = entropy3(limage)
     threshold = T.inverse_log_transform(t2, d)
     workspace, module = self.make_workspace(image)
     module.binary.value = A.BINARY
     module.threshold_scope.value = I.TS_GLOBAL
     module.threshold_method.value = T.TM_OTSU
     module.use_weighted_variance.value = I.O_ENTROPY
     module.two_class_otsu.value = I.O_THREE_CLASS
     module.assign_middle_to_foreground.value = I.O_BACKGROUND
     module.run(workspace)
     output = workspace.image_set.get_image(OUTPUT_IMAGE_NAME)
     m = workspace.measurements
     m_threshold = m[cpmeas.IMAGE, I.FF_ORIG_THRESHOLD % module.get_measurement_objects_name()]
     self.assertAlmostEqual(m_threshold, threshold)
    def display(self, workspace, figure):
        from identify import TS_BINARY_IMAGE

        object_pct = workspace.display_data.object_pct
        img = workspace.display_data.img
        primary_outline = workspace.display_data.primary_outline
        secondary_outline = workspace.display_data.secondary_outline
        segmented_out = workspace.display_data.segmented_out
        global_threshold = workspace.display_data.global_threshold
        object_count = workspace.display_data.object_count
        statistics = workspace.display_data.statistics

        if global_threshold is not None:
            statistics.append(["Threshold", "%.3f" % global_threshold])

        if object_count > 0:
            areas = scind.sum(np.ones(segmented_out.shape), segmented_out,
                              np.arange(1, object_count + 1))
            areas.sort()
            low_diameter = (np.sqrt(float(areas[object_count / 10]) / np.pi) *
                            2)
            median_diameter = (
                np.sqrt(float(areas[object_count / 2]) / np.pi) * 2)
            high_diameter = (
                np.sqrt(float(areas[object_count * 9 / 10]) / np.pi) * 2)
            statistics.append(
                ["10th pctile diameter",
                 "%.1f pixels" % (low_diameter)])
            statistics.append(
                ["Median diameter",
                 "%.1f pixels" % (median_diameter)])
            statistics.append(
                ["90th pctile diameter",
                 "%.1f pixels" % (high_diameter)])
            if self.method != M_DISTANCE_N and self.threshold_scope != TS_BINARY_IMAGE:
                statistics.append([
                    "Thresholding filter size",
                    "%.1f" % (workspace.display_data.threshold_sigma)
                ])
            statistics.append(
                ["Area covered by objects",
                 "%.1f %%" % object_pct])
        workspace.display_data.statistics = statistics

        figure.set_subplots((2, 2))
        title = "Input image, cycle #%d" % (
            workspace.measurements.image_number)
        figure.subplot_imshow_grayscale(0, 0, img, title)
        figure.subplot_imshow_labels(1,
                                     0,
                                     segmented_out,
                                     "%s objects" % self.objects_name.value,
                                     sharexy=figure.subplot(0, 0))

        primary_img = np.dstack((img, img, img))
        #
        # Stretch the outline image to the full scale
        #
        primary_img = stretch(primary_img)
        # Outline the primary objects
        cpmi.draw_outline(primary_img, primary_outline > 0,
                          cpprefs.get_primary_outline_color())
        # Outline the secondary objects
        cpmi.draw_outline(primary_img, secondary_outline > 0,
                          cpprefs.get_secondary_outline_color())
        figure.subplot_imshow(
            0,
            1,
            primary_img,
            "%s and %s outlines" %
            (self.primary_objects.value, self.objects_name.value),
            normalize=False,
            sharexy=figure.subplot(0, 0))
        figure.subplot_table(
            1,
            1, [[x[1]] for x in workspace.display_data.statistics],
            row_labels=[x[0] for x in workspace.display_data.statistics])
Beispiel #23
0
 def run(self, workspace):
     image = workspace.image_set.get_image(self.image_name.value,
                                           must_be_grayscale=True)
     orig_pixels = image.pixel_data
     if image.has_mask:
         mask = image.mask
     else:
         mask = np.ones(orig_pixels.shape, bool)
     if self.method == M_SOBEL:
         if self.direction == E_ALL:
             output_pixels = sobel(orig_pixels, mask)
         elif self.direction == E_HORIZONTAL:
             output_pixels = hsobel(orig_pixels, mask)
         elif self.direction == E_VERTICAL:
             output_pixels = vsobel(orig_pixels, mask)
         else:
             raise NotImplementedError(
                 "Unimplemented direction for Sobel: %s",
                 self.direction.value)
     elif self.method == M_LOG:
         sigma = self.get_sigma()
         size = int(sigma * 4) + 1
         output_pixels = laplacian_of_gaussian(orig_pixels, mask, size,
                                               sigma)
     elif self.method == M_PREWITT:
         if self.direction == E_ALL:
             output_pixels = prewitt(orig_pixels)
         elif self.direction == E_HORIZONTAL:
             output_pixels = hprewitt(orig_pixels, mask)
         elif self.direction == E_VERTICAL:
             output_pixels = vprewitt(orig_pixels, mask)
         else:
             raise NotImplementedError(
                 "Unimplemented direction for Prewitt: %s",
                 self.direction.value)
     elif self.method == M_CANNY:
         high_threshold = self.manual_threshold.value
         low_threshold = self.low_threshold.value
         if (self.wants_automatic_low_threshold.value
                 or self.wants_automatic_threshold.value):
             sobel_image = sobel(orig_pixels, mask)
             low, high = otsu3(sobel_image[mask])
             if self.wants_automatic_low_threshold.value:
                 low_threshold = low * self.threshold_adjustment_factor.value
             if self.wants_automatic_threshold.value:
                 high_threshold = high * self.threshold_adjustment_factor.value
         output_pixels = canny(orig_pixels, mask, self.get_sigma(),
                               low_threshold, high_threshold)
     elif self.method == M_ROBERTS:
         output_pixels = roberts(orig_pixels, mask)
     else:
         raise NotImplementedError(
             "Unimplemented edge detection method: %s" % self.method.value)
     if not workspace.frame is None:
         figure = workspace.create_or_find_figure(
             title="EnhanceEdges, image cycle #%d" %
             (workspace.measurements.image_set_number),
             subplots=(2, 2))
         figure.subplot_imshow_grayscale(
             0, 0, orig_pixels, "Original: %s" % self.image_name.value)
         if self.method == M_CANNY:
             # Canny is binary
             figure.subplot_imshow_bw(0,
                                      1,
                                      output_pixels,
                                      self.output_image_name.value,
                                      sharex=figure.subplot(0, 0),
                                      sharey=figure.subplot(0, 0))
         else:
             figure.subplot_imshow_grayscale(0,
                                             1,
                                             output_pixels,
                                             self.output_image_name.value,
                                             sharex=figure.subplot(0, 0),
                                             sharey=figure.subplot(0, 0))
         color_image = np.zeros(
             (output_pixels.shape[0], output_pixels.shape[1], 3))
         color_image[:, :, 0] = stretch(orig_pixels)
         color_image[:, :, 1] = stretch(output_pixels)
         figure.subplot_imshow(1,
                               0,
                               color_image,
                               "Composite image",
                               sharex=figure.subplot(0, 0),
                               sharey=figure.subplot(0, 0))
     output_image = cpi.Image(output_pixels, parent_image=image)
     workspace.image_set.add(self.output_image_name.value, output_image)
 def stretch(self, input_image):
     '''Stretch the input image to the range 0:1'''
     if input_image.has_mask:
         return stretch(input_image.pixel_data, input_image.mask)
     else:
         return stretch(input_image.pixel_data)
Beispiel #25
0
    def handle_interaction(self, current_shape, orig_image):
        '''Show the cropping user interface'''
        import matplotlib as M
        import matplotlib.cm
        import wx
        from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg
        pixel_data = stretch(orig_image)
        #
        # Create the UI - a dialog with a figure inside
        #
        style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER
        dialog_box = wx.Dialog(wx.GetApp().TopWindow, -1,
                               "Select the cropping region",
                               size=(640,480),
                               style = style)
        sizer = wx.BoxSizer(wx.VERTICAL)
        figure = matplotlib.figure.Figure()
        panel = FigureCanvasWxAgg(dialog_box, -1, figure)
        sizer.Add(panel, 1, wx.EXPAND)
        btn_sizer = wx.StdDialogButtonSizer()
        btn_sizer.AddButton(wx.Button(dialog_box, wx.ID_OK))
        btn_sizer.AddButton(wx.Button(dialog_box, wx.ID_CANCEL))
        btn_sizer.Realize()
        sizer.Add(btn_sizer, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALL, 5)
        dialog_box.SetSizer(sizer)
        dialog_box.Size = dialog_box.BestSize
        dialog_box.Layout()

        axes = figure.add_subplot(1,1,1)
        assert isinstance(axes, matplotlib.axes.Axes)
        if pixel_data.ndim == 2:
            axes.imshow(pixel_data, matplotlib.cm.Greys_r, origin="upper")
        else:
            axes.imshow(pixel_data, origin="upper")
        #t = axes.transData.inverted()
        current_handle = [ None ]
        def data_xy(mouse_event):
            '''Return the mouse event's x & y converted into data-relative coords'''
            x = mouse_event.xdata
            y = mouse_event.ydata
            return (x,y)
        
        class handle(M.patches.Rectangle):
            dm = max((10,min(pixel_data.shape)/50))
            height, width = (dm,dm)
            def __init__(self, x, y, on_move):
                x = max(0, min(x, pixel_data.shape[1]))
                y = max(0, min(y, pixel_data.shape[0]))
                self.__selected = False
                self.__color = cpprefs.get_primary_outline_color()
                self.__color = np.hstack((self.__color,[255])).astype(float) / 255.0
                self.__on_move = on_move
                super(handle, self).__init__((x-self.width/2, y-self.height/2),
                                             self.width, self.height,
                                             edgecolor = self.__color,
                                             facecolor = "none")
                self.set_picker(True)
                
            def move(self, x, y):
                self.set_xy((x-self.width/2, y-self.height/2))
                self.__on_move(x, y)
                
            def select(self, on):
                self.__selected = on
                if on:
                    current_handle[0] = self
                    self.set_facecolor(self.__color)
                    
                else:
                    self.set_facecolor("none")
                    if current_handle[0] == self:
                        current_handle[0] = None
                figure.canvas.draw()
                dialog_box.Update()
                
            @property
            def is_selected(self):
                return self.__selected
            
            @property
            def center_x(self):
                '''The handle's notion of its x coordinate'''
                return self.get_x() + self.get_width() / 2
            
            @property
            def center_y(self):
                '''The handle's notion of its y coordinate'''
                return self.get_y() + self.get_height() / 2
            
            def handle_pick(self, event):
                mouse_event = event.mouseevent
                x, y = data_xy(mouse_event)
                if mouse_event.button == 1:
                    self.select(True)
                    self.orig_x = self.center_x
                    self.orig_y = self.center_y
                    self.first_x = x
                    self.first_y = y
                    
            def handle_mouse_move_event(self, event):
                x,y = data_xy(event)
                if x is None or y is None:
                    return
                x = x - self.first_x + self.orig_x
                y = y - self.first_y + self.orig_y
                if x < 0:
                    x = 0
                if x >= pixel_data.shape[1]:
                    x = pixel_data.shape[1] -1
                if y < 0:
                    y = 0
                if y >= pixel_data.shape[0]:
                    y = pixel_data.shape[0] -1
                self.move(x, y)
            
        class crop_rectangle(object):
            def __init__(self, top_left, bottom_right):
                self.__left, self.__top = top_left
                self.__right, self.__bottom = bottom_right
                color = cpprefs.get_primary_outline_color()
                color = np.hstack((color,[255])).astype(float) / 255.0
                self.rectangle = M.patches.Rectangle(
                    (min(self.__left, self.__right), 
                     min(self.__bottom, self.__top)),
                    abs(self.__right - self.__left),
                    abs(self.__top - self.__bottom),
                    edgecolor = color,
                    facecolor = "none"
                )
                self.top_left_handle = handle(top_left[0], top_left[1],
                                              self.handle_top_left)
                self.bottom_right_handle = handle(bottom_right[0], 
                                                  bottom_right[1], 
                                                  self.handle_bottom_right)
                
            def handle_top_left(self, x, y):
                self.__left = x
                self.__top = y
                self.__reshape()
                
            def handle_bottom_right(self, x, y):
                self.__right = x
                self.__bottom = y
                self.__reshape()
                
            def __reshape(self):
                self.rectangle.set_xy((min(self.__left, self.__right), 
                                       min(self.__bottom,self.__top)))
                self.rectangle.set_width(abs(self.__right - self.__left))
                self.rectangle.set_height(abs(self.__bottom - self.__top))
                self.rectangle.figure.canvas.draw()
                dialog_box.Update()
                
            @property
            def patches(self):
                return [self.rectangle, self.top_left_handle, 
                        self.bottom_right_handle]
            
            @property
            def handles(self):
                return [self.top_left_handle, self.bottom_right_handle]
            
            @property
            def left(self):
                return min(self.__left, self.__right)
            
            @property
            def right(self):
                return max(self.__left, self.__right)
            
            @property
            def top(self):
                return min(self.__top, self.__bottom)
            
            @property
            def bottom(self):
                return max(self.__top, self.__bottom)

        class crop_ellipse(object):
            def __init__(self, center, radius):
                '''Draw an ellipse with control points at the ellipse center and
                a given x and y radius'''
                self.center_x, self.center_y = center
                self.radius_x = self.center_x + radius[0] / 2
                self.radius_y = self.center_y + radius[1] / 2
                color = cpprefs.get_primary_outline_color()
                color = np.hstack((color,[255])).astype(float) / 255.0
                self.ellipse = M.patches.Ellipse(center, self.width, self.height,
                                                 edgecolor = color,
                                                 facecolor = "none")
                self.center_handle = handle(self.center_x, self.center_y,
                                            self.move_center)
                self.radius_handle = handle(self.radius_x, self.radius_y,
                                            self.move_radius)
                
            def move_center(self, x, y):
                self.center_x = x
                self.center_y = y
                self.redraw()
                
            def move_radius(self, x, y):
                self.radius_x = x
                self.radius_y = y
                self.redraw()
                
            @property
            def width(self):
                return abs(self.center_x - self.radius_x) * 4
            
            @property
            def height(self):
                return abs(self.center_y - self.radius_y) * 4
            
            def redraw(self):
                self.ellipse.center = (self.center_x, self.center_y)
                self.ellipse.width = self.width
                self.ellipse.height = self.height
                self.ellipse.figure.canvas.draw()
                dialog_box.Update()
                
            @property
            def patches(self):
                return [self.ellipse, self.center_handle, self.radius_handle] 
            
            @property
            def handles(self):
                return [self.center_handle, self.radius_handle]
            
        if self.shape == SH_ELLIPSE:
            if current_shape is None:
                current_shape = {
                    EL_XCENTER: pixel_data.shape[1] / 2,
                    EL_YCENTER: pixel_data.shape[0] / 2,
                    EL_XRADIUS: pixel_data.shape[1] / 2,
                    EL_YRADIUS: pixel_data.shape[0] / 2
                    }
            ellipse = current_shape
            shape = crop_ellipse((ellipse[EL_XCENTER], ellipse[EL_YCENTER]),
                                 (ellipse[EL_XRADIUS], ellipse[EL_YRADIUS]))
        else:
            if current_shape is None:
                current_shape = {
                    RE_LEFT: pixel_data.shape[1] / 4,
                    RE_TOP: pixel_data.shape[0] / 4,
                    RE_RIGHT: pixel_data.shape[1] * 3 / 4,
                    RE_BOTTOM: pixel_data.shape[0] * 3 / 4
                    }
            rectangle = current_shape
            shape = crop_rectangle((rectangle[RE_LEFT], rectangle[RE_TOP]),
                                   (rectangle[RE_RIGHT], rectangle[RE_BOTTOM]))
        for patch in shape.patches:
            axes.add_artist(patch)
            
        def on_mouse_down_event(event):
            axes.pick(event)
            
        def on_mouse_move_event(event):
            if current_handle[0] is not None:
                current_handle[0].handle_mouse_move_event(event)
                
        def on_mouse_up_event(event):
            if current_handle[0] is not None:
                current_handle[0].select(False)
            
        def on_pick_event(event):
            for h in shape.handles:
                if id(h) == id(event.artist):
                    h.handle_pick(event)
                    
        figure.canvas.mpl_connect('button_press_event', on_mouse_down_event)
        figure.canvas.mpl_connect('button_release_event', on_mouse_up_event)
        figure.canvas.mpl_connect('motion_notify_event', on_mouse_move_event)
        figure.canvas.mpl_connect('pick_event', on_pick_event)
        
        try:
            if dialog_box.ShowModal() != wx.ID_OK:
                raise ValueError("Cancelled by user")
        finally:
            dialog_box.Destroy()
        if self.shape == SH_RECTANGLE:
            return {
                RE_LEFT: shape.left,
                RE_TOP: shape.top,
                RE_RIGHT: shape.right,
                RE_BOTTOM: shape.bottom
                }
        else:
            return {
                EL_XCENTER: shape.center_x,
                EL_YCENTER: shape.center_y,
                EL_XRADIUS: shape.width / 2,
                EL_YRADIUS: shape.height / 2
                }
Beispiel #26
0
 def run(self, workspace):
     image = workspace.image_set.get_image(self.image_name.value,
                                           must_be_grayscale = True)
     orig_pixels = image.pixel_data
     if image.has_mask:
         mask = image.mask
     else:
         mask = np.ones(orig_pixels.shape,bool)
     if self.method == M_SOBEL:
         if self.direction == E_ALL:
             output_pixels = sobel(orig_pixels, mask)
         elif self.direction == E_HORIZONTAL:
             output_pixels = hsobel(orig_pixels, mask)
         elif self.direction == E_VERTICAL:
             output_pixels = vsobel(orig_pixels, mask)
         else:
             raise NotImplementedError("Unimplemented direction for Sobel: %s",self.direction.value)
     elif self.method == M_LOG:
         sigma = self.get_sigma()
         size = int(sigma * 4)+1
         output_pixels = laplacian_of_gaussian(orig_pixels, mask, size, sigma)
     elif self.method == M_PREWITT:
         if self.direction == E_ALL:
             output_pixels = prewitt(orig_pixels)
         elif self.direction == E_HORIZONTAL:
             output_pixels = hprewitt(orig_pixels, mask)
         elif self.direction == E_VERTICAL:
             output_pixels = vprewitt(orig_pixels, mask)
         else:
             raise NotImplementedError("Unimplemented direction for Prewitt: %s",self.direction.value)
     elif self.method == M_CANNY:
         high_threshold = self.manual_threshold.value
         low_threshold = self.low_threshold.value
         if (self.wants_automatic_low_threshold.value or
             self.wants_automatic_threshold.value):
             sobel_image = sobel(orig_pixels, mask)
             low, high = otsu3(sobel_image[mask])
             if self.wants_automatic_low_threshold.value:
                 low_threshold = low * self.threshold_adjustment_factor.value
             if self.wants_automatic_threshold.value:
                 high_threshold = high * self.threshold_adjustment_factor.value
         output_pixels = canny(orig_pixels,mask, self.get_sigma(),
                               low_threshold,
                               high_threshold)
     elif self.method == M_ROBERTS:
         output_pixels = roberts(orig_pixels, mask)
     else:
         raise NotImplementedError("Unimplemented edge detection method: %s"%
                                   self.method.value)
     if not workspace.frame is None:
         figure = workspace.create_or_find_figure(title="EnhanceEdges, image cycle #%d"%(
             workspace.measurements.image_set_number),subplots=(2,2))
         figure.subplot_imshow_grayscale(0,0, orig_pixels,
                                         "Original: %s"%
                                         self.image_name.value)
         if self.method == M_CANNY:
             # Canny is binary
             figure.subplot_imshow_bw(0,1, output_pixels,
                                      self.output_image_name.value,
                                      sharex = figure.subplot(0,0),
                                      sharey = figure.subplot(0,0))
         else:
             figure.subplot_imshow_grayscale(0,1,output_pixels,
                                             self.output_image_name.value,
                                             sharex = figure.subplot(0,0),
                                             sharey = figure.subplot(0,0))
         color_image = np.zeros((output_pixels.shape[0],
                                 output_pixels.shape[1],3))
         color_image[:,:,0] = stretch(orig_pixels)
         color_image[:,:,1] = stretch(output_pixels)
         figure.subplot_imshow(1,0, color_image,"Composite image",
                               sharex = figure.subplot(0,0),
                               sharey = figure.subplot(0,0))
     output_image = cpi.Image(output_pixels, parent_image = image)
     workspace.image_set.add(self.output_image_name.value, output_image)   
Beispiel #27
0
 def stretch(self, input_image):
     '''Stretch the input image to the range 0:1'''
     if input_image.has_mask:
         return stretch(input_image.pixel_data, input_image.mask)
     else:
         return stretch(input_image.pixel_data)