def add_additional_object(self): group = cps.SettingsGroup() group.append( "object_name", cps.ObjectNameSubscriber('Select additional object to relabel', 'None')) group.append( "target_name", cps.ObjectNameProvider('Name the relabeled objects', 'FilteredGreen')) group.append( "wants_outlines", cps.Binary('Retain outlines of relabeled objects?', False)) group.append( "outlines_name", cps.OutlineNameProvider('Name the outline image', 'OutlinesFilteredGreen')) group.append( "remover", cps.RemoveSettingButton("", "Remove this additional object", self.additional_objects, group)) group.append("divider", cps.Divider(line=False)) self.additional_objects.append(group)
def create_settings(self): """Create the settings for the module Create the settings for the module during initialization. """ self.secondary_objects_name = cps.ObjectNameSubscriber( "Select the larger identified objects", "None", doc=""" What did you call the larger identified objects?""") self.primary_objects_name = cps.ObjectNameSubscriber( "Select the smaller identified objects", "None", doc=""" What did you call the smaller identified objects?""") self.subregion_objects_name = cps.ObjectNameProvider( "Name the tertiary objects to be identified", "Cytoplasm", doc=""" What do you want to call the new subregions? The new tertiary subregion will consist of the smaller object subtracted from the larger object.""" ) self.use_outlines = cps.Binary( "Retain outlines of the tertiary objects?", False) self.outlines_name = cps.OutlineNameProvider("Name the outline image", "CytoplasmOutlines", doc="""\ <i>(Used only if outlines are to be retained for later use in the pipeline)</i><br> <p> Enter a name that will allow the outlines to be selected later in the pipeline.""" )
def create_settings(self): self.image_name = cps.ImageNameSubscriber( "Select the input image", "None", doc="""Choose the name of the image to display in the object selection user interface.""") self.objects_name = cps.ObjectNameProvider( "Name the objects to be identified", "Cells", doc="""What do you want to call the objects that you identify using this module? You can use this name to refer to your objects in subsequent modules.""") self.wants_outlines = cps.Binary( "Retain outlines of the identified objects?", False, doc="""Check this setting to save the outlines around the objects as a binary image.""") self.outlines_name = cps.OutlineNameProvider( "Name the outlines", "CellOutlines", doc= """<i>(Used only if outlines are to be saved)</i><br>What do you want to call the outlines image? You can refer to this image in subsequent modules, such as <b>SaveImages</b>.""")
def create_settings(self): self.image_name = cps.ImageNameSubscriber("Select the input image", cps.NONE, doc=""" Choose the name of the image to display in the object selection user interface.""") self.objects_name = cps.ObjectNameProvider( "Name the objects to be identified", "Cells", doc=""" What do you want to call the objects that you identify using this module? You can use this name to refer to your objects in subsequent modules.""") self.wants_outlines = cps.Binary( "Retain outlines of the identified objects?", False, doc=""" %(RETAINING_OUTLINES_HELP)s""" % globals()) self.outlines_name = cps.OutlineNameProvider("Name the outlines", "CellOutlines", doc=""" %(NAMING_OUTLINES_HELP)s""" % globals())
def create_settings(self): self.object_name = cps.ObjectNameSubscriber("Select the input objects", "None", doc=''' What did you call the objects you want to expand or shrink?''' ) self.output_object_name = cps.ObjectNameProvider( "Name the output objects", "ShrunkenNuclei", doc=''' What do you want to call the resulting objects?''' ) self.operation = cps.Choice("Select the operation", O_ALL, doc=''' What operation do you want to perform? <ul> <li><i>Shrink objects to a point:</i> Remove all pixels but one from filled objects. Thin objects with holes to loops unless the "fill" option is checked.</li> <li><i>Expand objects until touching:</i> Expand objects, assigning every pixel in the image to an object. Background pixels are assigned to the nearest object.</li> <li><i>Add partial dividing lines between objects:</i> Remove pixels from an object that are adjacent to another object's pixels unless doing so would change the object's Euler number (break an object in two, remove the object completely or open a hole in an object).</li> <li><i>Shrink objects by a specified number of pixels:</i> Remove pixels around the perimeter of an object unless doing so would change the object's Euler number (break the object in two, remove the object completely or open a hole in the object). You can specify the number of times perimeter pixels should be removed. Processing stops automatically when there are no more pixels to remove.</li> <li><i>Expand objects by a specified number of pixels:</i> Expand each object by adding background pixels adjacent to the image. You can choose the number of times to expand. Processing stops automatically if there are no more background pixels.</li> <li><i>Skeletonize each object:</i> Erode each object to its skeleton.</li> <li><i>Remove spurs:</i> Remove or reduce the length of spurs in a skeletonized image. The algorithm reduces spur size by the number of pixels indicated in the setting <i>Number of pixels by which to expand or shrink</i>.</li> </ul> ''') self.iterations = cps.Integer( "Number of pixels by which to expand or shrink", 1, minval=1) self.wants_fill_holes = cps.Binary( "Fill holes in objects so that all objects shrink to a single point?", False, doc=DOC_FILL_HOLES) self.wants_outlines = cps.Binary( "Retain the outlines of the identified objects for use later in the pipeline (for example, in SaveImages)?", False) self.outlines_name = cps.OutlineNameProvider("Name the outline image", "ShrunkenNucleiOutlines", doc=""" <i>(Used only if outlines are to be retained for later use in the pipeline)</i><br> Choose a name for the outlines of the identified objects that will allow them to be selected as an image later in the pipeline.""" )
def create_settings(self): """Create the settings for the module Create the settings for the module during initialization. """ self.secondary_objects_name = cps.ObjectNameSubscriber( "Select the larger identified objects", cps.NONE, doc=""" Select the larger identified objects. This will usually be an object previously identified by a <b>IdentifySecondaryObjects</b> module.""") self.primary_objects_name = cps.ObjectNameSubscriber( "Select the smaller identified objects", cps.NONE, doc=""" Select the smaller identified objects. This will usually be an object previously identified by a <b>IdentifyPrimaryObjects</b> module.""") self.subregion_objects_name = cps.ObjectNameProvider( "Name the tertiary objects to be identified", "Cytoplasm", doc=""" Enter a name for the new tertiary objects. The tertiary objects will consist of the smaller object subtracted from the larger object.""" ) self.shrink_primary = cps.Binary( "Shrink smaller object prior to subtraction?", True, doc=""" Select <i>%(YES)s</i> to shrink the smaller object by 1 pixel before subtracting the objects. this approach will ensure that there is always a tertiary object produced, even if it is only 1 pixel wide. <p>Select <i>%(NO)s</i> to subtract the objects directly, which will ensure that no pixels are shared between the primary/secondary/tertiary objects and hence measurements for all three sets of objects will not use the same pixels multiple times. However, this may result in the creation of objects with no area. Measurements can still be made on such objects, but the results will be zero or not-a-number (NaN)</p>""" % globals()) self.use_outlines = cps.Binary( "Retain outlines of the tertiary objects?", False, doc=""" %(RETAINING_OUTLINES_HELP)s""" % globals()) self.outlines_name = cps.OutlineNameProvider("Name the outline image", "CytoplasmOutlines", doc=""" %(NAMING_OUTLINES_HELP)s""" % globals())
def create_settings(self): # # The ObjectNameSubscriber is aware of all objects published by # modules upstream of this one. You use it to let the user choose # the objects produced by a prior module. # self.input_objects_name = cps.ObjectNameSubscriber( "Input objects", "Nuclei") # # The ObjectNamePublisher lets downstream modules know that this # module will produce objects with the name entered by the user. # self.output_objects_name = cps.ObjectNameProvider( "Output objects", "Skeletons")
def create_settings(self): """Create the settings for the module Create the settings for the module during initialization. """ self.secondary_objects_name = cps.ObjectNameSubscriber( "Select the larger identified objects", "None", doc=""" What did you call the larger identified objects?""") self.primary_objects_name = cps.ObjectNameSubscriber( "Select the smaller identified objects", "None", doc=""" What did you call the smaller identified objects?""") self.subregion_objects_name = cps.ObjectNameProvider( "Name the tertiary objects to be identified", "Cytoplasm", doc=""" What do you want to call the new subregions? The new tertiary subregion will consist of the smaller object subtracted from the larger object.""" ) self.shrink_primary = cps.Binary( "Shrink smaller object prior to subtraction?", True, doc=""" Checking this box will shrink the smaller object by 1 pixel before subtracting the objects. this approach will ensure that there is always a tertiary object produced, even if it is only 1 pixel wide. <p>Unchecking this box will subtract the objects directly, which will ensure that no pixels are shared between the primary/secondary/tertiary objects and hence measurements for all three sets of objects will not use the same pixels multiple times. However, this may result in the creation of objects with no area. Measurements can still be made on such objects, but the results will be zero or not-a-number (NaN)</p>""") self.use_outlines = cps.Binary( "Retain outlines of the tertiary objects?", False) self.outlines_name = cps.OutlineNameProvider("Name the outline image", "CytoplasmOutlines", doc="""\ <i>(Used only if outlines are to be retained for later use in the pipeline)</i><br> <p> Enter a name that will allow the outlines to be selected later in the pipeline.""" )
def create_settings(self): self.primary_objects = cps.ObjectNameSubscriber( "Select the input objects", "Nuclei", doc=""" What did you call the objects you want to use as "seeds" to identify a secondary object around each one? By definition, each primary object must be associated with exactly one secondary object and completely contained within it.""") self.objects_name = cps.ObjectNameProvider( "Name the objects to be identified", "Cells", doc=""" Enter the name that you want to call the objects identified by this module.""" ) self.method = cps.Choice( "Select the method to identify the secondary objects", [ M_PROPAGATION, M_WATERSHED_G, M_WATERSHED_I, M_DISTANCE_N, M_DISTANCE_B ], M_PROPAGATION, doc=""" <p>There are several methods available to find the dividing lines between secondary objects which touch each other: <ul> <li><i>%(M_PROPAGATION)s:</i> This method will find dividing lines between clumped objects where the image stained for secondary objects shows a change in staining (i.e., either a dimmer or a brighter line). Smoother lines work better, but unlike the Watershed method, small gaps are tolerated. This method is considered an improvement on the traditional <i>Watershed</i> method. The dividing lines between objects are determined by a combination of the distance to the nearest primary object and intensity gradients. This algorithm uses local image similarity to guide the location of boundaries between cells. Boundaries are preferentially placed where the image's local appearance changes perpendicularly to the boundary (<i>Jones et al, 2005</i>).</li> <li><i>%(M_WATERSHED_G)s:</i> This method uses the watershed algorithm (<i>Vincent and Soille, 1991</i>) to assign pixels to the primary objects which act as seeds for the watershed. In this variant, the watershed algorithm operates on the Sobel transformed image which computes an intensity gradient. This method works best when the image intensity drops off or increases rapidly near the boundary between cells. </li> <li><i>%(M_WATERSHED_I)s:</i> This method is similar to the above, but it uses the inverted intensity of the image for the watershed. The areas of lowest intensity will form the boundaries between cells. This method works best when there is a saddle of relatively low intensity at the cell-cell boundary. </li> <li><i>Distance:</i> In this method, the edges of the primary objects are expanded a specified distance to create the secondary objects. For example, if nuclei are labeled but there is no stain to help locate cell edges, the nuclei can simply be expanded in order to estimate the cell's location. This is often called the "doughnut" or "annulus" or "ring" approach for identifying the cytoplasm. There are two methods that can be used: <ul> <li><i>%(M_DISTANCE_N)s</i>: In this method, the image of the secondary staining is not used at all; the expanded objects are the final secondary objects.</li> <li><i>%(M_DISTANCE_B)s</i>: Thresholding of the secondary staining image is used to eliminate background regions from the secondary objects. This allows the extent of the secondary objects to be limited to a certain distance away from the edge of the primary objects without including regions of background.</li></ul></li> </ul> <b>References</b> <ul> <li>Jones TR, Carpenter AE, Golland P (2005) "Voronoi-Based Segmentation of Cells on Image Manifolds", <i>ICCV Workshop on Computer Vision for Biomedical Image Applications</i>, 535-543. (<a href="http://www.cellprofiler.org/linked_files/Papers/JonesCVBIA2005.pdf">link</a>)</li> <li>(Vincent L, Soille P (1991) "Watersheds in Digital Spaces: An Efficient Algorithm Based on Immersion Simulations", <i>IEEE Transactions of Pattern Analysis and Machine Intelligence</i>, 13(6): 583-598 (<a href="http://dx.doi.org/10.1109/34.87344">link</a>)</li> </ul>""" % globals()) self.image_name = cps.ImageNameSubscriber("Select the input image", cps.NONE, doc=""" The selected image will be used to find the edges of the secondary objects. For <i>%(M_DISTANCE_N)s</i> this will not affect object identification, only the final display.""" % globals()) self.create_threshold_settings() # default smoothing choice is different for idprimary and idsecondary self.threshold_smoothing_choice.value = cpmi.TSM_NONE self.distance_to_dilate = cps.Integer( "Number of pixels by which to expand the primary objects", 10, minval=1) self.regularization_factor = cps.Float("Regularization factor", 0.05, minval=0, doc=""" <i>(Used only if %(M_PROPAGATION)s method is selected)</i> <br> The regularization factor λ can be anywhere in the range 0 to infinity. This method takes two factors into account when deciding where to draw the dividing line between two touching secondary objects: the distance to the nearest primary object, and the intensity of the secondary object image. The regularization factor controls the balance between these two considerations: <ul> <li>A λ value of 0 means that the distance to the nearest primary object is ignored and the decision is made entirely on the intensity gradient between the two competing primary objects. </li> <li>Larger values of λ put more and more weight on the distance between the two objects. This relationship is such that small changes in λ will have fairly different results (e.,g 0.01 vs 0.001). However, the intensity image is almost completely ignored at λ much greater than 1.</li> <li>At infinity, the result will look like %(M_DISTANCE_B)s, masked to the secondary staining image.</li> </ul>""" % globals()) self.use_outlines = cps.Binary( "Retain outlines of the identified secondary objects?", False, doc=""" %(RETAINING_OUTLINES_HELP)s""" % globals()) self.outlines_name = cps.OutlineNameProvider('Name the outline image', "SecondaryOutlines", doc=""" %(NAMING_OUTLINES_HELP)s""" % globals()) self.wants_discard_edge = cps.Binary( "Discard secondary objects touching the border of the image?", False, doc=""" Select <i>%(YES)s</i> to discard secondary objects which touch the image border. Select <i>%(NO)s</i> to retain objects regardless of whether they touch the image edge or not. <p>The objects are discarded with respect to downstream measurement modules, but they are retained in memory as "unedited objects"; this allows them to be considered in downstream modules that modify the segmentation.</p>""" % globals()) self.fill_holes = cps.Binary("Fill holes in identified objects?", True, doc=""" Select <i>%(YES)s</i> to fill any holes inside objects.""" % globals()) self.wants_discard_primary = cps.Binary( "Discard the associated primary objects?", False, doc=""" <i>(Used only if discarding secondary objects touching the image border)</i> <br> It might be appropriate to discard the primary object for any secondary object that touches the edge of the image. <p>Select <i>%(YES)s</i> to create a new set of objects that are identical to the original primary objects set, minus the objects for which the associated secondary object touches the image edge.</p>""" % globals()) self.new_primary_objects_name = cps.ObjectNameProvider( "Name the new primary objects", "FilteredNuclei", doc=""" <i>(Used only if associated primary objects are discarded)</i> <br> You can name the primary objects that remain after the discarding step. These objects will all have secondary objects that do not touch the edge of the image. Note that any primary object whose secondary object touches the edge will be retained in memory as an "unedited object"; this allows them to be considered in downstream modules that modify the segmentation.""") self.wants_primary_outlines = cps.Binary( "Retain outlines of the new primary objects?", False, doc=""" <i>(Used only if associated primary objects are discarded)</i><br> %(RETAINING_OUTLINES_HELP)s""" % globals()) self.new_primary_outlines_name = cps.OutlineNameProvider( "Name the new primary object outlines", "FilteredNucleiOutlines", doc=""" <i>(Used only if associated primary objects are discarded and saving outlines of new primary objects)</i><br> Enter a name for the outlines of the identified objects. The outlined image can be selected in downstream modules by selecting them from any drop-down image list.""")
def create_settings(self): '''Create the settings that control this module''' self.object_name = cps.ObjectNameSubscriber( "Select objects to be masked",cps.NONE,doc=""" Select the objects that will be masked (that is, excluded in whole or in part based on the other settings in the module). You can choose from any objects created by a previous object processing module, such as <b>IdentifyPrimaryObjects</b>, <b>IdentifySecondaryObjects</b> or <b>IdentifyTertiaryObjects</b>.""") self.remaining_objects = cps.ObjectNameProvider( "Name the masked objects", "MaskedNuclei",doc=""" Enter a name for the objects that remain after the masking operation. You can refer to the masked objects in subsequent modules by this name.""") self.mask_choice = cps.Choice( "Mask using a region defined by other objects or by binary image?", [MC_OBJECTS, MC_IMAGE],doc=""" You can mask your objects by defining a region using objects you previously identified in your pipeline (<i>%(MC_OBJECTS)s</i>) or by defining a region based on the white regions in a binary image (<i>%(MC_IMAGE)s</i>)."""%globals()) self.masking_objects = cps.ObjectNameSubscriber( "Select the masking object",cps.NONE,doc=""" Select the objects that will be used to define the masking region. You can choose from any objects created by a previous object processing module, such as <b>IdentifyPrimaryObjects</b>, <b>IdentifySecondaryObjects</b>, or <b>IdentifyTertiaryObjects</b>.""") self.masking_image = cps.ImageNameSubscriber( "Select the masking image",cps.NONE, doc=""" Select an image that was either loaded or created by a previous module. The image should be a binary image where the white portion of the image is the region(s) you will use for masking. Images can be loaded from disk by <b>LoadImages</b> or <b>LoadData</b>. You can create a binary image from a grayscale image using <b>ApplyThreshold</b>.""") self.wants_inverted_mask = cps.Binary( "Invert the mask?", False, doc=""" This option reverses the foreground/background relationship of the mask. <ul> <li>Select <i>%(NO)s</i> for the mask to be composed of the foregound (white portion) of the masking image or the area within the masking objects.</li> <li>Select <i>%(YES)s</i> for the mask to instead be composed of the <i>background</i> (black portions) of the masking image or the area <i>outside</i> the masking objects.</li> </ul>"""%globals()) self.overlap_choice = cps.Choice( "Handling of objects that are partially masked", [P_MASK, P_KEEP, P_REMOVE, P_REMOVE_PERCENTAGE],doc=""" An object might partially overlap the mask region, with pixels both inside and outside the region. <b>MaskObjects</b> can handle this in one of three ways:<br> <ul> <li><i>%(P_MASK)s:</i> Choosing this option will reduce the size of partially overlapping objects. The part of the object that overlaps the region will be retained. The part of the object that is outside of the region will be removed.</li> <li><i>%(P_KEEP)s:</i> If you choose this option, <b>MaskObjects</b> will keep the whole object if any part of it overlaps the masking region.</li> <li><i>%(P_REMOVE)s:</i> Objects that are partially outside of the masking region will be completely removed if you choose this option.</li> <li><i>%(P_REMOVE_PERCENTAGE)s:</i> Determine whether to remove or keep an object depending on how much of the object overlaps the masking region. <b>MaskObjects</b> will keep an object if at least a certain fraction (which you enter below) of the object falls within the masking region. <b>MaskObjects</b> completely removes the object if too little of it overlaps the masking region.</li> </ul>"""%globals()) self.overlap_fraction = cps.Float( "Fraction of object that must overlap", .5, minval = 0, maxval = 1,doc = """ <i>(Used only if removing based on a overlap)</i><br> Specify the minimum fraction of an object that must overlap the masking region for that object to be retained. For instance, if the fraction is 0.75, then 3/4 of an object must be within the masking region for that object to be retained.""") self.retain_or_renumber = cps.Choice( "Numbering of resulting objects", [R_RENUMBER, R_RETAIN],doc=""" Choose how to number the objects that remain after masking, which controls how remaining objects are associated with their predecessors: <ul> <li><i>%(R_RENUMBER)s:</i> The objects that remain will be renumbered using consecutive numbers. This is a good choice if you do not plan to use measurements from the original objects; your object measurements for the masked objects will not have gaps (where removed objects are missing).</li> <li><i>%(R_RETAIN)s:</i>: The original labels for the objects will be retained. This allows any measurements you make from the masked objects to be directly aligned with measurements you might have made of the original, unmasked objects (or objects directly associated with them).</li> </ul>"""%globals()) self.wants_outlines = cps.Binary( "Retain outlines of the resulting objects?", False, doc = """ %(RETAINING_OUTLINES_HELP)s"""%globals()) self.outlines_name = cps.OutlineNameProvider( "Name the outline image", "MaskedOutlines", doc = """ %(NAMING_OUTLINES_HELP)s"""%globals())
def create_settings(self): self.objects_name = cps.ObjectNameSubscriber( "Select the input objects", cps.NONE, doc=""" Select the objects whose object numbers you want to reassign. You can use any objects that were created in previous modules, such as <b>IdentifyPrimaryObjects</b> or <b>IdentifySecondaryObjects</b>.""" ) self.output_objects_name = cps.ObjectNameProvider( "Name the new objects", "RelabeledNuclei", doc=""" Enter a name for the objects whose numbers have been reassigned. You can use this name in subsequent modules that take objects as inputs.""" ) self.relabel_option = cps.Choice("Operation", [OPTION_UNIFY, OPTION_SPLIT], doc=""" You can choose one of the following options: <ul> <li><i>%(OPTION_UNIFY)s:</i> Assign adjacent or nearby objects the same label based on certain criteria. It can be useful, for example, to merge together touching objects that were incorrectly split into two pieces by an <b>Identify</b> module.</li> <li><i>%(OPTION_SPLIT)s:</i> Assign a unique number to separate objects that currently share the same label. This can occur if you applied certain operations with the <b>Morph</b> module to objects.</li> </ul>""" % globals()) self.unify_option = cps.Choice("Unification method", [UNIFY_DISTANCE, UNIFY_PARENT], doc=""" <i>(Used only with the %(OPTION_UNIFY)s option)</i><br> You can unify objects in one of two ways: <ul> <li><i>%(UNIFY_DISTANCE)s: </i> All objects within a certain pixel radius from each other will be unified</li> <li><i>%(UNIFY_PARENT)s: </i>All objects which share the same parent relationship to another object will be unified. This is not be confused with using the <b>RelateObjects</b> module, in which the related objects remain as individual objects. See <b>RelateObjects</b> for more details.</li> </ul> """ % globals()) self.parent_object = cps.Choice("Select the parent object", [cps.NONE], choices_fn=self.get_parent_choices, doc=""" Select the parent object that will be used to unify the child objects. Please note the following: <ul> <li>You must have established a parent-child relationship between the objects using a prior <b>RelateObjects</b> module.</li> <li>Primary objects and their associated secondary objects are already in a one-to-one parent-child relationship, so it makes no sense to unify them here.</li> </ul>""") self.distance_threshold = cps.Integer( "Maximum distance within which to unify objects", 0, minval=0, doc=""" <i>(Used only with the %(OPTION_UNIFY)s option and the %(UNIFY_DISTANCE)s method)</i><br> Objects that are less than or equal to the distance you enter here, in pixels, will be unified. If you choose zero (the default), only objects that are touching will be unified. Note that <i>%(OPTION_UNIFY)s </i> will not actually connect or bridge the two objects by adding any new pixels; it simply assigns the same object number to the portions of the object. The new, unified object may therefore consist of two or more unconnected components.""" % globals()) self.wants_image = cps.Binary("Unify using a grayscale image?", False, doc=""" <i>(Used only with the %(OPTION_UNIFY)s option)</i><br> <i>%(OPTION_UNIFY)s</i> can use the objects' intensity features to determine whether two objects should be unified. If you choose to use a grayscale image, <i>%(OPTION_UNIFY)s</i> will unify two objects only if they are within the distance you have specified <i>and</i> certain criteria about the objects within the grayscale image are met.""" % globals()) self.image_name = cps.ImageNameSubscriber( "Select the grayscale image to guide unification", cps.NONE, doc=""" <i>(Used only if a grayscale image is to be used as a guide for unification)</i><br> Select the name of an image loaded or created by a previous module.""" ) self.minimum_intensity_fraction = cps.Float( "Minimum intensity fraction", .9, minval=0, maxval=1, doc=""" <i>(Used only if a grayscale image is to be used as a guide for unification)</i><br> Select the minimum acceptable intensity fraction. This will be used as described for the method you choose in the next setting.""") self.where_algorithm = cps.Choice("Method to find object intensity", [CA_CLOSEST_POINT, CA_CENTROIDS], doc=""" <i>(Used only if a grayscale image is to be used as a guide for unification)</i><br> You can use one of two methods to determine whether two objects should unified, assuming they meet the distance criteria (as specified above): <ul> <li><i>%(CA_CENTROIDS)s:</i> When the module considers merging two objects, this method identifies the centroid of each object, records the intensity value of the dimmer of the two centroids, multiplies this value by the <i>minimum intensity fraction</i> to generate a threshold, and draws a line between the centroids. The method will unify the two objects only if the intensity of every point along the line is above the threshold. For instance, if the intensity of one centroid is 0.75 and the other is 0.50 and the <i>minimum intensity fraction</i> has been chosen to be 0.9, all points along the line would need to have an intensity of min(0.75, 0.50) * 0.9 = 0.50 * 0.9 = 0.45.<br> This method works well for round cells whose maximum intensity is in the center of the cell: a single cell that was incorrectly segmented into two objects will typically not have a dim line between the centroids of the two halves and will be correctly unified.</li> <li><i>%(CA_CLOSEST_POINT)s:</i> This method is useful for unifying irregularly shaped cells which are connected. It starts by assigning background pixels in the vicinity of the objects to the nearest object. Objects are then unified if each object has background pixels that are: <ul> <li>Within a distance threshold from each object;</li> <li>Above the minimum intensity fraction of the nearest object pixel;</li> <li>Adjacent to background pixels assigned to a neighboring object.</li> </ul> An example of a feature that satisfies the above constraints is a line of pixels that connect two neighboring objects and is roughly the same intensity as the boundary pixels of both (such as an axon connecting two neurons).</li> </ul>""") self.wants_outlines = cps.Binary( "Retain outlines of the relabeled objects?", False, doc=""" %(RETAINING_OUTLINES_HELP)s""" % globals()) self.outlines_name = cps.OutlineNameProvider('Name the outlines', 'RelabeledNucleiOutlines', doc=""" %(NAMING_OUTLINES_HELP)s""" % globals())
def create_settings(self): """Create your settings by subclassing this function create_settings is called at the end of initialization. """ self.grid_name = cps.GridNameSubscriber("Select the defined grid", "None", doc=""" Select the name of a grid created by a previous <b>DefineGrid</b> module.""") self.output_objects_name = cps.ObjectNameProvider( "Name the objects to be identified", "Wells", doc= """What do you want to call the grid objects identified by this module? These objects will be available for further measurement and processing in subsequent modules.""") self.shape_choice = cps.Choice( "Select object shapes and locations", [ SHAPE_RECTANGLE, SHAPE_CIRCLE_FORCED, SHAPE_CIRCLE_NATURAL, SHAPE_NATURAL ], doc= """Use this setting to choose the method to be used to determine the grid objects' shapes and locations: <ul> <li><i>Rectangle Forced Location:</i> Each object will be created as a rectangle, completely occupying the entire grid compartment (rectangle). This option creates the rectangular objects based solely on the grid's specifications, not on any previously identified guiding objects.</li> <li><i>Circle Forced Location:</i> Each object will be created as a circle, centered in the middle of each grid compartment. This option places the circular objects' locations based solely on the grid's specifications, not on any previously identified guiding objects. The radius of all circles in a grid will be constant for the entire grid in each image cycle, and can be determined automatically for each image cycle based on the average radius of previously identified guiding objects for that image cycle, or instead it can be specified as a single radius for all circles in all grids in the entire analysis run.</li> <li><i>Circle Natural Location:</i> Each object will be created as a circle, and each circle's location within its grid compartment will be determined based on the location of any previously identified guiding objects within that grid compartment. Thus, if a guiding object lies within a particular grid compartment, that object's center will be the center of the created circular object. If no guiding objects lie within a particular grid compartment, the circular object is placed within the center of that grid compartment. If more than one guiding object lies within the grid compartment, they will be combined and the centroid of this combined object will be the location of the created circular object. Note that guiding objects whose centers are close to the grid edge are ignored.</li> <li><i>Natural Shape and Location:</i> Within each grid compartment, the object will be identified based on combining all of the parts of guiding objects, if any, that fall within the grid compartment. Note that guiding objects whose centers are close to the grid edge are ignored. If a guiding object does not exist within a grid compartment, an object consisting of one single pixel in the middle of the grid compartment will be created.</li> </ul>""") self.diameter_choice = cps.Choice( "Specify the circle diameter automatically?", [AM_AUTOMATIC, AM_MANUAL], doc="""<i>(Used only if Circle is selected as object shape)</i><br> The automatic method uses the average diameter of previously identified guiding objects as the diameter. The manual method lets you specify the diameter directly, as a number.""") self.diameter = cps.Integer( "Circle diameter", 20, minval=2, doc= """<i>(Used only if Circle is selected as object shape and diameter is specified manually)</i><br> Enter the diameter to be used for each grid circle, in pixels. %(HELP_ON_MEASURING_DISTANCES)s""" % globals()) self.guiding_object_name = cps.ObjectNameSubscriber( "Select the guiding objects", "None", doc= """<i>(Used only if Circle is selected as object shape and diameter is specified automatically, or if Natural Location is selected as object shape)</i><br> Select the names of previously identified objects that will be used to guide the shape and/or location of the objects created by this module, depending on the method chosen.""") self.wants_outlines = cps.Binary( "Retain outlines of the identified objects?", False, doc="""The module can create a binary image of the outlines of the objects it creates. You can then use <b>OverlayOutlines</b> to overlay the outlines on an image or use <b>SaveImages</b> to save them.""") self.outlines_name = cps.OutlineNameProvider( "Name the outline image", "GridOutlines", doc="""<i>(Used only if outlines are to be saved)</i><br> This setting names the outlines of the output objects. You can use this name to refer to the outlines in the <b>OverlayOutlines</b> and <b>SaveImages</b> modules.""")
def create_settings(self): '''Create the initial settings and name the module''' self.target_name = cps.ObjectNameProvider('Name the output objects', 'FilteredBlue', doc=""" What do you want to call the filtered objects? This will be the name for the collection of objects that are retained after applying the filter(s).""" ) self.object_name = cps.ObjectNameSubscriber( 'Select the object to filter', 'None', doc=""" What object would you like to filter? This setting also controls which measurement choices appear for filtering: you can only filter based on measurements made on the object you select. If you intend to use a measurement calculated by the <b>CalculateMath</b> module to to filter objects, select the first operand's object here, because <b>CalculateMath</b> measurements are stored with the first operand's object.""") self.spacer_1 = cps.Divider(line=False) self.rules_or_measurement = cps.Choice( 'Filter using classifier rules or measurements?', [ROM_MEASUREMENTS, ROM_RULES], doc="""You can choose either a measurement made on the objects or a rules file produced by CellProfiler Analyst. If you choose <i>Rules</i>, you will have to ensure that this pipeline makes every measurement in that rules file.""") self.spacer_2 = cps.Divider(line=False) self.measurements = [] self.measurement_count = cps.HiddenCount(self.measurements, "Measurement count") self.add_measurement(False) self.add_measurement_button = cps.DoSomething( "Add another measurement", "Add", self.add_measurement) self.filter_choice = cps.Choice("Select the filtering method", FI_ALL, FI_LIMITS, doc=""" <i>(Used only if filtering using measurements)</i><br> There are five different ways to filter objects: <ul> <li><i>Limits:</i> Keep an object if its measurement value falls within a range you specify.</li> <li><i>Maximal:</i> Keep the object with the maximum value for the measurement of interest. If multiple objects share a maximal value, retain one object selected arbitrarily per image.</li> <li><i>Minimal:</i> Keep the object with the minimum value for the measurement of interest. If multiple objects share a minimal value, retain one object selected arbitrarily per image.</li> <li><i>Maximal per object:</i> This option requires you to choose a parent object. The parent object might contain several child objects of choice (for instance, mitotic spindles within a cell or FISH probe spots within a nucleus). Only the child object whose measurements equal the maximum child-measurement value among that set of child objects will be kept (for example, the longest spindle in each cell). You do not have to explicitly relate objects before using this module.</li> <li><i>Minimal per object:</i> Same as <i>Maximal per object</i>, except filtering is based on the minimum value.</li> </ul>""") self.enclosing_object_name = cps.ObjectNameSubscriber( 'Select the objects that contain the filtered objects', 'None', doc=""" <i>(Used only if a per-object filtering method is selected)</i><br> This setting selects the container (i.e., parent) objects for the <i>Maximal per object</i> and <i>Minimal per object</i> filtering choices.""" ) self.rules_directory = cps.DirectoryPath( "Rules file location", doc="""<i>(Used only when filtering by rules)</i> <br> Select the location of the rules file that will be used for filtering. %(IO_FOLDER_CHOICE_HELP_TEXT)s""" % globals()) def get_directory_fn(): '''Get the directory for the rules file name''' return self.rules_directory.get_absolute_path() def set_directory_fn(path): dir_choice, custom_path = self.rules_directory.get_parts_from_path( path) self.rules_directory.join_parts(dir_choice, custom_path) self.rules_file_name = cps.FilenameText( "Rules file name", "rules.txt", get_directory_fn=get_directory_fn, set_directory_fn=set_directory_fn, doc="""<i>(Used only when filtering using rules)</i> <br>The name of the file holding the rules. Each line of this file should be a rule naming a measurement to be made on the object you selected, for instance: <br><tt> IF (Nuclei_AreaShape_Area < 351.3, [0.79, -0.79], [-0.94, 0.94]) </tt><br> The above rule will score +.79 for the positive category and -0.94 for the negative category for nuclei whose area is less than 351.3 pixels and will score the opposite for nuclei whose area is larger. The filter adds positive and negative and keeps only objects whose positive score is higher than the negative score""") self.wants_outlines = cps.Binary( 'Retain outlines of the identified objects?', False) self.outlines_name = cps.OutlineNameProvider('Name the outline image', 'FilteredObjects', doc=''' <i>(Used only if the outline image is to be retained for later use in the pipeline)</i> <br> Choose a name by which the outline image can be selected later in the pipeline. <p><i>Special note on saving images:</i> You can use the settings in this module to pass object outlines along to the module <b>OverlayOutlines</b>, and then save them with the <b>SaveImages</b> module. Also, the identified objects themselves can be passed along to the object processing module <b>ConvertToImage</b> and then saved with the <b>SaveImages</b> module.''' ) self.additional_objects = [] self.additional_object_count = cps.HiddenCount( self.additional_objects, "Additional object count") self.spacer_3 = cps.Divider(line=False) self.additional_object_button = cps.DoSomething( 'Relabel additional objects to match the filtered object?', 'Add an additional object', self.add_additional_object, doc=""" Click this button to add an object to receive the same post-filtering labels as the filtered object. This is useful in making sure that labeling is maintained between related objects (e.g., primary and secondary objects) after filtering.""" )
def create_settings(self): '''Create the settings for the module''' self.images = [] self.objects_name = cps.ObjectNameSubscriber( 'Select the input untangled worm objects', 'OverlappingWorms', doc = """This is the name of the objects produced by the <b>UntangleWorms</b> module. <b>StraightenWorms</b> can use either the overlapping or non-overlapping objects as input. It will use the control point measurements associated with the objects to reconstruct the straight worms. You can also use objects saved from a previous run and loaded via <b>LoadImages</b>, objects edited using <b>EditObjectsManually</b> or objects from one of the Identify modulues. <b>StraightenWorms</b> will recalculate the control points for these images.""") self.straightened_objects_name = cps.ObjectNameProvider( "Name the output straightened worm objects", "StraightenedWorms", doc = """This is the name that will be given to the straightened worm objects. These objects can then be used in a subsequent measurement module.""") self.width = cps.Integer( "Worm width", 20, minval = 3, doc = """This setting determines the width of the image of each worm. The width should be set to at least the maximum width of any untangled worm, but can be set to be larger to include the worm's background in the straightened image.""") self.training_set_directory = cps.DirectoryPath( "Training set file location", support_urls = True, allow_metadata = False, doc = """Select the folder containing the training set to be loaded. %(IO_FOLDER_CHOICE_HELP_TEXT)s <p>An additional option is the following: <ul> <li><i>URL</i>: Use the path part of a URL. For instance, your training set might be hosted at <i>http://university.edu/~johndoe/TrainingSet.mat</i> To access this file, you would choose <i>URL</i> and enter <i>https://svn.broadinstitute.org/CellProfiler/trunk/ExampleImages/ExampleSBSImages</i> as the path location.</li> </ul></p>"""%globals()) def get_directory_fn(): '''Get the directory for the CSV file name''' return self.training_set_directory.get_absolute_path() def set_directory_fn(path): dir_choice, custom_path = self.training_set_directory.get_parts_from_path(path) self.training_set_directory.join_parts(dir_choice, custom_path) self.training_set_file_name = cps.FilenameText( "Training set file name", "TrainingSet.mat", doc = "This is the name of the training set file.", get_directory_fn = get_directory_fn, set_directory_fn = set_directory_fn, browse_msg = "Choose training set", exts = [("Worm training set (*.xml)", "*.xml"), ("All files (*.*)", "*.*")]) self.wants_measurements = cps.Binary( "Measure intensity distribution?", True, doc = """<b>StraightenWorms</b> can divide a worm into sections and measure the intensities of each section in each of the straightened images. These measurements can help classify phenotypes if the staining pattern across the segments differs between phenotypes.""") self.number_of_segments = cps.Integer( "Number of transverse segments", 4, 1, doc = """(<i>Only displayed if intensities are measured</i>)<br> This setting controls the number of segments measured, dividing the worm longitudally into transverse segments starting at the head and ending at the tail. These measurements might be used to identify a phenotype in which a stain is localized longitudally, for instance, in the head. Set the number of vertical segments to 1 to only measure intensity in the horizontal direction.""") self.number_of_stripes = cps.Integer( "Number of longitudinal stripes", 3, 1, doc = """(<i>Only displayed if intensities are measured</i>)<br> This setting controls the number of stripes measured, dividing the worm transversely into areas that run longitudally. These measurements might be used to identify a phenotype in which a stain is localized transversely, for instance in the gut of the worm. Set the number of horizontal stripes to 1 to only measure intensity in the vertical direction.""") self.flip_worms = cps.Choice( "Align worms?", [FLIP_NONE, FLIP_TOP, FLIP_BOTTOM], doc = """(<i>Only displayed if intensities are measured</i>)<br> <b>StraightenWorms</b> can align worms so that the brightest half of the worm (the half with the highest mean intensity) is at the top of the image or at the bottom of the image. This can be used to align all worms similarly if some feature, such as the larynx, is stained and is always at the same end of the worm. Choose <i>%(FLIP_TOP)s</i> if the brightest part of the worm should be at the top of the image, <i>%(FLIP_BOTTOM)s</i> if the brightest part of the worm should be at the bottom or <i>%(FLIP_NONE)s</i> if the worm should not be aligned."""%globals()) def image_choices_fn(pipeline): '''Return the image choices for the alignment image''' return [ group.image_name.value for group in self.images ] self.flip_image = cps.Choice( "Alignment image", [ "None" ], choices_fn = image_choices_fn, doc = """(<i>Only displayed if aligning worms</i>)<br> This is the image whose intensity will be used to align the worms. You must use one of the straightened images below.""") self.image_count = cps.HiddenCount(self.images, "Image count") self.add_image(False) self.add_image_button = cps.DoSomething( "", "Add another image", self.add_image, doc = """Press this button to add another image to be straightened""")
def create_settings(self): """Create your settings by subclassing this function create_settings is called at the end of initialization. You should create the setting variables for your module here: # Ask the user for the input image self.image_name = cellprofiler.settings.ImageNameSubscriber(...) # Ask the user for the name of the output image self.output_image = cellprofiler.settings.ImageNameProvider(...) # Ask the user for a parameter self.smoothing_size = cellprofiler.settings.Float(...) """ self.object_name = cps.ObjectNameSubscriber( "Select the objects to be edited", "None", doc=""" Choose a set of previously identified objects for editing, such as those produced by one of the <b>Identify</b> modules.""") self.filtered_objects = cps.ObjectNameProvider( "Name the edited objects", "EditedObjects", doc="""What do you want to call the objects that remain after editing? These objects will be available for use by subsequent modules.""") self.allow_overlap = cps.Binary( "Allow overlapping objects", False, doc="""<b>EditObjectsManually</b> can allow you to edit an object so that it overlaps another or it can prevent you from overlapping one object with another. Objects such as worms or the neurites of neurons may cross each other and might need to be edited with overlapping allowed, whereas a monolayer of cells might be best edited with overlapping off. Check this setting to allow overlaps or uncheck it to prevent them.""") self.wants_outlines = cps.Binary( "Retain outlines of the edited objects?", False, doc="""Check this box if you want to keep images of the outlines of the objects that remain after editing. This image can be saved by downstream modules or overlayed on other images using the <b>OverlayOutlines</b> module.""") self.outlines_name = cps.OutlineNameProvider( "Name the outline image", "EditedObjectOutlines", doc= """<i>(Used only if you have selected to retain outlines of edited objects)</i><br> What do you want to call the outline image?""") self.renumber_choice = cps.Choice( "Numbering of the edited objects", [R_RENUMBER, R_RETAIN], doc="""Choose how to number the objects that remain after editing, which controls how edited objects are associated with their predecessors: <p> If you choose <i>Renumber</i>, this module will number the objects that remain using consecutive numbers. This is a good choice if you do not plan to use measurements from the original objects and you only want to use the edited objects in downstream modules; the objects that remain after editing will not have gaps in numbering where removed objects are missing. <p> If you choose <i>Retain</i>, this module will retain each object's original number so that the edited object's number matches its original number. This allows any measurements you make from the edited objects to be directly aligned with measurements you might have made of the original, unedited objects (or objects directly associated with them).""") self.wants_image_display = cps.Binary( "Display a guiding image?", True, doc="""Check this setting to display an image and outlines of the objects. Leave the setting unchecked if you do not want a guide image while editing""") self.image_name = cps.ImageNameSubscriber("Select the guiding image", "None", doc=""" <i>(Used only if a guiding image is desired)</i><br> This is the image that will appear when editing objects. Choose an image supplied by a previous module.""")
def create_settings(self): self.primary_objects = cps.ObjectNameSubscriber( "Select the input objects", "Nuclei", doc=""" What did you call the objects you want to use as "seeds" to identify a secondary object around each one? By definition, each primary object must be associated with exactly one secondary object and completely contained within it.""") self.objects_name = cps.ObjectNameProvider( "Name the objects to be identified", "Cells") self.method = cps.Choice( "Select the method to identify the secondary objects", [ M_PROPAGATION, M_WATERSHED_G, M_WATERSHED_I, M_DISTANCE_N, M_DISTANCE_B ], M_PROPAGATION, doc="""\ <p>There are several methods available to find the dividing lines between secondary objects which touch each other: <ul> <li><i>Propagation:</i> This method will find dividing lines between clumped objects where the image stained for secondary objects shows a change in staining (i.e., either a dimmer or a brighter line). Smoother lines work better, but unlike the Watershed method, small gaps are tolerated. This method is considered an improvement on the traditional <i>Watershed</i> method. The dividing lines between objects are determined by a combination of the distance to the nearest primary object and intensity gradients. This algorithm uses local image similarity to guide the location of boundaries between cells. Boundaries are preferentially placed where the image's local appearance changes perpendicularly to the boundary (TR Jones, AE Carpenter, P Golland (2005) <i>Voronoi-Based Segmentation of Cells on Image Manifolds</i>, ICCV Workshop on Computer Vision for Biomedical Image Applications, pp. 535-543).</li> <li><i>%(M_WATERSHED_G)s:</i> This method uses the watershed algorithm (Vincent, Luc and Pierre Soille, <i>Watersheds in Digital Spaces: An Efficient Algorithm Based on Immersion Simulations</i>, IEEE Transactions of Pattern Analysis and Machine Intelligence, Vol. 13, No. 6, June 1991, pp. 583-598) to assign pixels to the primary objects which act as seeds for the watershed. In this variant, the watershed algorithm operates on the Sobel transformed image which computes an intensity gradient. This method works best when the image intensity drops off or increases rapidly near the boundary between cells. </li> <li><i>%(M_WATERSHED_I)s:</i> This method is similar to the above, but it uses the inverted intensity of the image for the watershed. The areas of lowest intensity will form the boundaries between cells. This method works best when there is a saddle of relatively low intensity at the cell-cell boundary. </li> <li><i>Distance:</i> In this method, the edges of the primary objects are expanded a specified distance to create the secondary objects. For example, if nuclei are labeled but there is no stain to help locate cell edges, the nuclei can simply be expanded in order to estimate the cell's location. This is often called the "doughnut" or "annulus" or "ring" approach for identifying the cytoplasm. There are two methods that can be used: <ul> <li><i>%(M_DISTANCE_N)s</i>: In this method, the image of the secondary staining is not used at all; the expanded objects are the final secondary objects.</li> <li><i>%(M_DISTANCE_B)s</i>: Thresholding of the secondary staining image is used to eliminate background regions from the secondary objects. This allows the extent of the secondary objects to be limited to a certain distance away from the edge of the primary objects without including regions of background.</li></ul></li> </ul>""" % globals()) self.image_name = cps.ImageNameSubscriber("Select the input image", "None", doc=""" The selected image will be used to find the edges of the secondary objects. For <i>Distance - N</i> this will not affect object identification, only the final display.""" ) self.create_threshold_settings() self.distance_to_dilate = cps.Integer( "Number of pixels by which to expand the primary objects", 10, minval=1) self.regularization_factor = cps.Float("Regularization factor", 0.05, minval=0, doc="""\ <i>(Used only if Propagation method selected)</i> <br> The regularization factor λ can be anywhere in the range 0 to infinity. This method takes two factors into account when deciding where to draw the dividing line between two touching secondary objects: the distance to the nearest primary object, and the intensity of the secondary object image. The regularization factor controls the balance between these two considerations: <ul> <li>A λ value of 0 means that the distance to the nearest primary object is ignored and the decision is made entirely on the intensity gradient between the two competing primary objects. </li> <li>Larger values of λ put more and more weight on the distance between the two objects. This relationship is such that small changes in λ will have fairly different results (e.,g 0.01 vs 0.001). However, the intensity image is almost completely ignored at λ much greater than 1.</li> <li>At infinity, the result will look like %(M_DISTANCE_B)s, masked to the secondary staining image.</li> </ul>""" % globals()) self.use_outlines = cps.Binary( "Retain outlines of the identified secondary objects?", False) self.outlines_name = cps.OutlineNameProvider('Name the outline image', "SecondaryOutlines", doc="""\ <i>(Used only if outlines are to be saved)</i><br> Once the outline image is named here, the outlines of the identified objects may be used by modules downstream, by selecting them from any drop-down image list.""") self.wants_discard_edge = cps.Binary( "Discard secondary objects touching the border of the image?", False, doc="""This option will discard objects which have an edge that falls on the border of the image. The objects are discarded with respect to downstream measurement modules, but they are retained in memory as "unedited objects"; this allows them to be considered in downstream modules that modify the segmentation.""") self.fill_holes = cps.Binary( "Fill holes in identified objects?", True, doc="""Check this box to fill any holes inside objects.""") self.wants_discard_primary = cps.Binary( "Discard the associated primary objects?", False, doc= """<i>(Used only if discarding secondary objects touching the image border)</i> <br> It might be appropriate to discard the primary object for any secondary object that touches the edge of the image. The module will create a new set of objects that mirrors your primary objects if you check this setting. The new objects will be identical to the old, except that the new objects will have objects removed if their associated secondary object touches the edge of the image.""") self.new_primary_objects_name = cps.ObjectNameProvider( "Name the new primary objects", "FilteredNuclei", doc= """<i>(Used only if associated primary objects are discarded)</i> <br> You can name the primary objects that remain after the discarding step. These objects will all have secondary objects that do not touch the edge of the image. Note that any primary object whose secondary object touches the edge will be retained in memory as an "unedited object"; this allows them to be considered in downstream modules that modify the segmentation.""") self.wants_primary_outlines = cps.Binary( "Retain outlines of the new primary objects?", False, doc= """<i>(Used only if associated primary objects are discarded)</i><br> Check this setting in order to save images of the outlines of the primary objects after filtering. You can save these images using the <b>SaveImages</b> module.""") self.new_primary_outlines_name = cps.OutlineNameProvider( "Name the new primary object outlines", "FilteredNucleiOutlines", doc= """<i>(Used only if associated primary objects are discarded and saving outlines of new primary objects)</i><br> You can name the outline image of the primary objects after filtering. You can refer to this image using this name in subsequent modules such as <b>SaveImages</b>.""" )
def add_file(self, can_remove = True): """Add settings for another file to the list""" group = cps.SettingsGroup() if can_remove: group.append("divider", cps.Divider(line=False)) def get_directory_fn(): return self.directory.get_absolute_path() group.append("file_name", cps.FilenameText( FILE_TEXT, cps.NONE, metadata=True, get_directory_fn = get_directory_fn, exts = [("TIF - Tagged Image File format (*.tif,*.tiff)","*.tif,*.tiff"), ("PNG - Portable Network Graphics (*.png)", "*.png"), ("JPG/JPEG file (*.jpg,*.jpeg)", "*.jpg,*.jpeg"), ("BMP - Windows Bitmap (*.bmp)", "*.bmp"), ("Compuserve GIF file (*.gif)", "*.gif"), ("MATLAB image (*.mat)","*.mat"), ("All files (*.*)", "*.*")],doc = """ The filename can be constructed in one of two ways: <ul> <li>As a fixed filename (e.g., <i>Exp1_D03f00d0.tif</i>). </li> <li>Using the metadata associated with an image set in <b>LoadImages</b> or <b>LoadData</b>. This is especially useful if you want your output given a unique label according to the metadata corresponding to an image group. The name of the metadata to substitute is included in a special tag format embedded in your file specification. %(USING_METADATA_TAGS_REF)s%(USING_METADATA_HELP_REF)s.</li> </ul> <p>Keep in mind that in either case, the image file extension, if any, must be included."""% globals() )) group.append("image_objects_choice", cps.Choice( 'Load as images or objects?', IO_ALL, doc = """ This setting determines whether you load an image as image data or as segmentation results (i.e., objects): <ul> <li><i>%(IO_IMAGES)s:</i> The input image will be given a user-specified name by which it will be refered downstream. This is the most common usage for this module.</li> <li><i>%(IO_OBJECTS)s:</i> Use this option if the input image is a label matrix and you want to obtain the objects that it defines. A <i>label matrix</i> is a grayscale or color image in which the connected regions share the same label, and defines how objects are represented in CellProfiler. The labels are integer values greater than or equal to 0. The elements equal to 0 are the background, whereas the elements equal to 1 make up one object, the elements equal to 2 make up a second object, and so on. This option allows you to use the objects without needing to insert an <b>Identify</b> module to extract them first. See <b>IdentifyPrimaryObjects</b> for more details.</li> </ul>"""%globals())) group.append("image_name", cps.FileImageNameProvider("Name the image that will be loaded", "OrigBlue", doc = ''' <i>(Used only if an image is output)</i><br> Enter the name of the image that will be loaded. You can use this name to select the image in downstream modules.''')) group.append("rescale", cps.Binary( "Rescale intensities?",True,doc = """ <i>(Used only if an image is output)</i><br> This option determines whether image metadata should be used to rescale the image's intensities. Some image formats save the maximum possible intensity value along with the pixel data. For instance, a microscope might acquire images using a 12-bit A/D converter which outputs intensity values between zero and 4095, but stores the values in a field that can take values up to 65535. <p>Select <i>%(YES)s</i> to rescale the image intensity so that saturated values are rescaled to 1.0 by dividing all pixels in the image by the maximum possible intensity value. </p> <p>Select <i>%(NO)s</i> to ignore the image metadata and rescale the image to 0 – 1.0 by dividing by 255 or 65535, depending on the number of bits used to store the image.</p>"""%globals())) group.append("objects_name", cps.ObjectNameProvider( 'Name this loaded object', "Nuclei", doc = """<i>(Used only if objects are output)</i><br> This is the name for the objects loaded from your image""")) group.append("wants_outlines", cps.Binary( "Retain outlines of loaded objects?", False, doc = """ <i>(Used only if objects are output)</i><br> Select <i>%(YES)s</i> if you want to save an image of the outlines of the loaded objects."""%globals())) group.append("outlines_name", cps.OutlineNameProvider( 'Name the outlines', 'NucleiOutlines',doc = """ <i>(Used only if objects are output)</i><br> Enter a name that will allow the outlines to be selected later in the pipeline.""")) if can_remove: group.append("remove", cps.RemoveSettingButton("", "Remove this image", self.file_settings, group)) self.file_settings.append(group)
def create_settings(self): self.object_name = cps.ObjectNameSubscriber( "Select the input objects", cps.NONE, doc=''' Select the objects that you want to expand or shrink.''') self.output_object_name = cps.ObjectNameProvider( "Name the output objects", "ShrunkenNuclei", doc=''' Enter a name for the resulting objects.''') self.operation = cps.Choice( "Select the operation", O_ALL, doc=''' Select the operation that you want to perform: <ul> <li><i>%(O_SHRINK_INF)s:</i> Remove all pixels but one from filled objects. Thin objects with holes to loops unless the "fill" option is checked.</li> <li><i>%(O_EXPAND_INF)s:</i> Expand objects, assigning every pixel in the image to an object. Background pixels are assigned to the nearest object.</li> <li><i>%(O_DIVIDE)s:</i> Remove pixels from an object that are adjacent to another object's pixels unless doing so would change the object's Euler number (break an object in two, remove the object completely or open a hole in an object).</li> <li><i>%(O_SHRINK)s:</i> Remove pixels around the perimeter of an object unless doing so would change the object's Euler number (break the object in two, remove the object completely or open a hole in the object). You can specify the number of times perimeter pixels should be removed. Processing stops automatically when there are no more pixels to remove.</li> <li><i>%(O_EXPAND)s:</i> Expand each object by adding background pixels adjacent to the image. You can choose the number of times to expand. Processing stops automatically if there are no more background pixels.</li> <li><i>%(O_SKELETONIZE)s:</i> Erode each object to its skeleton.</li> <li><i>%(O_SPUR)s:</i> Remove or reduce the length of spurs in a skeletonized image. The algorithm reduces spur size by the number of pixels indicated in the setting <i>Number of pixels by which to expand or shrink</i>.</li> </ul>''' % globals()) self.iterations = cps.Integer( "Number of pixels by which to expand or shrink", 1, minval=1) self.wants_fill_holes = cps.Binary( "Fill holes in objects so that all objects shrink to a single point?", False, doc=""" <i>(Used only if one of the "shrink" options selected)</i><br> Select <i>%(YES)s</i> to ensure that each object will shrink to a single point, by filling the holes in each object. <p>Select <i>%(NO)s</i> to preserve the Euler number. in this case, the shrink algorithm preserves each object's Euler number, which means that it will erode an object with a hole to a ring in order to keep the hole. An object with two holes will be shrunk to two rings connected by a line in order to keep from breaking up the object or breaking the hole.</p>""" % globals()) self.wants_outlines = cps.Binary( "Retain the outlines of the identified objects?", False, doc=""" %(RETAINING_OUTLINES_HELP)s""" % globals()) self.outlines_name = cps.OutlineNameProvider( "Name the outline image", "ShrunkenNucleiOutlines", doc=""" %(NAMING_OUTLINES_HELP)s""" % globals())
def create_settings(self): """Create the settings for the module Create the settings for the module during initialization. """ self.image_name = cps.ImageNameSubscriber("Select the input image", cps.NONE, doc=""" The name of a binary image from a previous module. <b>IdentifyDeadWorms</b> will use this image to establish the foreground and background for the fitting operation. You can use <b>ApplyThreshold</b> to threshold a grayscale image and create the binary mask. You can also use a module such as <b>IdentifyPrimaryObjects</b> to label each worm and then use <b>ConvertObjectsToImage</b> to make the result a mask.""") self.object_name = cps.ObjectNameProvider( "Name the dead worm objects to be identified", "DeadWorms", doc=""" This is the name for the dead worm objects. You can refer to this name in subsequent modules such as <b>IdentifySecondaryObjects</b>""") self.worm_width = cps.Integer("Worm width", 10, minval=1, doc=""" This is the width (the short axis), measured in pixels, of the diamond used as a template when matching against the worm. It should be less than the width of a worm.""") self.worm_length = cps.Integer("Worm length", 100, minval=1, doc=""" This is the length (the long axis), measured in pixels, of the diamond used as a template when matching against the worm. It should be less than the length of a worm""") self.angle_count = cps.Integer("Number of angles", 32, minval=1, doc=""" This is the number of different angles at which the template will be tried. For instance, if there are 12 angles, the template will be rotated by 0°, 15°, 30°, 45° ... 165°. The shape is bilaterally symmetric; that is, you will get the same shape after rotating it by 180°.""") self.wants_automatic_distance = cps.Binary( "Automatically calculate distance parameters?", True, doc=""" This setting determines whether or not <b>IdentifyDeadWorms</b> automatically calculates the parameters used to determine whether two found-worm centers belong to the same worm. <p>Select <i>%(YES)s</i> to have <b>IdentifyDeadWorms</b> automatically calculate the distance from the worm length and width. Select <i>%(NO)s</i> to set the distances manually.</p>""" % globals()) self.space_distance = cps.Float("Spatial distance", 5, minval=1, doc=""" <i>(Used only if not automatically calculating distance parameters)</i><br> Enter the distance for calculating the worm centers, in units of pixels. The worm centers must be at least many pixels apart for the centers to be considered two separate worms.""") self.angular_distance = cps.Float("Angular distance", 30, minval=1, doc=""" <i>(Used only if automatically calculating distance parameters)</i><br> <b>IdentifyDeadWorms</b> calculates the worm centers at different angles. Two worm centers are considered to represent different worms if their angular distance is larger than this number. The number is measured in degrees.""")
def create_settings(self): self.image_name = cps.ImageNameSubscriber("Select the input image", doc=""" Select the image that you want to use to identify objects.""") self.object_name = cps.ObjectNameProvider( "Name the primary objects to be identified", "Spots", doc=""" Enter the name that you want to call the objects identified by this module.""" ) self.atrous_level = cps.Choice(ATROUS_LEVEL_SETTING_TEXT, ["2", "3", "4", "5", "6"], doc=""" Select the level of a trous wavelet to extract as wavelet representation. """) self.smoothing_filter_size = cps.Integer( SMOOTHING_FILTER_SIZE_SETTING_TEXT, 3, doc=""" The size of a circular average filter used to smooth wavelet representation. Larger filter size will decrease the number of noisy spot detections but can also effect on the removal of real detections. """) self.noise_removal_factor = cps.Float(NOISE_REMOVAL_FACTOR_TEXT, 3.0, doc=""" Threshold for spots in wavelet representation is calculated as <i>a*std</i> where <i>a</i> is the noise removal factor. Larger value sets larger threshold and thus removes noisy spots but also decreases the overall number of the spots. """) self.final_spot_threshold = cps.Float(FINAL_SPOT_THRESHOLD_TEXT, 1e-10, doc=""" Final threshold value for detected spots. This parameter can be considered the same as fixed lower bound for threshold in IdentifyPrimaryObjects module. """) self.should_save_outlines = cps.Binary( 'Retain outlines of the identified objects?', False, doc=""" %(RETAINING_OUTLINES_HELP)s""" % globals()) self.save_outlines = cps.OutlineNameProvider('Name the outline image', "PrimaryOutlines", doc=""" %(NAMING_OUTLINES_HELP)s""" % globals()) self.limit_choice = cps.Choice( "Handling of objects if excessive number of objects identified", [LIMIT_NONE, LIMIT_TRUNCATE, LIMIT_ERASE], doc=""" This setting deals with images that are segmented into an unreasonable number of objects. This might happen if the module calculates a low threshold or if the image has unusual artifacts. <b>DetectSpots</b> can handle this condition in one of three ways: <ul> <li><i>%(LIMIT_NONE)s</i>: Don't check for large numbers of objects.</li> <li><i>%(LIMIT_TRUNCATE)s</i>: Limit the number of objects. Arbitrarily erase objects to limit the number to the maximum allowed.</li> <li><i>%(LIMIT_ERASE)s</i>: Erase all objects if the number of objects exceeds the maximum. This results in an image with no primary objects. This option is a good choice if a large number of objects indicates that the image should not be processed.</li> </ul>""" % globals()) self.maximum_object_count = cps.Integer("Maximum number of objects", value=500, minval=2, doc=""" <i>(Used only when handling images with large numbers of objects by truncating)</i> <br> This setting limits the number of objects in the image. See the documentation for the previous setting for details.""")