def add_channelfn(self, can_remove=True): '''Add another image channel can_remove - true if we are allowed to remove this channel ''' group = cps.SettingsGroup() self.channels.append(group) # Check which cellprofiler image we are in the group # (each channel translates to a single cellprofiler image) cpimg_index = 0 for channel in self.channels: if id(channel) == id(group): break cpimg_index += 1 group.append("divider", cps.Divider(line=True)) group.append("cpimage_name", cps.ImageNameProvider( 'Image name', default_cpimage_name(cpimg_index))) channel_numbers = [ str(x) for x in range(0, max(10, len(self.channels) + 2))] group.append("channel_number", cps.Choice( "Channel number:", channel_numbers, channel_numbers[len(self.channels) - 1], doc="""(Used only for multichannel images) The channels of a multichannel image are numbered starting from 0 (zero). Each channel is a greyscale image, acquired using different illumination sources and/or optics. Use this setting to pick the channel to associate with the image or images you load from OMERO.""")) group.can_remove = can_remove if can_remove: group.append("remover", cps.RemoveSettingButton( "Remove this channel", "Remove channel", self.channels, group))
def add_image(self, can_remove=True): '''Add an image + associated questions and buttons''' group = cps.SettingsGroup() if can_remove: group.append("divider", cps.Divider(line=False)) group.append("input_image_name", cps.ImageNameSubscriber( "Select the additional image", cps.NONE, doc=""" Select the additional image to align?""")) group.append("output_image_name", cps.ImageNameProvider( "Name the output image", "AlignedBlue", doc=""" Enter the name of the aligned image?""")) group.append("align_choice", cps.Choice( "Select how the alignment is to be applied", [A_SIMILARLY, A_SEPARATELY], doc=""" An additional image can either be aligned similarly to the second one or a separate alignment to the first image can be calculated: <ul> <li><i>%(A_SIMILARLY)s:</i> The same alignment measurements obtained from the first two input images are applied to this additional image.</li> <li><i>%(A_SEPARATELY)s:</i> A new set of alignment measurements are calculated for this additional image using the alignment method specified with respect to the first input image.</li> </ul>""" % globals())) if can_remove: group.append("remover", cps.RemoveSettingButton("", "Remove above image", self.additional_images, group)) self.additional_images.append(group)
def add_channel(self, can_remove=True): '''Add another channel to the channels list''' group = cps.SettingsGroup() group.can_remove = can_remove group.append("channel_choice", cps.Choice( "Channel number", self.channel_names, self.channel_names[len(self.channels) % len(self.channel_names)], doc=""" This setting chooses a channel to be processed. <i>Red: 1</i> is the first channel in a .TIF or the red channel in a traditional image file. <i>Green: 2</i> and <i>Blue: 3</i> are the second and third channels of a TIF or the green and blue channels in other formats. <i>Alpha: 4</i> is the transparency channel for image formats that support transparency and is channel # 4 for a .TIF file. <b>ColorToGray</b> will fail to process an image if you select a channel that is not supported by that image, for example, "5" for a .PNG file""")) group.append("contribution", cps.Float( "Relative weight of the channel", 1, 0, doc=''' <i>(Used only when combining channels)</i><br> Relative weights: If all relative weights are equal, all three colors contribute equally in the final image. To weight colors relative to each other, increase or decrease the relative weights.''')) group.append("image_name", cps.ImageNameProvider( "Image name", value="Channel%d" % (len(self.channels) + 1), doc=""" This is the name of the grayscale image that holds the image data from the chosen channel.""")) if group.can_remove: group.append("remover", cps.RemoveSettingButton( "", "Remove this channel", self.channels, group)) self.channels.append(group)
def create_settings(self): self.image_name = cps.ImageNameSubscriber("Select the input image", cps.NONE, doc="""\ Select the image that you want to perform a morphological operation on. A grayscale image can be converted to binary using the **Threshold** module. Objects can be converted to binary using the **ConvertToImage** module.""") self.output_image_name = cps.ImageNameProvider( "Name the output image", "MorphBlue", doc= """Enter the name for the output image. It will be of the same type as the input image.""" ) self.add_button = cps.DoSomething("", "Add another operation", self.add_function, doc="""\ Press this button to add an operation that will be applied to the image resulting from the previous operation(s). The module repeats the previous operation the number of times you select before applying the operation added by this button.""") self.functions = [] self.add_function(can_remove=False)
def add_image(self, can_remove=True): '''Add an image + associated questions and buttons''' group = cps.SettingsGroup() if can_remove: group.append("divider", cps.Divider(line=False)) group.append( "input_image_name", cps.ImageNameSubscriber("Select the additional image?", cps.NONE, doc=""" What is the name of the additional image to resize? This image will be resized with the same settings as the first image.""" )) group.append( "output_image_name", cps.ImageNameProvider("Name the output image", "ResizedBlue", doc=""" What is the name of the additional resized image?""" )) if can_remove: group.append( "remover", cps.RemoveSettingButton("", "Remove above image", self.additional_images, group)) self.additional_images.append(group)
def create_settings(self): self.image_name = cps.ImageNameSubscriber("Select the input image", cps.NONE) self.conversion_method = cps.Choice("Conversion method", [MEAN, MEDIAN, CUSTOMFUNCTION], doc=''' How do you want to summarize the multichannel image? <ul> <li><i>%(MEAN)s:</i> Takes the mean.</li> <li><i>%(MEDIAN)s</i> Takes the median</li> <li><i>%(MEDIAN)s</i> Applies a cutstom python function</li> </ul>''' % globals()) self.custom_function = cps.Text("Input a Python function", 'np.mean', doc=''' Can be a simple function as "np.max" (without ") or complicated as "functools.partial(np.percentile,q=80, axis=2)". functools is imported as convenience. ''') # The following settings are used for the combine option self.grayscale_name = cps.ImageNameProvider("Name the output image", "OrigGray") # The alternative model: self.channels = []
def add_channel(self, can_remove=True): """Add another channel to the channels list""" group = cps.SettingsGroup() group.can_remove = can_remove group.append( "channel_choice", cps.Integer( text="Channel number", value=len(self.channels) + 1, minval=1, doc="""\ *(Used only when splitting images)* This setting chooses a channel to be processed. For example, *1* is the first channel in a .TIF or the red channel in a traditional image file. *2* and *3* are the second and third channels of a TIF or the green and blue channels in other formats. *4* is the transparency channel for image formats that support transparency and is channel # 4 for a .TIF file. **ColorToGray** will fail to process an image if you select a channel that is not supported by that image, for example, “5” for a three-channel .PNG file.""", ), ) group.append( "contribution", cps.Float( "Relative weight of the channel", 1, 0, doc="""\ *(Used only when combining channels)* Relative weights: If all relative weights are equal, all three colors contribute equally in the final image. To weight colors relative to each other, increase or decrease the relative weights.""", ), ) group.append( "image_name", cps.ImageNameProvider( "Image name", value="Channel%d" % (len(self.channels) + 1), doc="""\ *(Used only when splitting images)* Select the name of the output grayscale image.""", ), ) if group.can_remove: group.append( "remover", cps.RemoveSettingButton("", "Remove this channel", self.channels, group), ) self.channels.append(group)
def create_settings(self): """Create the settings here and set the module name (initialization) """ self.source_choice = cps.Choice("Use objects or an image as a mask?", [IO_OBJECTS, IO_IMAGE], doc="""\ You can mask an image in two ways: - *%(IO_OBJECTS)s*: Using objects created by another module (for instance **IdentifyPrimaryObjects**). The module will mask out all parts of the image that are not within one of the objects (unless you invert the mask). - *%(IO_IMAGE)s*: Using a binary image as the mask, where black portions of the image (false or zero-value pixels) will be masked out. If the image is not binary, the module will use all pixels whose intensity is greater than 0.5 as the mask’s foreground (white area). You can use **Threshold** instead to create a binary image with finer control over the intensity choice. """ % globals()) self.object_name = cps.ObjectNameSubscriber("Select object for mask", cps.NONE, doc="""\ *(Used only if mask is to be made from objects)* Select the objects you would like to use to mask the input image. """) self.masking_image_name = cps.ImageNameSubscriber( "Select image for mask", cps.NONE, doc="""\ *(Used only if mask is to be made from an image)* Select the image that you like to use to mask the input image. """) self.image_name = cps.ImageNameSubscriber( "Select the input image", cps.NONE, doc="Select the image that you want to mask.") self.masked_image_name = cps.ImageNameProvider( "Name the output image", "MaskBlue", doc="Enter the name for the output masked image.") self.invert_mask = cps.Binary("Invert the mask?", False, doc="""\ This option reverses the foreground/background relationship of the mask. - Select "*%(NO)s*" to produce the mask from the foreground (white portion) of the masking image or the area within the masking objects. - Select "*%(YES)s*" to instead produce the mask from the *background* (black portions) of the masking image or the area *outside* the masking objects. """ % globals())
def add_image(self, can_delete=True): '''Add an image and its settings to the list of images''' image_name = cps.ImageNameSubscriber( "Select the input image", cps.NONE, doc="Select the image to be corrected.") corrected_image_name = cps.ImageNameProvider( "Name the output image", "CorrBlue", doc="Enter a name for the corrected image.") illum_correct_function_image_name = cps.ImageNameSubscriber( "Select the illumination function", cps.NONE, doc="""\ Select the illumination correction function image that will be used to carry out the correction. This image is usually produced by another module or loaded as a .npy format image using the **Images** module or **LoadSingleImage**. """) divide_or_subtract = cps.Choice( "Select how the illumination function is applied", [DOS_DIVIDE, DOS_SUBTRACT], doc="""\ This choice depends on how the illumination function was calculated and on your physical model of the way illumination variation affects the background of images relative to the objects in images; it is also somewhat empirical. - *%(DOS_SUBTRACT)s:* Use this option if the background signal is significant relative to the real signal coming from the cells. If you created the illumination correction function using *%(IC_BACKGROUND)s*, then you will want to choose *%(DOS_SUBTRACT)s* here. - *%(DOS_DIVIDE)s:* Choose this option if the signal to background ratio is high (the cells are stained very strongly). If you created the illumination correction function using *%(IC_REGULAR)s*, then you will want to choose *%(DOS_DIVIDE)s* here. """ % globals()) image_settings = cps.SettingsGroup() image_settings.append("image_name", image_name) image_settings.append("corrected_image_name", corrected_image_name) image_settings.append("illum_correct_function_image_name", illum_correct_function_image_name) image_settings.append("divide_or_subtract", divide_or_subtract) image_settings.append("rescale_option", RE_NONE) if can_delete: image_settings.append( "remover", cps.RemoveSettingButton("", "Remove this image", self.images, image_settings)) image_settings.append("divider", cps.Divider()) self.images.append(image_settings)
def add_heatmap(self): group = cps.SettingsGroup() if len(self.heatmaps) > 0: group.append("divider", cps.Divider(line=False)) group.append("image_name", MORDImageNameSubscriber( "Image", doc=""" The heatmap will be displayed with measurements taken using this image. The setting will let you choose from among the images you have specified in "Select image to measure". """)) group.image_name.set_module(self) group.append("object_name", MORDObjectNameSubscriber( "Objects to display", doc=""" The objects to display in the heatmap. You can select any of the objects chosen in "Select objects to measure". """)) group.object_name.set_module(self) group.append("bin_count", cps.Choice( "Number of bins", self.get_bin_count_choices(), choices_fn=self.get_bin_count_choices)) def get_number_of_bins(module=self, group=group): if len(module.bin_counts) == 1: return module.bin_counts[0].bin_count.value else: return int(group.bin_count.value) group.get_number_of_bins = get_number_of_bins group.append("measurement", cps.Choice( "Measurement", MEASUREMENT_CHOICES, doc="""The measurement to display.""")) group.append("colormap", cps.Colormap( "Color map", doc=""" The color map setting chooses the color palette that will be used to render the different values for your measurement. If you choose "gray", the image will label each of the bins with the actual image measurement. """)) group.append("wants_to_save_display", cps.Binary( "Save display as image?", False, doc="""This setting allows you to save the heatmap display as an image that can be output using the <b>SaveImages</b> module. Choose <i>%(YES)s</i> to save the display or <i>%(NO)s</i> if the display is not needed.""" % globals())) group.append("display_name", cps.ImageNameProvider( "Output image name", "Heatmap", doc=""" <i>(Only used if "Save display as image?" is "%(YES)s")</i><br> This setting names the heatmap image so that the name you enter here can be selected in a later <b>SaveImages</b> or other module. """ % globals())) group.append("remover", cps.RemoveSettingButton( "", "Remove this heatmap display", self.heatmaps, group)) self.heatmaps.append(group)
def create_settings(self) -> None: module_explanation = "Creates a binary mask of the wedge." self.set_notes([module_explanation]) self.wedge_mask_name = cps.ObjectNameProvider( text="Name the wedge mask", value="WedgeMask", doc="Enter the name of the wedge mask.", ) self.image_name = cps.ImageNameProvider( text="Select image to overlay on", value="None", doc="""\ Choose the image_name upon which a wedge mask constructed from the given parameters is laid. Can be either RGB or grayscale. """, ) self.divider = cps.Divider(line=True) self.thickness = cps.Float(text="Enter thickness of wedge (um)", value=400.0, doc="") self.span = cps.Float(text="Enter span of wedge (deg)", value=90.0, doc="") self.radial_offset = cps.Float( text="Enter radial offset", value=0.0, doc= "Enter offset of the inner edge of wedge from well, in microns.", ) self.angular_offset = cps.Float( text="Enter angular offset", value=0.0, doc="""\ Enter offset of the wedge midline from well midline, in degrees, clockwise positive. """, ) self.mask_color = cps.Color( text="Select wedge fill color", value=DEFAULT_MASK_COLOR, doc="""\ The wedge is outlined in this color. Only applies when the result of this module is visualized.""", )
def add_image(self, can_delete=True): '''Add an image and its settings to the list of images''' image_name = cps.ImageNameSubscriber("Select the input image", cps.NONE, doc=''' Select the image to be corrected.''') corrected_image_name = cps.ImageNameProvider("Name the output image", "SpillCorrected", doc=''' Enter a name for the corrected image.''') spill_correct_function_image_name = cps.ImageNameSubscriber( "Select the spillover function image", cps.NONE, doc=''' Select the spillover correction image that will be used to carry out the correction. This image is usually produced by the R software CATALYST or loaded as a .tiff format image using the <b>Images</b> module or <b>LoadSingleImage</b>.''') spill_correct_method = cps.Choice("Spillover correction method", [METHOD_LS, METHOD_NNLS], doc=""" Select the spillover correction method. <ul> <li><i>%(METHOD_LS)s:</i> Gives the least square solution for overdetermined solutions or the exact solution for exactly constraint problems. </li> <li><i>%(METHOD_NNLS)s:</i> Gives the non linear least squares solution: The most accurate solution, according to the least squares criterium, without any negative values. </li> </ul> """ % globals()) image_settings = cps.SettingsGroup() image_settings.append("image_name", image_name) image_settings.append("corrected_image_name", corrected_image_name) image_settings.append("spill_correct_function_image_name", spill_correct_function_image_name) image_settings.append("spill_correct_method", spill_correct_method) if can_delete: image_settings.append( "remover", cps.RemoveSettingButton("", "Remove this image", self.images, image_settings)) image_settings.append("divider", cps.Divider()) self.images.append(image_settings)
def create_settings(self): self.image_name = cps.ImageNameSubscriber('Select the input image', cps.NONE) self.transformed_image_name = cps.ImageNameProvider( "Name the transformed image", 'DistanceImage') self.transform_method = cps.Choice('Select a transformation', [DISTANCE_BORDER], doc=""" <ul> <li><i>%(DISTANCE_BORDER)s</i> Transforms the binary image to an eucledian distance transform to the border between the binary regions. The distance to a nonzero pixel will be positive, while the distance to a zero pixel will be negative.</li> </ul>""" % globals())
def add_output(self, can_remove=True): group = cps.SettingsGroup() group.append("output_image", cps.ImageNameProvider("Output image", "Probability")) group.append( "class_name", cps.Choice("Class name", choices=self.get_class_names(), choices_fn=self.get_class_names)) if can_remove: group.append( "remover", cps.RemoveSettingButton("Remove object", "Remove", self.outputs, group)) self.outputs.append(group)
def create_settings(self): self.image_name = cps.ImageNameSubscriber( "Select the input image", cps.NONE, doc=''' Select the image to be resized.''') self.cropped_image_name = cps.ImageNameProvider( "Name the output image", "CroppedImage", doc=''' Enter the name of the cropped image.''') self.crop_random = cps.Choice( 'Crop random or specified section?', [C_RANDOM, C_SPECIFIC, C_SEED_METADATA]) self.crop_x = cps.Text( "X of upper left corner", '0', doc=''' X position.''', metadata=True) self.crop_y = cps.Text( "Y of upper left corner", '0', doc=''' Y position.''', metadata=True) self.crop_w = cps.Text( "W width", '100', doc=''' Width of cut.''', metadata=True) self.crop_h = cps.Text( "H height", '100', doc=''' Height of cut.''', metadata=True) self.seed_metadata = cps.Text( "Optional Random Seed", '', doc=''' Sets the seed based on this string. Use the `Metadata` module to generate metadata and right click into the field to select metadata.''', metadata=True ) self.separator = cps.Divider(line=False) self.additional_images = [] self.additional_image_count = cps.HiddenCount( self.additional_images, "Additional image count") self.add_button = cps.DoSomething("", "Add another image", self.add_image)
def create_settings(self): self.object_name = cps.ObjectNameSubscriber("Select the input objects", cps.NONE, doc=""" Choose the name of the objects you want to convert to an image.""") self.image_name = cps.ImageNameProvider("Name the output image", "CellImage", doc=""" Enter the name of the resulting image.""") self.image_mode = cps.Choice("Select the color format", IM_ALL, doc=""" Select which colors the resulting image should use. You have the following options: <ul> <li><i>%(IM_COLOR)s:</i> Allows you to choose a colormap that will produce jumbled colors for your objects. </li> <li><i>%(IM_BINARY)s:</i> All object pixels will be assigned 1 and all background pixels will be assigned 0, creating a binary image.</li> <li><i>%(IM_GRAYSCALE)s:</i> Gives each object a graylevel pixel intensity value corresponding to its number (also called label), so it usually results in objects on the left side of the image being very dark, progressing toward white on the right side of the image. </li> <li><i>%(IM_UINT16)s:</i> Assigns each object a different number, from 1 to 65535 (the numbers that you can put in a 16-bit integer) and numbers all pixels in each object with the object's number. This format can be written out as a .mat or .tiff file if you want to process the label matrix image using another program.</li> </ul> You can choose <i>%(IM_COLOR)s</i> with a <i>Gray</i> colormap to produce jumbled gray objects.""" % globals()) self.colormap = cps.Colormap("Select the colormap", doc=""" <i>(Used only if "<i>%(IM_COLOR)s</i>" output image selected)</i><br> Choose the colormap to be used, which affects how the objects are colored. You can look up your default colormap under <i>File > Preferences</i>. """ % globals())
def create_settings(self): self.input_type = cps.Choice("Select the type of input", [IF_IMAGE, IF_OBJECTS], IF_IMAGE) self.image_name = cps.ImageNameSubscriber("Select input images", cps.NONE) self.objects_name = cps.ObjectNameSubscriber( "Select the input objects", cps.NONE, ) self.output_name = cps.ImageNameProvider( "Input the output image stack name", "BinStack", doc=""" Input the output name. """ % globals()) self.main_object_def = cps.Choice( "How should the main label be determined?", [SEL_MID, SEL_MAXAREA, SEL_PROVIDED], SEL_MID, doc=""" The main object can be determined by 3 ways: <ul> <li> %(SEL_PROVIDED)s: Label provided by metadata or manual. <\li> <li> %(SEL_MAXAREA)s: Label with the biggest area is assumed to be the main label. <\li> <li> %(SEL_MID)s: The label closest to the middle of the image is considered the main label. <\li> <\ul> """ % globals()) self.main_object_id = cps.Text("Indicate the object id", '1', doc=""" Indicates the id from the main object. Rightclick to choose a metadata value. """ % globals(), metadata=True)
def create_settings(self): self.image_name = cps.ImageNameSubscriber( "Select the input image",cps.NONE, doc = ''' Select the image to be resized.''') self.cropped_image_name = cps.ImageNameProvider( "Name the output image", "croppedImage", doc = ''' Enter the name of the cropped image.''') self.crop_random = cps.Choice( 'Crop random or specified section?', [C_RANDOM, C_SPECIFIC]) self.crop_x = cps.Text( "X of upper left corner", '0', doc = ''' X position.''', metadata=True) self.crop_y = cps.Text( "Y of upper left corner", '0', doc = ''' Y position.''', metadata=True) self.crop_w = cps.Text( "W width", '100', doc = ''' Width of cut.''', metadata=True) self.crop_h = cps.Text( "H height", '100', doc = ''' Height of cut.''', metadata=True) self.separator = cps.Divider(line=False) self.additional_images = [] self.additional_image_count = cps.HiddenCount( self.additional_images, "Additional image count") self.add_button = cps.DoSomething("", "Add another image", self.add_image)
def __init__(self): self.__spacer = cps.Divider(line=True) self.__operand_choice = cps.Choice( "Measure the area occupied in a binary image, or in objects?", [O_BINARY_IMAGE, O_OBJECTS], doc=""" The area can be measured in two ways: <ul> <li><i>%(O_BINARY_IMAGE)s:</i> The area occupied by the foreground in a binary (black and white) image.</li> <li><i>%(O_OBJECTS)s:</i> The area occupied by previously-identified objects.</li> </ul>""" % globals()) self.__operand_objects = cps.ObjectNameSubscriber( "Select objects to measure", cps.NONE, doc=""" <i>(Used only if '%(O_OBJECTS)s' are to be measured)</i> <br> Select the previously identified objects you would like to measure.""" % globals()) self.__should_save_image = cps.Binary( "Retain a binary image of the object regions?", False, doc=""" <i>(Used only if '%(O_OBJECTS)s' are to be measured)</i><br> Select <i>%(YES)s</i> if you would like to use a binary image later in the pipeline, for example in <b>SaveImages</b>. The image will display the object area that you have measured as the foreground in white and the background in black. """ % globals()) self.__image_name = cps.ImageNameProvider( "Name the output binary image", "Stain", doc=""" <i>(Used only if the binary image of the objects is to be retained for later use in the pipeline)</i> <br> Specify a name that will allow the binary image of the objects to be selected later in the pipeline.""") self.__binary_name = cps.ImageNameSubscriber( "Select a binary image to measure", cps.NONE, doc=""" <i>(Used only if '%(O_BINARY_IMAGE)s' is to be measured)</i><br> This is a binary image created earlier in the pipeline, where you would like to measure the area occupied by the foreground in the image.""" % globals())
def create_settings(self): # # # # # # # # # # # # # # # # Stack settings # # # # # # # # # # # # # # # self.stack_image_name = cps.ImageNameProvider( "Name the output image", "ColorImage", doc="""Enter a name for the resulting image.""") self.stack_channels = [] self.stack_channel_count = cps.HiddenCount(self.stack_channels) self.add_stack_channel_cb(can_remove=False) self.add_stack_channel_cb(can_remove=False) self.add_stack_channel = cps.DoSomething("Add another channel", "Add another channel", self.add_stack_channel_cb, doc="""\ Press this button to add another image to the stack. """)
def create_settings(self): self.image_name = cps.ImageNameSubscriber( 'Select the input image', cps.NONE, doc="Select the images to be made into a projection.") self.projection_type = cps.Choice( 'Type of projection', P_ALL, doc="""\ The final projection image can be created by the following methods: - *%(P_AVERAGE)s:* Use the average pixel intensity at each pixel position. - *%(P_MAXIMUM)s:* Use the maximum pixel value at each pixel position. - *%(P_MINIMUM)s:* Use the minimum pixel value at each pixel position. - *%(P_SUM)s:* Add the pixel values at each pixel position. - *%(P_VARIANCE)s:* Compute the variance at each pixel position. The variance method is described in Selinummi et al (2009). The method is designed to operate on a Z-stack of brightfield images taken at different focus planes. Background pixels will have relatively uniform illumination whereas cytoplasm pixels will have higher variance across the Z-stack. - *%(P_POWER)s:* Compute the power at a given frequency at each pixel position. The power method is experimental. The method computes the power at a given frequency through the Z-stack. It might be used with a phase contrast image where the signal at a given pixel will vary sinusoidally with depth. The frequency is measured in Z-stack steps and pixels that vary with the given frequency will have a higher score than other pixels with similar variance, but different frequencies. - *%(P_BRIGHTFIELD)s:* Perform the brightfield projection at each pixel position. Artifacts such as dust appear as black spots that are most strongly resolved at their focal plane with gradually increasing signals below. The brightfield method scores these as zero since the dark appears in the early Z-stacks. These pixels have a high score for the variance method but have a reduced score when using the brightfield method. - *%(P_MASK)s:* Compute a binary image of the pixels that are masked in any of the input images. The mask method operates on any masks that might have been applied to the images in a group. The output is a binary image where the “1” pixels are those that are not masked in all of the images and the “0” pixels are those that are masked in one or more of the images. You can use the output of the mask method to mask or crop all of the images in a group similarly. Use the mask method to combine all of the masks in a group, save the image and then use **Crop**, **MaskImage** or **MaskObjects** in another pipeline to mask all images or objects in the group similarly. References ^^^^^^^^^^ - Selinummi J, Ruusuvuori P, Podolsky I, Ozinsky A, Gold E, et al. (2009) “Bright field microscopy as an alternative to whole cell fluorescence in automated analysis of macrophage images”, *PLoS ONE* 4(10): e7497 `(link)`_. .. _(link): https://doi.org/10.1371/journal.pone.0007497 """% globals()) self.projection_image_name = cps.ImageNameProvider( 'Name the output image', 'ProjectionBlue', doc="Enter the name for the projected image.", provided_attributes={cps.AGGREGATE_IMAGE_ATTRIBUTE: True, cps.AVAILABLE_ON_LAST_ATTRIBUTE: True}) self.frequency = cps.Float( "Frequency", 6.0, minval=1.0, doc="""\ *(Used only if "%(P_POWER)s" is selected as the projection method)* This setting controls the frequency at which the power is measured. A frequency of 2 will respond most strongly to pixels that alternate between dark and light in successive z-stack slices. A frequency of N will respond most strongly to pixels whose brightness cycles every N slices.""" % globals())
def create_settings(self): self.image_name = cps.ImageNameSubscriber( "Select the input image", cps.NONE, doc='''Select the image whose edges you want to enhance.''') self.output_image_name = cps.ImageNameProvider( "Name the output image", "EdgedImage", doc='''Enter a name for the resulting image with edges enhanced.''') self.method = cps.Choice( "Select an edge-finding method", [M_SOBEL, M_PREWITT, M_ROBERTS, M_LOG, M_CANNY, M_KIRSCH], doc='''\ There are several methods that can be used to enhance edges. Often, it is best to test them against each other empirically: - *%(M_SOBEL)s:* Finds edges using the %(M_SOBEL)s approximation to the derivative. The %(M_SOBEL)s method derives a horizontal and vertical gradient measure and returns the square-root of the sum of the two squared signals. - *%(M_PREWITT)s:* Finds edges using the %(M_PREWITT)s approximation to the derivative. It returns edges at those points where the gradient of the image is maximum. - *%(M_ROBERTS)s:* Finds edges using the Roberts approximation to the derivative. The %(M_ROBERTS)s method looks for gradients in the diagonal and anti-diagonal directions and returns the square-root of the sum of the two squared signals. This method is fast, but it creates diagonal artifacts that may need to be removed by smoothing. - *%(M_LOG)s:* Applies a Laplacian of Gaussian filter to the image and finds zero crossings. - *%(M_CANNY)s:* Finds edges by looking for local maxima of the gradient of the image. The gradient is calculated using the derivative of a Gaussian filter. The method uses two thresholds to detect strong and weak edges, and includes the weak edges in the output only if they are connected to strong edges. This method is therefore less likely than the others to be fooled by noise, and more likely to detect true weak edges. - *%(M_KIRSCH)s:* Finds edges by calculating the gradient among the 8 compass points (North, North-east, etc.) and selecting the maximum as the pixel’s value. ''' % globals()) self.wants_automatic_threshold = cps.Binary( "Automatically calculate the threshold?", True, doc='''\ *(Used only with the "%(M_CANNY)s" option and automatic thresholding)* Select *%(YES)s* to automatically calculate the threshold using a three-category Otsu algorithm performed on the Sobel transform of the image. Select *%(NO)s* to manually enter the threshold value. ''' % globals()) self.manual_threshold = cps.Float( "Absolute threshold", 0.2, 0, 1, doc='''\ *(Used only with the "%(M_CANNY)s" option and manual thresholding)* The upper cutoff for Canny edges. All Sobel-transformed pixels with this value or higher will be marked as an edge. You can enter a threshold between 0 and 1. ''' % globals()) self.threshold_adjustment_factor = cps.Float( "Threshold adjustment factor", 1, doc='''\ *(Used only with the "%(M_CANNY)s" option and automatic thresholding)* This threshold adjustment factor is a multiplier that is applied to both the lower and upper Canny thresholds if they are calculated automatically. An adjustment factor of 1 indicates no adjustment. The adjustment factor has no effect on any threshold entered manually. ''' % globals()) self.direction = cps.Choice( "Select edge direction to enhance", [E_ALL, E_HORIZONTAL, E_VERTICAL], doc='''\ *(Used only with "%(M_PREWITT)s" and "%(M_SOBEL)s" methods)* Select the direction of the edges you aim to identify in the image (predominantly horizontal, predominantly vertical, or both). ''' % globals()) self.wants_automatic_sigma = cps.Binary("Calculate Gaussian's sigma automatically?", True, doc="""\ Select *%(YES)s* to automatically calculate the Gaussian's sigma. Select *%(NO)s* to manually enter the value. """ % globals()) self.sigma = cps.Float("Gaussian's sigma value", 10, doc="""Set a value for Gaussian's sigma.""") self.wants_automatic_low_threshold = cps.Binary( "Calculate value for low threshold automatically?", True, doc="""\ *(Used only with the "%(M_CANNY)s" option and automatic thresholding)* Select *%(YES)s* to automatically calculate the low / soft threshold cutoff for the %(M_CANNY)s method. Select *%(NO)s* to manually enter the low threshold value. """ % globals()) self.low_threshold = cps.Float( "Low threshold value", 0.1, 0, 1, doc="""\ *(Used only with the "%(M_CANNY)s" option and manual thresholding)* Enter the soft threshold cutoff for the %(M_CANNY)s method. The %(M_CANNY)s method will mark all %(M_SOBEL)s-transformed pixels with values below this threshold as not being edges. """ % globals())
def create_settings(self): self.image_name = cps.ImageNameSubscriber("Select the input image", cps.NONE) self.output_name = cps.ImageNameProvider("Name the output image", "FlippedOrigBlue") self.flip_choice = cps.Choice("Select method to flip image", FLIP_ALL, doc=""" Select how the image is to be flipped.""") self.rotate_choice = cps.Choice("Select method to rotate image", ROTATE_ALL, doc=''' <ul> <li><i>%(ROTATE_NONE)s:</i> Leave the image unrotated. This should be used if you want to flip the image only.</li> <li><i>%(ROTATE_ANGLE)s:</i> Provide the numerical angle by which the image should be rotated.</li> <li><i>%(ROTATE_COORDINATES)s:</i> Provide the X,Y pixel locations of two points in the image that should be aligned horizontally or vertically.</li> <li><i>%(ROTATE_MOUSE)s:</i> CellProfiler will pause so you can select the rotation interactively. When prompted during the analysis run, grab the image by clicking the left mouse button, rotate the image by dragging with the mouse, then release the mouse button. Press the <i>Done</i> button on the image after rotating the image appropriately.</li> </ul>''' % globals()) self.wants_crop = cps.Binary("Crop away the rotated edges?", True, doc=''' <i>(Used only when rotating images)</i> <br> When an image is rotated, there will be black space at the corners/edges; select <i>%(YES)s</i> to crop away the incomplete rows and columns of the image, or select <i>%(NO)s</i> to leave it as-is. <p>This cropping will produce an image that is not exactly the same size as the original, which may affect downstream modules.</p>''' % globals()) self.how_often = cps.Choice("Calculate rotation", IO_ALL, doc=''' <i>(Used only when using "%(ROTATE_MOUSE)s" to rotate images)</i> <br> Select the cycle(s) at which the calculation is requested and calculated. <ul> <li><i>%(IO_INDIVIDUALLY)s:</i> Determine the amount of rotation for each image individually, e.g., for each cycle.</li> <li><i>%(IO_ONCE)s:</i> Define the rotation only once (on the first image), then then apply it to all images.</li> </ul>''' % globals()) self.first_pixel = cps.Coordinates( "Enter coordinates of the top or left pixel", (0, 0)) self.second_pixel = cps.Coordinates( "Enter the coordinates of the bottom or right pixel", (0, 100)) self.horiz_or_vert = cps.Choice( "Select how the specified points should be aligned", C_ALL, doc=""" <i>(Used only when using "%(ROTATE_COORDINATES)s" to rotate images)</i><br> Specify whether you would like the coordinate points that you entered to be horizontally or vertically aligned after the rotation is complete.""" % globals()) self.angle = cps.Float("Enter angle of rotation", 0, doc=""" <i>(Used only when using "%(ROTATE_ANGLE)s" to rotate images)</i> <br> Enter the angle you would like to rotate the image. This setting is in degrees, with positive angles corresponding to counterclockwise and negative as clockwise.""" % globals())
def add_image(self, can_remove=True): group = cps.SettingsGroup() group.can_remove = can_remove if can_remove: group.append("divider", cps.Divider()) idx = len(self.outputs) default_name = STAINS_BY_POPULARITY[idx % len(STAINS_BY_POPULARITY)] default_name = default_name.replace(" ", "") group.append("image_name", cps.ImageNameProvider( "Name the output name", default_name, doc="""\ Use this setting to name one of the images produced by the module for a particular stain. The image can be used in subsequent modules in the pipeline. """)) choices = list(sorted(STAIN_DICTIONARY.keys())) + [CHOICE_CUSTOM] group.append("stain_choice", cps.Choice( "Stain", choices=choices, doc="""\ Use this setting to choose the absorbance values for a particular stain. The stains are: +-----------------------------------+--------------------------------------------------+ | Stain |Specific to | +===================================+==================================================+ | AEC (3-Amino-9-ethylcarbazole) |Peroxidase | +-----------------------------------+--------------------------------------------------+ | Alican blue |Mucopolysaccharides | +-----------------------------------+--------------------------------------------------+ | Aniline blue |Pollen tubes | +-----------------------------------+--------------------------------------------------+ | Azocarmine |Plasma | +-----------------------------------+--------------------------------------------------+ | DAB |Peroxisomes, mitochondria | +-----------------------------------+--------------------------------------------------+ | Eosin |Elastic, collagen and reticular fibers | +-----------------------------------+--------------------------------------------------+ | Fast red |Nuclei | +-----------------------------------+--------------------------------------------------+ | Fast blue |Myelin fibers | +-----------------------------------+--------------------------------------------------+ | Feulgen |DNA | +-----------------------------------+--------------------------------------------------+ | Hematoxylin |Nucleic acids, endoplasmic reticulum | +-----------------------------------+--------------------------------------------------+ | Hematoxylin and PAS |Nucleus (stained with both Hematoxylin and PAS) | +-----------------------------------+--------------------------------------------------+ | Methyl blue |Collagen | +-----------------------------------+--------------------------------------------------+ | Methyl green |Chromatin | +-----------------------------------+--------------------------------------------------+ | Methylene blue |Nuclei | +-----------------------------------+--------------------------------------------------+ | Orange G |Erythrocytes, pancreas, pituitary | +-----------------------------------+--------------------------------------------------+ | PAS |Glycogen, carbohydrates | +-----------------------------------+--------------------------------------------------+ | Ponceau Fuchsin |Red counterstain for Masson’s trichrome | +-----------------------------------+--------------------------------------------------+ (Information taken from `here`_, `here <http://en.wikipedia.org/wiki/Staining>`__, and `here <http://stainsfile.info>`__.) You can choose *%(CHOICE_CUSTOM)s* and enter your custom values for the absorbance (or use the estimator to determine values from a single-stain image). .. _here: http://en.wikipedia.org/wiki/Histology#Staining """ % globals())) group.append("red_absorbance", cps.Float( "Red absorbance", 0.5, 0, 1, doc="""\ *(Used only if "%(CHOICE_CUSTOM)s" is selected for the stain)* The red absorbance setting estimates the dye’s absorbance of light in the red channel.You should enter a value between 0 and 1 where 0 is no absorbance and 1 is complete absorbance. You can use the estimator to calculate this value automatically. """ % globals())) group.append("green_absorbance", cps.Float( "Green absorbance", 0.5, 0, 1, doc="""\ *(Used only if "%(CHOICE_CUSTOM)s" is selected for the stain)* The green absorbance setting estimates the dye’s absorbance of light in the green channel. You should enter a value between 0 and 1 where 0 is no absorbance and 1 is complete absorbance. You can use the estimator to calculate this value automatically. """ % globals())) group.append("blue_absorbance", cps.Float( "Blue absorbance", 0.5, 0, 1, doc="""\ *(Used only if "%(CHOICE_CUSTOM)s" is selected for the stain)* The blue absorbance setting estimates the dye’s absorbance of light in the blue channel. You should enter a value between 0 and 1 where 0 is no absorbance and 1 is complete absorbance. You can use the estimator to calculate this value automatically. """ % globals())) def on_estimate(): result = self.estimate_absorbance() if result is not None: (group.red_absorbance.value, group.green_absorbance.value, group.blue_absorbance.value) = result group.append("estimator_button", cps.DoSomething( "Estimate absorbance from image", "Estimate", on_estimate, doc="""\ Press this button to load an image of a sample stained only with the dye of interest. **UnmixColors** will estimate appropriate red, green and blue absorbance values from the image. """)) if can_remove: group.append("remover", cps.RemoveSettingButton( "", "Remove this image", self.outputs, group)) self.outputs.append(group)
def create_settings(self): """Create your settings by subclassing this function create_settings is called at the end of initialization. """ self.grid_image = cps.GridNameProvider("Name the grid", doc="""\ This is the name of the grid. You can use this name to retrieve the grid in subsequent modules.""") self.grid_rows = cps.Integer( "Number of rows", 8, 1, doc="""Along the height of the grid, define the number of rows""") self.grid_columns = cps.Integer( "Number of columns", 12, 1, doc="""Along the width of the grid, define the number of columns""" ) self.origin = cps.Choice( "Location of the first spot", [NUM_TOP_LEFT, NUM_BOTTOM_LEFT, NUM_TOP_RIGHT, NUM_BOTTOM_RIGHT], doc="""\ Grid cells are numbered consecutively; this option identifies the origin for the numbering system and the direction for numbering. For instance, if you choose "*%(NUM_TOP_LEFT)s*", the top left cell is cell #1 and cells to the right and bottom are indexed with larger numbers.""" % globals()) self.ordering = cps.Choice("Order of the spots", [NUM_BY_ROWS, NUM_BY_COLUMNS], doc="""\ Grid cells can either be numbered by rows, then columns or by columns, then rows. For instance, you might ask to start numbering a 96-well plate at the top left (by specifying the location of the first spot). - *%(NUM_BY_ROWS)s:* This option will give well A01 the index 1, B01 the index 2, and so on up to H01 which receives the index 8. Well A02 will be assigned the index 9. - *%(NUM_BY_COLUMNS)s:* With this option, the well A02 will be assigned 2, well A12 will be assigned 12 and well B01 will be assigned 13. """ % globals()) self.each_or_once = cps.Choice("Define a grid for which cycle?", [EO_EACH, EO_ONCE], doc="""\ The setting allows you choose when you want to define a new grid: - *%(EO_ONCE)s:* If all of your images are perfectly aligned with each other (due to very consistent image acquisition, consistent grid location within the plate, and/or automatic cropping precisely within each plate), you can define the location of the marker spots once for all of the image cycles. - *%(EO_EACH)s:* If the location of the grid will vary from one image cycle to the next then you should define the location of the marker spots for each cycle independently. """ % globals()) self.auto_or_manual = cps.Choice( "Select the method to define the grid", [AM_AUTOMATIC, AM_MANUAL], doc="""\ Select whether you would like to define the grid automatically (based on objects you have identified in a previous module) or manually. This setting controls how the grid is defined: - *%(AM_MANUAL)s:* In manual mode, you manually indicate known locations of marker spots in the grid and have the rest of the positions calculated from those marks, no matter what the image itself looks like. You can define the grid either by clicking on the image with a mouse or by entering coordinates. - *%(AM_AUTOMATIC)s:* If you would like the grid to be defined automatically, an **IdentifyPrimaryObjects** module must be run prior to this module to identify the objects which will be used to define the grid. The left-most, right-most, top-most, and bottom-most object will be used to define the edges of the grid, and the rows and columns will be evenly spaced between these edges. Note that Automatic mode requires that the incoming objects are nicely defined: for example, if there is an object at the edge of the images that is not really an object that ought to be in the grid, a skewed grid will result. You might wish to use a **FilterObjects** module to clean up badly identified objects prior to defining the grid. If the spots are slightly out of alignment with each other from one image cycle to the next, this allows the identification to be a bit flexible and adapt to the real location of the spots. """ % globals()) self.object_name = cps.ObjectNameSubscriber( "Select the previously identified objects", cps.NONE, doc="""\ *(Used only if you selected "%(AM_AUTOMATIC)s" to define the grid)* Select the previously identified objects you want to use to define the grid. Use this setting to specify the name of the objects that will be used to define the grid. """ % globals()) self.manual_choice = cps.Choice( "Select the method to define the grid manually", [MAN_MOUSE, MAN_COORDINATES], doc="""\ *(Used only if you selected "%(AM_MANUAL)s" to define the grid)* Specify whether you want to define the grid using the mouse or by entering the coordinates of the cells. - *%(MAN_MOUSE)s:* The user interface displays the image you specify. You will be asked to click in the center of two of the grid cells and specify the row and column for each. The grid coordinates will be computed from this information. - *%(MAN_COORDINATES)s:* Enter the X and Y coordinates of the grid cells directly. You can display an image of your grid to find the locations of the centers of the cells, then enter the X and Y position and cell coordinates for each of two cells. """ % globals()) self.manual_image = cps.ImageNameSubscriber( "Select the image to display", cps.NONE, doc="""\ *(Used only if you selected "%(AM_MANUAL)s" and "%(MAN_MOUSE)s" to define the grid)* Specify the image you want to display when defining the grid. This setting lets you choose the image to display in the grid definition user interface. """ % globals()) self.first_spot_coordinates = cps.Coordinates( "Coordinates of the first cell", (0, 0), doc="""\ *(Used only if you selected "%(AM_MANUAL)s" and "%(MAN_COORDINATES)s" to define the grid)* Enter the coordinates of the first cell on your grid. This setting defines the location of the first of two cells in your grid. You should enter the coordinates of the center of the cell. You can display an image of your grid and use the pixel coordinate display to determine the coordinates of the center of your cell. """ % globals()) self.first_spot_row = cps.Integer("Row number of the first cell", 1, minval=1, doc="""\ *(Used only if you selected "%(AM_MANUAL)s" and "%(MAN_COORDINATES)s" to define the grid)* Enter the row index for the first cell here. Rows are numbered starting at the origin. For instance, if you chose "*%(NUM_TOP_LEFT)s*" as your origin, well A01 will be row number 1 and H01 will be row number 8. If you chose "*%(NUM_BOTTOM_LEFT)s*", A01 will be row number 8 and H01 will be row number 12. """ % globals()) self.first_spot_col = cps.Integer("Column number of the first cell", 1, minval=1, doc="""\ *(Used only if you selected "%(AM_MANUAL)s" and "%(MAN_COORDINATES)s" to define the grid)* Enter the column index for the first cell here. Columns are numbered starting at the origin. For instance, if you chose "*%(NUM_TOP_LEFT)s*" as your origin, well A01 will be column number *1* and A12 will be column number *12*. If you chose "*%(NUM_TOP_RIGHT)s*", A01 and A12 will be *12* and *1*, respectively. """ % globals()) self.second_spot_coordinates = cps.Coordinates( "Coordinates of the second cell", (0, 0), doc="""\ *(Used only if you selected "%(AM_MANUAL)s" and "%(MAN_COORDINATES)s" to define the grid)* This setting defines the location of the second of two cells in your grid. You should enter the coordinates of the center of the cell. You can display an image of your grid and use use the pixel coordinate display to determine the coordinates of the center of your cell. """ % globals()) self.second_spot_row = cps.Integer("Row number of the second cell", 1, minval=1, doc="""\ *(Used only if you selected "%(AM_MANUAL)s" and "%(MAN_COORDINATES)s" to define the grid)* Enter the row index for the second cell here. Rows are numbered starting at the origin. For instance, if you chose "*%(NUM_TOP_LEFT)s*" as your origin, well A01 will be row number 1 and H01 will be row number 8. If you chose "*%(NUM_BOTTOM_LEFT)s*", A01 will be row number 8 and H01 will be row number 12. """ % globals()) self.second_spot_col = cps.Integer("Column number of the second cell", 1, minval=1, doc="""\ *(Used only if you selected "%(AM_MANUAL)s" and "%(MAN_COORDINATES)s" to define the grid)* Enter the column index for the second cell here. Columns are numbered starting at the origin. For instance, if you chose "*%(NUM_TOP_LEFT)s*" as your origin, well A01 will be column number 1 and A12 will be column number 12. If you chose "*%(NUM_TOP_RIGHT)s*", A01 and A12 will be 12 and 1, respectively. """ % globals()) self.wants_image = cps.Binary("Retain an image of the grid?", False, doc="""\ Select "*%(YES)s*" to retain an image of the grid for use later in the pipeline. This module can create an annotated image of the grid that can be saved using the **SaveImages** module. """ % globals()) self.display_image_name = cps.ImageNameSubscriber( "Select the image on which to display the grid", cps.LEAVE_BLANK, can_be_blank=True, doc="""\ *(Used only if saving an image of the grid)* Enter the name of the image that should be used as the background for annotations (grid lines and grid indexes). This image will be used for the figure and for the saved image. """) self.save_image_name = cps.ImageNameProvider("Name the output image", "Grid", doc="""\ *(Used only if retaining an image of the grid for use later in the pipeline)* Enter the name you want to use for the output image. You can save this image using the **SaveImages** module. """) self.failed_grid_choice = cps.Choice( "Use a previous grid if gridding fails?", [FAIL_NO, FAIL_ANY_PREVIOUS, FAIL_FIRST], doc="""\ If the gridding fails, this setting allows you to control how the module responds to the error: - *%(FAIL_NO)s:* The module will stop the pipeline if gridding fails. - *%(FAIL_ANY_PREVIOUS)s:*: The module will use the the most recent successful gridding. - *%(FAIL_FIRST)s:* The module will use the first gridding. Note that the pipeline will stop in all cases if gridding fails on the first image. """ % globals())
def create_settings(self): self.image_name = cps.ImageNameSubscriber( "Select the input image", cps.NONE, doc="""Select the multichannel image you want to convert to grayscale.""") self.combine_or_split = cps.Choice( "Conversion method", [COMBINE, SPLIT], doc='''\ How do you want to convert the color image? - *%(SPLIT)s:* Splits the channels of a color image (e.g., red, green, blue) into separate grayscale images. - *%(COMBINE)s:* Converts a color image to a grayscale image by combining channels together (e.g., red, green, blue).''' % globals()) self.rgb_or_channels = cps.Choice( "Image type", [CH_RGB, CH_HSV, CH_CHANNELS], doc="""\ This setting provides three options to choose from: - *%(CH_RGB)s:* The RGB (red, green, blue) color space is the typical model in which color images are stored. Choosing this option will split the image into red, green, and blue component images. - *%(CH_HSV)s:* The HSV (hue, saturation, value) color space is based on color characteristics such as tint, shade, and tone. Choosing this option will split the image into the hue, saturation, and value component images. - *%(CH_CHANNELS)s:* Many images contain color channels other than RGB or HSV. For instance, GIF and PNG formats can have an alpha channel that encodes transparency. TIF formats can have an arbitrary number of channels which represent pixel measurements made by different detectors, filters or lighting conditions. This setting allows you to handle a more complex model for images that have more than three channels.""" % globals()) # The following settings are used for the combine option self.grayscale_name = cps.ImageNameProvider( "Name the output image", "OrigGray", doc="""\ *(Used only when combining channels)* Enter a name for the resulting grayscale image.""") self.red_contribution = cps.Float( "Relative weight of the red channel", 1, 0, doc='''\ *(Used only when combining channels)* Relative weights: If all relative weights are equal, all three colors contribute equally in the final image. To weight colors relative to each other, increase or decrease the relative weights.''') self.green_contribution = cps.Float( "Relative weight of the green channel", 1, 0, doc='''\ *(Used only when combining channels)* Relative weights: If all relative weights are equal, all three colors contribute equally in the final image. To weight colors relative to each other, increase or decrease the relative weights.''') self.blue_contribution = cps.Float( "Relative weight of the blue channel", 1, 0, doc='''\ *(Used only when combining channels)* Relative weights: If all relative weights are equal, all three colors contribute equally in the final image. To weight colors relative to each other, increase or decrease the relative weights.''') # The following settings are used for the split RGB option self.use_red = cps.Binary('Convert red to gray?', True, doc="""\ *(Used only when splitting RGB images)* Select *"%(YES)s"* to extract the red channel to grayscale. Otherwise, the red channel will be ignored. """ % globals()) self.red_name = cps.ImageNameProvider('Name the output image', "OrigRed", doc="""\ *(Used only when splitting RGB images)* Enter a name for the resulting grayscale image coming from the red channel.""") self.use_green = cps.Binary('Convert green to gray?', True, doc="""\ *(Used only when splitting RGB images)* Select *"%(YES)s"* to extract the green channel to grayscale. Otherwise, the green channel will be ignored. """ % globals()) self.green_name = cps.ImageNameProvider('Name the output image', "OrigGreen", doc="""\ *(Used only when splitting RGB images)* Enter a name for the resulting grayscale image coming from the green channel.""") self.use_blue = cps.Binary('Convert blue to gray?', True, doc="""\ *(Used only when splitting RGB images)* Select *"%(YES)s"* to extract the blue channel to grayscale. Otherwise, the blue channel will be ignored. """ % globals()) self.blue_name = cps.ImageNameProvider('Name the output image', "OrigBlue", doc="""\ *(Used only when splitting RGB images)* Enter a name for the resulting grayscale image coming from the blue channel.""") # The following settings are used for the split HSV ption self.use_hue = cps.Binary('Convert hue to gray?', True, doc="""\ *(Used only when splitting HSV images)* Select *"%(YES)s"* to extract the hue to grayscale. Otherwise, the hue will be ignored. """ % globals()) self.hue_name = cps.ImageNameProvider('Name the output image', "OrigHue", doc="""\ *(Used only when splitting HSV images)* Enter a name for the resulting grayscale image coming from the hue.""") self.use_saturation = cps.Binary('Convert saturation to gray?', True, doc="""\ *(Used only when splitting HSV images)* Select *"%(YES)s"* to extract the saturation to grayscale. Otherwise, the saturation will be ignored. """ % globals()) self.saturation_name = cps.ImageNameProvider('Name the output image', "OrigSaturation", doc="""\ *(Used only when splitting HSV images)* Enter a name for the resulting grayscale image coming from the saturation.""") self.use_value = cps.Binary('Convert value to gray?', True, doc="""\ *(Used only when splitting HSV images)* Select *"%(YES)s"* to extract the value to grayscale. Otherwise, the value will be ignored. """ % globals()) self.value_name = cps.ImageNameProvider('Name the output image', "OrigValue", doc="""\ *(Used only when splitting HSV images)* Enter a name for the resulting grayscale image coming from the value.""") # The alternative model: self.channels = [] self.add_channel(False) self.channel_button = cps.DoSomething( "", "Add another channel", self.add_channel) self.channel_count = cps.HiddenCount(self.channels, "Channel count")
def create_settings(self): self.image_name = cps.ImageNameSubscriber( 'Select the input image', cps.NONE, doc="""Select the image to be smoothed.""") self.filtered_image_name = cps.ImageNameProvider( 'Name the output image', 'FilteredImage', doc="""Enter a name for the resulting image.""") self.smoothing_method = cps.Choice('Select smoothing method', [ FIT_POLYNOMIAL, GAUSSIAN_FILTER, MEDIAN_FILTER, SMOOTH_KEEPING_EDGES, CIRCULAR_AVERAGE_FILTER, SM_TO_AVERAGE ], doc="""\ This module smooths images using one of several filters. Fitting a polynomial is fastest but does not allow a very tight fit compared to the other methods: - *%(FIT_POLYNOMIAL)s:* This method is fastest but does not allow a very tight “fit” compared to the other methods. Thus, it will usually be less accurate. The method treats the intensity of the image pixels as a polynomial function of the x and y position of each pixel. It fits the intensity to the polynomial, *A x* :sup:`2` *+ B y* :sup:`2` *+ C xy + D x + E y + F*. This will produce a smoothed image with a single peak or trough of intensity that tapers off elsewhere in the image. For many microscopy images (where the illumination of the lamp is brightest in the center of field of view), this method will produce an image with a bright central region and dimmer edges. But, in some cases the peak/trough of the polynomial may actually occur outside of the image itself. - *%(GAUSSIAN_FILTER)s:* This method convolves the image with a Gaussian whose full width at half maximum is the artifact diameter entered. Its effect is to blur and obscure features smaller than the specified diameter and spread bright or dim features larger than the specified diameter. - *%(MEDIAN_FILTER)s:* This method finds the median pixel value within the diameter you specify. It removes bright or dim features that are significantly smaller than the specified diameter. - *%(SMOOTH_KEEPING_EDGES)s:* This method uses a bilateral filter which limits Gaussian smoothing across an edge while applying smoothing perpendicular to an edge. The effect is to respect edges in an image while smoothing other features. *%(SMOOTH_KEEPING_EDGES)s* will filter an image with reasonable speed for artifact diameters greater than 10 and for intensity differences greater than 0.1. The algorithm will consume more memory and operate more slowly as you lower these numbers. - *%(CIRCULAR_AVERAGE_FILTER)s:* This method convolves the image with a uniform circular averaging filter whose size is the artifact diameter entered. This filter is useful for re-creating an out-of-focus blur to an image. - *%(SM_TO_AVERAGE)s:* Creates a flat, smooth image where every pixel of the image equals the average value of the original image. *Note, when deciding between %(MEDIAN_FILTER)s and %(GAUSSIAN_FILTER)s we typically recommend %(MEDIAN_FILTER)s over %(GAUSSIAN_FILTER)s because the median is less sensitive to outliers, although the results are also slightly less smooth and the fact that images are in the range of 0 to 1 means that outliers typically will not dominate too strongly anyway.* """ % globals()) self.wants_automatic_object_size = cps.Binary( 'Calculate artifact diameter automatically?', True, doc="""\ *(Used only if “%(GAUSSIAN_FILTER)s”, “%(MEDIAN_FILTER)s”, “%(SMOOTH_KEEPING_EDGES)s” or “%(CIRCULAR_AVERAGE_FILTER)s” is selected)* Select *%(YES)s* to choose an artifact diameter based on the size of the image. The minimum size it will choose is 30 pixels, otherwise the size is 1/40 of the size of the image. Select *%(NO)s* to manually enter an artifact diameter. """ % globals()) self.object_size = cps.Float('Typical artifact diameter', 16.0, doc="""\ *(Used only if choosing the artifact diameter automatically is set to “%(NO)s”)* Enter the approximate diameter (in pixels) of the features to be blurred by the smoothing algorithm. This value is used to calculate the size of the spatial filter. %(HELP_ON_MEASURING_DISTANCES)s For most smoothing methods, selecting a diameter over ~50 will take substantial amounts of time to process. """ % globals()) self.sigma_range = cps.Float('Edge intensity difference', 0.1, doc="""\ *(Used only if “%(SMOOTH_KEEPING_EDGES)s” is selected)* Enter the intensity step (which indicates an edge in an image) that you want to preserve. Edges are locations where the intensity changes precipitously, so this setting is used to adjust the rough magnitude of these changes. A lower number will preserve weaker edges. A higher number will preserve only stronger edges. Values should be between zero and one. %(HELP_ON_PIXEL_INTENSITIES)s """ % globals()) self.clip = cps.Binary('Clip intensities to 0 and 1?', True, doc="""\ *(Used only if "%(FIT_POLYNOMIAL)s" is selected)* The *%(FIT_POLYNOMIAL)s* method is the only smoothing option that can yield an output image whose values are outside of the values of the input image. This setting controls whether to limit the image intensity to the 0 - 1 range used by CellProfiler. Select *%(YES)s* to set all output image pixels less than zero to zero and all pixels greater than one to one. Select *%(NO)s* to allow values less than zero and greater than one in the output image. """ % globals())
def create_settings(self): '''Create the UI settings for the module''' self.seed_objects_name = cps.ObjectNameSubscriber( "Select the seed objects", cps.NONE, doc="""\ Select the previously identified objects that you want to use as the seeds for measuring branches and distances. Branches and trunks are assigned per seed object. Seed objects are typically not single points/pixels but instead are usually objects of varying sizes.""") self.image_name = cps.ImageNameSubscriber( "Select the skeletonized image", cps.NONE, doc="""\ Select the skeletonized image of the dendrites and/or axons as produced by the **Morph** module’s *Skel* operation.""") self.wants_branchpoint_image = cps.Binary( "Retain the branchpoint image?", False, doc="""\ Select "*%(YES)s*" if you want to save the color image of branchpoints and trunks. This is the image that is displayed in the output window for this module.""" % globals()) self.branchpoint_image_name = cps.ImageNameProvider( "Name the branchpoint image", "BranchpointImage", doc="""\ *(Used only if a branchpoint image is to be retained)* Enter a name for the branchpoint image here. You can then use this image in a later module, such as **SaveImages**.""") self.wants_to_fill_holes = cps.Binary("Fill small holes?", True, doc="""\ The algorithm reskeletonizes the image and this can leave artifacts caused by small holes in the image prior to skeletonizing. These holes result in false trunks and branchpoints. Select "*%(YES)s*" to fill in these small holes prior to skeletonizing.""" % globals()) self.maximum_hole_size = cps.Integer("Maximum hole size", 10, minval=1, doc="""\ *(Used only when filling small holes)* This is the area of the largest hole to fill, measured in pixels. The algorithm will fill in any hole whose area is this size or smaller.""") self.wants_objskeleton_graph = cps.Binary( "Export the skeleton graph relationships?", False, doc="""\ Select "*%(YES)s*" to produce an edge file and a vertex file that gives the relationships between vertices (trunks, branchpoints and endpoints).""" % globals()) self.intensity_image_name = cps.ImageNameSubscriber("Intensity image", cps.NONE, doc="""\ Select the image to be used to calculate the total intensity along the edges between the vertices (trunks, branchpoints, and endpoints).""" ) self.directory = cps.DirectoryPath( "File output directory", doc= 'Select the directory you want to save the graph relationships to.', dir_choices=[ cps.DEFAULT_OUTPUT_FOLDER_NAME, cps.DEFAULT_INPUT_FOLDER_NAME, cps.ABSOLUTE_FOLDER_NAME, cps.DEFAULT_OUTPUT_SUBFOLDER_NAME, cps.DEFAULT_INPUT_SUBFOLDER_NAME ]) self.directory.dir_choice = cps.DEFAULT_OUTPUT_FOLDER_NAME self.vertex_file_name = cps.Text("Vertex file name", "vertices.csv", doc="""\ *(Used only when exporting graph relationships)* Enter the name of the file that will hold the edge information. You can use metadata tags in the file name. Each line of the file is a row of comma-separated values. The first row is the header; this names the file’s columns. Each subsequent row represents a vertex in the skeleton graph: either a trunk, a branchpoint or an endpoint. The file has the following columns: - *image\_number:* The image number of the associated image. - *vertex\_number:* The number of the vertex within the image. - *i:* The I coordinate of the vertex. - *j:* The J coordinate of the vertex. - *label:* The label of the seed object associated with the vertex. - *kind:* The vertex type, with the following choices: - **T:** Trunk - **B:** Branchpoint - **E:** Endpoint """) self.edge_file_name = cps.Text("Edge file name", "edges.csv", doc="""\ *(Used only when exporting graph relationships)* Enter the name of the file that will hold the edge information. You can use metadata tags in the file name. Each line of the file is a row of comma-separated values. The first row is the header; this names the file’s columns. Each subsequent row represents an edge or connection between two vertices (including between a vertex and itself for certain loops). Note that vertices include trunks, branchpoints, and endpoints. The file has the following columns: - *image\_number:* The image number of the associated image. - *v1:* The zero-based index into the vertex table of the first vertex in the edge. - *v2:* The zero-based index into the vertex table of the second vertex in the edge. - *length:* The number of pixels in the path connecting the two vertices, including both vertex pixels. - *total\_intensity:* The sum of the intensities of the pixels in the edge, including both vertex pixel intensities. """)
def create_settings(self): self.image_name = cps.ImageNameSubscriber("Select the input image", cps.NONE, doc=''' Select the image to be resized.''') self.resized_image_name = cps.ImageNameProvider( "Name the output image", "ResizedBlue", doc=''' Enter the name of the resized image.''') self.size_method = cps.Choice("Resizing method", R_ALL, doc=""" The following options are available: <ul> <li><i>Resize by a fraction or multiple of the original size:</i> Enter a single value which specifies the scaling. </li> <li><i>Resize by specifying desired final dimensions:</i></li> Enter the new height and width of the resized image.</ul>""") self.resizing_factor = cps.Float("Resizing factor", 0.25, minval=0, doc=''' <i>(Used only if resizing by a fraction or multiple of the original size)</i><br> Numbers less than one (that is, fractions) will shrink the image; numbers greater than one (that is, multiples) will enlarge the image.''' ) self.use_manual_or_image = cps.Choice( "Method to specify the dimensions", C_ALL, doc=""" <i>(Used only if resizing by specifying the dimensions)</i><br> You have two options on how to resize your image: <ul> <li><i>%(C_MANUAL)s:</i> Specify the height and width of the output image.</li> <li><i>>%(C_IMAGE)s::</i> Specify an image and the input image will be resized to the same dimensions.</li> </ul>""" % globals()) self.specific_width = cps.Integer("Width of the final image", 100, minval=1, doc=''' <i>(Used only if resizing by specifying desired final dimensions)</i><br> Enter the desired width of the final image, in pixels.''') self.specific_height = cps.Integer("Height of the final image", 100, minval=1, doc=''' <i>(Used only if resizing by specifying desired final dimensions)</i><br> Enter the desired height of the final image, in pixels.''') self.specific_image = cps.ImageNameSubscriber( "Select the image with the desired dimensions", cps.NONE, doc="""" <i>(Used only if resizing by specifying desired final dimensions using an image)</i><br> The input image will be resized to the dimensions of the specified image.""" ) self.interpolation = cps.Choice("Interpolation method", I_ALL, doc=''' <ul><li><i>Nearest Neighbor:</i> Each output pixel is given the intensity of the nearest corresponding pixel in the input image.</li> <li><i>Bilinear:</i> Each output pixel is given the intensity of the weighted average of the 2x2 neighborhood at the corresponding position in the input image.</li> <li><i>Bicubic:</i> Each output pixel is given the intensity of the weighted average of the 4x4 neighborhood at the corresponding position in the input image.</li> </ul>''') self.separator = cps.Divider(line=False) self.additional_images = [] self.additional_image_count = cps.HiddenCount( self.additional_images, "Additional image count") self.add_button = cps.DoSomething("", "Add another image", self.add_image)
def create_settings(self): self.object_name = cps.ObjectNameSubscriber( 'Select objects to measure', cps.NONE, doc=""" Select the objects whose neighbors you want to measure.""") self.neighbors_name = cps.ObjectNameSubscriber( 'Select neighboring objects to measure', cps.NONE, doc=""" This is the name of the objects that are potential neighbors of the above objects. You can find the neighbors within the same set of objects by selecting the same objects as above.""") self.distance_method = cps.Choice('Method to determine neighbors', D_ALL, D_EXPAND, doc=""" There are several methods by which to determine whether objects are neighbors: <ul> <li><i>%(D_ADJACENT)s:</i> In this mode, two objects must have adjacent boundary pixels to be neighbors. </li> <li><i>%(D_EXPAND)s:</i> The objects are expanded until all pixels on the object boundaries are touching another. Two objects are neighbors if any of their boundary pixels are adjacent after expansion.</li> <li><i>%(D_WITHIN)s:</i> Each object is expanded by the number of pixels you specify. Two objects are neighbors if they have adjacent pixels after expansion. </li> </ul> <p>For <i>%(D_ADJACENT)s</i> and <i>%(D_EXPAND)s</i>, the <i>%(M_PERCENT_TOUCHING)s</i> measurement is the percentage of pixels on the boundary of an object that touch adjacent objects. For <i>%(D_WITHIN)s</i>, two objects are touching if any of their boundary pixels are adjacent after expansion and <i>%(M_PERCENT_TOUCHING)s</i> measures the percentage of boundary pixels of an <i>expanded</i> object that touch adjacent objects.</p>""" % globals()) self.distance = cps.Integer('Neighbor distance', 5, 1, doc=""" <i>(Used only when "%(D_WITHIN)s" is selected)</i> <br> The Neighbor distance is the number of pixels that each object is expanded for the neighbor calculation. Expanded objects that touch are considered neighbors.""" % globals()) self.wants_count_image = cps.Binary( 'Retain the image of objects colored by numbers of neighbors?', False, doc=""" An output image showing the input objects colored by numbers of neighbors may be retained. A colormap of your choice shows how many neighbors each object has. The background is set to -1. Objects are colored with an increasing color value corresponding to the number of neighbors, such that objects with no neighbors are given a color corresponding to 0. Use the <b>SaveImages</b> module to save this image to a file.""") self.count_image_name = cps.ImageNameProvider('Name the output image', 'ObjectNeighborCount', doc=""" <i>(Used only if the image of objects colored by numbers of neighbors is to be retained for later use in the pipeline)</i> <br> Specify a name that will allow the image of objects colored by numbers of neighbors to be selected later in the pipeline.""") self.count_colormap = cps.Colormap('Select colormap', doc=""" <i>(Used only if the image of objects colored by numbers of neighbors is to be retained for later use in the pipeline)</i> <br> Select the colormap to use to color the neighbor number image. All available colormaps can be seen <a href="http://www.scipy.org/Cookbook/Matplotlib/Show_colormaps">here</a>.""" ) self.wants_percent_touching_image = cps.Binary( 'Retain the image of objects colored by percent of touching pixels?', False, doc=""" Select <i>%(YES)s</i> to keep an image of the input objects colored by the percentage of the boundary touching their neighbors. A colormap of your choice is used to show the touching percentage of each object. Use the <b>SaveImages</b> module to save this image to a file.""" % globals()) self.touching_image_name = cps.ImageNameProvider( 'Name the output image', 'PercentTouching', doc=""" <i>(Used only if the image of objects colored by percent touching is to be retained for later use in the pipeline)</i> <br> Specify a name that will allow the image of objects colored by percent of touching pixels to be selected later in the pipeline.""") self.touching_colormap = cps.Colormap('Select a colormap', doc=""" <i>(Used only if the image of objects colored by percent touching is to be retained for later use in the pipeline)</i> <br> Select the colormap to use to color the percent touching image. All available colormaps can be seen <a href="http://www.scipy.org/Cookbook/Matplotlib/Show_colormaps">here</a>.""" )