def create_settings(self): super(ErodeObjects, self).create_settings() self.structuring_element = StructuringElement( allow_planewise=True, doc=HELP_FOR_STREL ) self.preserve_midpoints = Binary( "Prevent object removal", True, doc=""" If set to "Yes", the central pixels for each object will not be eroded. This ensures that objects are not lost. The preserved pixels are those furtherst from the object's edge, so in some objects this may be a cluster of pixels with equal distance to the edge. If set to "No", erosion can completely remove smaller objects.""", ) self.relabel_objects = Binary( "Relabel resulting objects", False, doc=""" Large erosion filters can sometimes remove a small object or cause an irregularly shaped object to be split into two. This can cause problems in some other modules. Selecting "Yes" will assign new label numbers to resulting objects. This will ensure that there are no 'missing' labels (if object '3' is gone, object '4' will be reassigned to that number). However, this also means that parts of objects which were split and are no longer touching will be given new, individual label numbers.""", )
def create_settings(self): """Create the module settings and name the module""" self.wants_default_output_directory = Binary( "Store batch files in default output folder?", True, doc="""\ Select "*Yes*" to store batch files in the Default Output folder. Select "*No*" to enter the path to the folder that will be used to store these files. The Default Output folder can be set by clicking the "View output settings" button in the main CP window, or in CellProfiler Preferences. """ % globals(), ) self.custom_output_directory = Text( "Output folder path", get_default_output_directory(), doc= "Enter the path to the output folder. (Used only if not using the default output folder)", ) # Worded this way not because I am windows-centric but because it's # easier than listing every other OS in the universe except for VMS self.remote_host_is_windows = Binary( "Are the cluster computers running Windows?", False, doc="""\ Select "*Yes*" if the cluster computers are running one of the Microsoft Windows operating systems. In this case, **CreateBatchFiles** will modify all paths to use the Windows file separator (backslash \\\\ ). Select "*No*" for **CreateBatchFiles** to modify all paths to use the Unix or Macintosh file separator (slash / ).""" % globals(), ) self.batch_mode = Binary("Hidden: in batch mode", False) self.distributed_mode = Binary("Hidden: in distributed mode", False) self.default_image_directory = Setting( "Hidden: default input folder at time of save", get_default_image_directory(), ) self.revision = Integer("Hidden: revision number", 0) self.from_old_matlab = Binary("Hidden: from old matlab", False) self.acknowledge_old_matlab = DoSomething( "Could not update CP1.0 pipeline to be compatible with CP2.0. See module notes.", "OK", self.clear_old_matlab, ) self.mappings = [] self.add_mapping() self.add_mapping_button = DoSomething( "", "Add another path mapping", self.add_mapping, doc="""\ Use this option if another path must be mapped because there is a difference between how the local computer sees a folder location vs. how the cluster computer sees the folder location.""", )
def create_settings(self): """Create the settings & name the module""" self.images_list = ImageListSubscriber( "Select images to measure", [], doc= """Select the grayscale images whose intensity you want to measure.""", ) self.divider = Divider(line=False) self.wants_objects = Binary( "Measure the intensity only from areas enclosed by objects?", False, doc="""\ Select *Yes* to measure only those pixels within an object type you choose, identified by a prior module. Note that this module will aggregate intensities across all objects in the image: to measure each object individually, see **MeasureObjectIntensity** instead. """, ) self.objects_list = LabelListSubscriber( "Select input object sets", [], doc= """Select the object sets whose intensity you want to measure.""", )
def create_settings(self): """Make settings here (and set the module name)""" self.images = [] self.add_image(can_delete=False) self.add_image_button = DoSomething("", "Add another image", self.add_image) self.clip = Binary("Clip intensity values", False, doc="Clip the values in the illumination function between 0 and 1")
def create_settings(self): """Create the settings & name the module""" self.images_list = ImageListSubscriber( "Select images to measure", [], doc="""Select the grayscale images whose intensity you want to measure.""", ) self.divider = Divider(line=False) self.wants_objects = Binary( "Measure the intensity only from areas enclosed by objects?", False, doc="""\ Select *Yes* to measure only those pixels within an object type you choose, identified by a prior module. Note that this module will aggregate intensities across all objects in the image: to measure each object individually, see **MeasureObjectIntensity** instead. """, ) self.objects_list = LabelListSubscriber( "Select input object sets", [], doc="""Select the object sets whose intensity you want to measure.""", ) self.wants_percentiles = Binary( text="Calculate custom percentiles", value=False, doc="""Choose whether to enable measurement of custom percentiles. Note that the Upper and Lower Quartile measurements are automatically calculated by this module, representing the 25th and 75th percentiles. """, ) self.percentiles = Text( text="Specify percentiles to measure", value="10,90", doc="""Specify the percentiles to measure. Values should range from 0-100 inclusive and be whole integers. Multiple values can be specified by seperating them with a comma, eg. "10,90" will measure the 10th and 90th percentiles. """, )
def create_settings(self): """Create the settings for the module at startup and set the module name The module allows for an unlimited number of measured objects, each of which has an entry in self.object_groups. """ self.objects_list = LabelListSubscriber( "Select object sets to measure", [], doc= """Select the object sets whose size and shape you want to measure.""", ) self.spacer = Divider(line=True) self.calculate_advanced = Binary( text="Calculate the advanced features?", value=False, doc="""\ Select *{YES}* to calculate additional statistics for object moments and intertia tensors in **2D mode**. These features should not require much additional time to calculate, but do add many additional columns to the resulting output files. In **3D mode** this setting enables the Solidity measurement, which can be time-consuming to calculate.""".format(**{"YES": "Yes"}), ) self.calculate_zernikes = Binary( text="Calculate the Zernike features?", value=True, doc="""\ Select *{YES}* to calculate the Zernike shape features. Because the first 10 Zernike polynomials (from order 0 to order 9) are calculated, this operation can be time consuming if the image contains a lot of objects. Select *{NO}* if you are measuring 3D objects with this module.""".format(**{ "YES": "Yes", "NO": "No" }), )
def create_settings(self): super(Noise2Void, self).create_settings() self.ml_model = Directory("Path to ML Model", doc="""\ Select the folder containing the machine learning model to be used. This model has to be generated via the noise2void training. See https://github.com/juglab/n2v/blob/master/examples/2D/denoising2D_RGB/01_training.ipynb for an example of training. """ ) self.color = Binary("Process as color image?", value=False, doc="""\ Select whether your image should be processed as a color image or not. """) self.manual_slicing = Binary("Slice Image manually?", value=False, doc="""\ If necessary, **Noise2Void** will slice your image into tiles automatically for a better memory fit. If you want to manually determine the size of the said tiles, check this setting. Colored images **do not** support custom slicing as of right now! """) self.slicing_configuration = Text("Tile size", value="(2,2,2)", doc="""\ You can provide an image slicing configuration for Noise2Void for a better memory fit. Specify your custom slicing configuration as follows: - (x,y) for 2D Images - (x,y,z) for 3D Images, whereas x,y and z are positive integers. If your input cannot be parsed, no slicing configuration will be provided to n2v. """) self.axes_configuration = Text(text="N2V Axes", value=N2V_AXES_3D, doc="""\ For internal use only. Communicates axes configuration (2D or 3D, color or not) to n2v. """) self.x_name.doc = """\
def create_settings(self): """Make settings here (and set the module name)""" self.images = [] self.add_image(can_delete=False) self.add_image_button = DoSomething("", "Add another image", self.add_image) self.truncate_low = Binary( "Set output image values less than 0 equal to 0?", True, doc="""\ Values outside the range 0 to 1 might not be handled well by other modules. Select *"Yes"* to set negative values to 0, which was previously done automatically without ability to override. """) self.truncate_high = Binary( "Set output image values greater than 1 equal to 1?", True, doc="""\ Values outside the range 0 to 1 might not be handled well by other modules. Select *"Yes"* to set values greater than 1 to a maximum value of 1. """)
def create_settings(self): super(ConvertImageToObjects, self).create_settings() self.cast_to_bool = Binary(text="Convert to boolean image", value=True, doc=HELP_BINARY_IMAGE) self.preserve_labels = Binary( text="Preserve original labels", value=False, doc="""\ By default, this module will re-label the input image. Setting this to *{YES}* will ensure that the original labels (i.e. pixel values of the objects) are preserved. """.format(**{"YES": "Yes"}), ) self.background_label = Integer( text="Background label", value=0, doc="""\ Consider all pixels with this value as background pixels, and label them as 0. By default, 0-valued pixels are considered as background pixels. """, ) self.connectivity = Integer( text="Connectivity", minval=0, value=0, doc="""\ Maximum number of orthogonal hops to consider a pixel/voxel as a neighbor. Accepted values are ranging from 1 to the number of dimensions of the input. If set to 0, a full connectivity of the input dimension is used. """, )
def create_settings(self): """Create the settings for the module Create the settings for the module during initialization. """ self.secondary_objects_name = LabelSubscriber( "Select the larger identified objects", "None", doc="""\ Select the larger identified objects. This will usually be an object previously identified by an **IdentifySecondaryObjects** module.""", ) self.primary_objects_name = LabelSubscriber( "Select the smaller identified objects", "None", doc="""\ Select the smaller identified objects. This will usually be an object previously identified by an **IdentifyPrimaryObjects** module.""", ) self.subregion_objects_name = LabelName( "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 = Binary( "Shrink smaller object prior to subtraction?", True, doc="""\ Select *Yes* to shrink the smaller objects by 1 pixel before subtracting them from the larger objects. this approach will ensure that there is always a tertiary object produced, even if it is only 1 pixel wide. If you need alternate amounts of shrinking, use the **ExpandOrShrink** module prior to **IdentifyTertiaryObjects**. Select *No* 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). """ % globals(), )
def create_settings(self): self.flags = [] self.flag_count = HiddenCount(self.flags) self.add_flag_button = DoSomething("", "Add another flag", self.add_flag) self.spacer_1 = Divider() self.add_flag(can_delete=False) self.ignore_flag_on_last = Binary( "Ignore flag skips on last cycle?", False, doc="""\ When set to *{YES}*, this option allows you to bypass skipping on the last cycle of an image group. This behavior is usually not desired, but may be useful when using SaveImages 'Save on last cycle' option for an image made by any other module than MakeProjection, CorrectIlluminationCalculate, and Tile. """.format(**{"YES": "Yes"}), )
def create_settings(self): super(FillObjects, self).create_settings() self.size = Float( text="Minimum hole size", value=64.0, doc="Holes smaller than this diameter will be filled.", ) self.planewise = Binary( text="Planewise fill", value=False, doc="""\ Select "*{YES}*" to fill objects on a per-plane level. This will perform the hole filling on each plane of a volumetric image, rather than on the image as a whole. This may be helpful for removing seed artifacts that are the result of segmentation. **Note**: Planewise operations will be considerably slower. """.format(**{"YES": "Yes"}), )
def create_settings(self): """Create the settings & name the module""" self.images_list = ImageListSubscriber( "Select images to measure", [], doc= """Select the grayscale images whose intensity you want to measure.""", ) self.divider = Divider(line=False) self.wants_objects = Binary( "Measure the intensity only from areas enclosed by objects?", False, doc="""\ Select *Yes* to measure only those pixels within an object type you choose, identified by a prior module. Note that this module will aggregate intensities across all objects in the image: to measure each object individually, see **MeasureObjectIntensity** instead. """, ) self.objects_list = LabelListSubscriber( "Select input object sets", [], doc= """Select the object sets whose intensity you want to measure.""", ) self.nchannels = Integer( "How many channels does the image have?", 1, doc=""" Indicate how many planes this image have. This is needed as the cellprofiler pipeline needs to be independent of the actuall image data. """, )
def create_settings(self): super(FillObjects, self).create_settings() self.size = Float( text="Minimum hole size", value=64.0, doc="Holes smaller than this diameter will be filled.", ) self.planewise = Binary( text="Planewise fill", value=False, doc="""\ Select "*{YES}*" to fill objects on a per-plane level. This will perform the hole filling on each plane of a volumetric image, rather than on the image as a whole. This may be helpful for removing seed artifacts that are the result of segmentation. **Note**: Planewise operations will be considerably slower. """.format(**{"YES": "Yes"}), ) self.mode = Choice("Filling method", [MODE_HOLES, MODE_CHULL], value=MODE_HOLES, doc=f"""\ Choose the mode for hole filling. In {MODE_HOLES} mode, the module will search for and fill holes entirely enclosed by each object. Size of the holes to be removed can be controlled. In {MODE_CHULL} mode, the module will apply the convex hull of each object to fill missing pixels. This can be useful when round objects have partial holes that are not entirely enclosed. Note: Convex hulls for each object are applied sequentially and may overlap. This means that touching objects may not be perfectly convex if there was a region of overlap. """)
def create_settings(self): self.save_image_or_figure = Choice( "Select the type of image to save", IF_ALL, IF_IMAGE, doc="""\ The following types of images can be saved as a file on the hard drive: - *{IF_IMAGE}:* Any of the images produced upstream of **SaveImages** can be selected for saving. Outlines of objects created by other modules such as **Identify** modules, **Watershed**, and various object processing modules can also be saved with this option, but you must use the **OverlayOutlines** module to create them prior to saving images. Likewise, if you wish to save the objects themselves, you must use the **ConvertObjectsToImage** module to create a savable image. - *{IF_MASK}:* Relevant only if a module that produces masks has been used such as **Crop**, **MaskImage**, or **MaskObjects**. These modules create a mask of the pixels of interest in the image. Saving the mask will produce a binary image in which the pixels of interest are set to 1; all other pixels are set to 0. - *{IF_CROPPING}:* Relevant only if the **Crop** module is used. The **Crop** module also creates a cropping image which is typically the same size as the original image. However, since **Crop** permits removal of the rows and columns that are left blank, the cropping can be of a different size than the mask. - *{IF_MOVIE}:* A sequence of images can be saved as a TIFF stack. """.format( **{ "IF_CROPPING": IF_CROPPING, "IF_IMAGE": IF_IMAGE, "IF_MASK": IF_MASK, "IF_MOVIE": IF_MOVIE, } ), ) self.image_name = ImageSubscriber( "Select the image to save", doc="Select the image you want to save." ) self.file_name_method = Choice( "Select method for constructing file names", [FN_FROM_IMAGE, FN_SEQUENTIAL, FN_SINGLE_NAME], FN_FROM_IMAGE, doc="""\ *(Used only if saving non-movie files)* Several choices are available for constructing the image file name: - *{FN_FROM_IMAGE}:* The filename will be constructed based on the original filename of an input image specified in **NamesAndTypes**. You will have the opportunity to prefix or append additional text. If you have metadata associated with your images, you can append text to the image filename using a metadata tag. 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 can be provided for each image for each cycle using the **Metadata** module. - *{FN_SEQUENTIAL}:* Same as above, but in addition, each filename will have a number appended to the end that corresponds to the image cycle number (starting at 1). - *{FN_SINGLE_NAME}:* A single name will be given to the file. Since the filename is fixed, this file will be overwritten with each cycle. In this case, you would probably want to save the image on the last cycle (see the *Select how often to save* setting). The exception to this is to use a metadata tag to provide a unique label, as mentioned in the *{FN_FROM_IMAGE}* option. {USING_METADATA_TAGS_REF} {USING_METADATA_HELP_REF} """.format( **{ "FN_FROM_IMAGE": FN_FROM_IMAGE, "FN_SEQUENTIAL": FN_SEQUENTIAL, "FN_SINGLE_NAME": FN_SINGLE_NAME, "USING_METADATA_HELP_REF": _help.USING_METADATA_HELP_REF, "USING_METADATA_TAGS_REF": _help.USING_METADATA_TAGS_REF, } ), ) self.file_image_name = FileImageSubscriber( "Select image name for file prefix", "None", doc="""\ *(Used only when “{FN_FROM_IMAGE}” is selected for constructing the filename)* Select an image loaded using **NamesAndTypes**. The original filename will be used as the prefix for the output filename.""".format( **{"FN_FROM_IMAGE": FN_FROM_IMAGE} ), ) self.single_file_name = Text( SINGLE_NAME_TEXT, "OrigBlue", metadata=True, doc="""\ *(Used only when “{FN_SEQUENTIAL}” or “{FN_SINGLE_NAME}” are selected for constructing the filename)* Specify the filename text here. If you have metadata associated with your images, enter the filename text with the metadata tags. {USING_METADATA_TAGS_REF} Do not enter the file extension in this setting; it will be appended automatically.""".format( **{ "FN_SEQUENTIAL": FN_SEQUENTIAL, "FN_SINGLE_NAME": FN_SINGLE_NAME, "USING_METADATA_TAGS_REF": _help.USING_METADATA_TAGS_REF, } ), ) self.number_of_digits = Integer( "Number of digits", 4, doc="""\ *(Used only when “{FN_SEQUENTIAL}” is selected for constructing the filename)* Specify the number of digits to be used for the sequential numbering. Zeros will be used to left-pad the digits. If the number specified here is less than that needed to contain the number of image sets, the latter will override the value entered.""".format( **{"FN_SEQUENTIAL": FN_SEQUENTIAL} ), ) self.wants_file_name_suffix = Binary( "Append a suffix to the image file name?", False, doc="""\ Select "*{YES}*" to add a suffix to the image’s file name. Select "*{NO}*" to use the image name as-is. """.format( **{"NO": "No", "YES": "Yes"} ), ) self.file_name_suffix = Text( "Text to append to the image name", "", metadata=True, doc="""\ *(Used only when constructing the filename from the image filename)* Enter the text that should be appended to the filename specified above. If you have metadata associated with your images, you may use metadata tags. {USING_METADATA_TAGS_REF} Do not enter the file extension in this setting; it will be appended automatically. """.format( **{"USING_METADATA_TAGS_REF": _help.USING_METADATA_TAGS_REF} ), ) self.file_format = Choice( "Saved file format", [FF_JPEG, FF_NPY, FF_PNG, FF_TIFF, FF_H5], value=FF_TIFF, doc="""\ *(Used only when saving non-movie files)* Select the format to save the image(s). Only *{FF_TIFF}* supports saving as 16-bit or 32-bit. *{FF_TIFF}* is a "lossless" file format. *{FF_PNG}* is also a "lossless" file format and it tends to produce smaller files without losing any image data. *{FF_JPEG}* is also small but is a "lossy" file format and should not be used for any images that will undergo further quantitative analysis. Select *{FF_NPY}* to save an illumination correction image generated by **CorrectIlluminationCalculate**. Select *{FF_H5}* to save files to be used for Ilastik pixel classificaiton. The images should be correctly recognized as yxcz images.""".format( **{ "FF_NPY": FF_NPY, "FF_TIFF": FF_TIFF, "FF_PNG": FF_PNG, "FF_JPEG": FF_JPEG, "FF_H5": FF_H5, } ), ) self.pathname = SaveImagesDirectoryPath( "Output file location", self.file_image_name, doc="""\ This setting lets you choose the folder for the output files. {IO_FOLDER_CHOICE_HELP_TEXT} An additional option is the following: - *Same folder as image*: Place the output file in the same folder that the source image is located. {IO_WITH_METADATA_HELP_TEXT} If the subfolder does not exist when the pipeline is run, CellProfiler will create it. If you are creating nested subfolders using the sub-folder options, you can specify the additional folders separated with slashes. For example, “Outlines/Plate1” will create a “Plate1” folder in the “Outlines” folder, which in turn is under the Default Input/Output Folder. The use of a forward slash (“/”) as a folder separator will avoid ambiguity between the various operating systems. """.format( **{ "IO_FOLDER_CHOICE_HELP_TEXT": _help.IO_FOLDER_CHOICE_HELP_TEXT, "IO_WITH_METADATA_HELP_TEXT": _help.IO_WITH_METADATA_HELP_TEXT, } ), ) self.bit_depth = Choice( "Image bit depth", [BIT_DEPTH_8, BIT_DEPTH_16, BIT_DEPTH_FLOAT, BIT_DEPTH_RAW], doc=f"""\ Select the bit-depth at which you want to save the images. *{BIT_DEPTH_FLOAT}* saves the image as floating-point decimals with 32-bit precision. When the input data is integer or binary type, pixel values are scaled within the range (0, 1). Floating point data is not rescaled. *{BIT_DEPTH_16}* and *{BIT_DEPTH_FLOAT}* images are supported only for TIFF formats. Data is normally checked and transformed to ensure that it matches the selected format's requirements. Selecting *{BIT_DEPTH_RAW}* will attempt to automatically save to a compatible format without applying any transformations to the data. This could be used to save integer labels in 32-bit float format if you had more labels than the 16-bit format can handle (without rescaling to the 0-1 range of *{BIT_DEPTH_FLOAT}*). Note that because the data validation step is skipped some images may fail to save if they contain unusable data. Note: Opening exported multichannel 16-bit TIFF stacks in ImageJ may require the BioFormats Importer plugin due to the compression method used by CellProfiler.""", ) self.tiff_compress = Binary( "Save with lossless compression?", value=True, doc="""\ *(Used only when saving 2D images as file type tiff)* Choose whether or not to use lossless compression when saving images. This will lead to smaller file sizes, but somewhat longer module execution time. Note that the value of this setting will be ignored when saving 3D tiff images, which have been saved by default with compression since CellProfiler 3.1. Do not use for multichannel tiff images created as Stacks in GrayToColor.""" ) self.stack_axis = Choice( "How to save the series", [AXIS_T, AXIS_Z], value=AXIS_T, doc="""\ *(Used only when saving movie/stack files)* This setting determines how planes are saved into a movie/stack. Selecting "T" will save planes as a time series. Selecting "Z" will save planes as slices in a 3D z-axis. """, ) self.overwrite = Binary( "Overwrite existing files without warning?", False, doc="""\ Select "*{YES}*" to automatically overwrite a file if it already exists. Select "*{NO}*" to be prompted for confirmation first. If you are running the pipeline on a computing cluster, select "*{YES}*" since you will not be able to intervene and answer the confirmation prompt.""".format( **{"NO": "No", "YES": "Yes"} ), ) self.when_to_save = Choice( "When to save", [WS_EVERY_CYCLE, WS_FIRST_CYCLE, WS_LAST_CYCLE], WS_EVERY_CYCLE, doc="""\ *(Used only when saving non-movie files)* Specify at what point during pipeline execution to save file(s). - *{WS_EVERY_CYCLE}:* Useful for when the image of interest is created every cycle and is not dependent on results from a prior cycle. - *{WS_FIRST_CYCLE}:* Useful for when you are saving an aggregate image created on the first cycle, e.g., **CorrectIlluminationCalculate** with the *All* setting used on images obtained directly from **NamesAndTypes**. - *{WS_LAST_CYCLE}:* Useful for when you are saving an aggregate image completed on the last cycle, e.g., **CorrectIlluminationCalculate** with the *All* setting used on intermediate images generated during each cycle.""".format( **{ "WS_EVERY_CYCLE": WS_EVERY_CYCLE, "WS_FIRST_CYCLE": WS_FIRST_CYCLE, "WS_LAST_CYCLE": WS_LAST_CYCLE, } ), ) self.update_file_names = Binary( "Record the file and path information to the saved image?", False, doc="""\ Select "*{YES}*" to store filename and pathname data for each of the new files created via this module as a per-image measurement. Instances in which this information may be useful include: - Exporting measurements to a database, allowing access to the saved image. If you are using the machine-learning tools or image viewer in CellProfiler Analyst, for example, you will want to enable this setting if you want the saved images to be displayed along with the original images.""".format( **{"YES": "Yes"} ), ) self.create_subdirectories = Binary( "Create subfolders in the output folder?", False, doc=""" Select "*{YES}*" to create subfolders to match the input image folder structure. For example, if your input images are organized into subfolders (e.g., for each plate, well, animal, etc.), this option allows you to mirror some or all of that nested folder structure in the output folder.""".format( **{"YES": "Yes"} ), ) self.root_dir = Directory( "Base image folder", doc="""\ *Used only if creating subfolders in the output folder* In subfolder mode, **SaveImages** determines the folder for an output image file by examining the path of the matching input file. You should choose as **Base image folder** the input folder that has the structure you'd like to mirror in the output folder. Consider an example where your input images are stored in a nested folder structure of "images\/experiment-name\/plate-name" (i.e., your files are in folders for each plate, nested inside of folders for each experiment, nested in a parent folder called "images"). If you select the base image folder to be **images**, **SaveImages** will go to your "Output file location" and save images in subfolders "experiment-name\/plate-name" that corresponds to each input image. If the base image folder chosen is one level deeper at "images\/experiment-name", **SaveImages** will store images in subfolders for each "plate-name" they belong to. **Warning**: Do not select the same folder you selected for "Output file location" as this can lead to unexpected behavior like saving in the original input file directory. For safety, ensure "Overwrite existing files without warning?" is set to "No" while testing this option. """, )
def create_settings(self): super(RelateObjects, self).create_settings() self.x_name.text = "Parent objects" self.x_name.doc = """\ Parent objects are defined as those objects which encompass the child object. For example, when relating speckles to the nuclei that contain them, the nuclei are the parents. """ self.y_name = LabelSubscriber( "Child objects", doc="""\ Child objects are defined as those objects contained within the parent object. For example, when relating speckles to the nuclei that contains them, the speckles are the children. """, ) self.find_parent_child_distances = Choice( "Calculate child-parent distances?", D_ALL, doc="""\ Choose the method to calculate distances of each child to its parent. For example, these measurements can tell you whether nuclear speckles are located more closely to the center of the nucleus or to the nuclear periphery. - *{D_NONE}:* Do not calculate any distances. This saves computation time. - *{D_MINIMUM}:* The distance from the centroid of the child object to the closest perimeter point on the parent object. - *{D_CENTROID}:* The distance from the centroid of the child object to the centroid of the parent. - *{D_BOTH}:* Calculate both the *{D_MINIMUM}* and *{D_CENTROID}* distances.""".format( **{ "D_NONE": D_NONE, "D_MINIMUM": D_MINIMUM, "D_CENTROID": D_CENTROID, "D_BOTH": D_BOTH, }), ) self.wants_step_parent_distances = Binary( "Calculate distances to other parents?", False, doc="""\ *(Used only if calculating distances)* Select "*{YES}*" to calculate the distances of the child objects to some other objects. These objects must be either parents or children of your parent object in order for this module to determine the distances. For instance, you might find “Nuclei” using **IdentifyPrimaryObjects**, find “Cells” using **IdentifySecondaryObjects** and find “Cytoplasm” using **IdentifyTertiaryObjects**. You can use **Relate** to relate speckles to cells and then measure distances to nuclei and cytoplasm. You could not use **RelateObjects** to relate speckles to cytoplasm and then measure distances to nuclei, because nuclei are neither a direct parent nor child of cytoplasm.""".format(**{"YES": "Yes"}), ) self.step_parent_names = [] self.add_step_parent(can_delete=False) self.add_step_parent_button = DoSomething("", "Add another parent", self.add_step_parent) self.wants_per_parent_means = Binary( "Calculate per-parent means for all child measurements?", False, doc="""\ Select "*{YES}*" to calculate the per-parent mean values of every upstream measurement made with the children objects and store them as a measurement for the parent; the nomenclature of this new measurement is “Mean_<child>_<category>_<feature>”. This module must be placed *after* all **Measure** modules that make measurements of the children objects.""".format(**{"YES": "Yes"}), ) self.wants_child_objects_saved = Binary( "Do you want to save the children with parents as a new object set?", False, doc="""\ Select "*{YES}*" to save the children objects that do have parents as new object set. Objects with no parents will be discarded""".format( **{"YES": "Yes"}), ) self.output_child_objects_name = LabelName( "Name the output object", "RelateObjects", doc="""\ Enter the name you want to call the object produced by this module. """, )
def create_settings(self): self.blank_image = Binary( "Display outlines on a blank image?", False, doc="""\ Select "*{YES}*" to produce an image of the outlines on a black background. Select "*{NO}*" to overlay the outlines on an image you choose. """.format( **{"YES": "Yes", "NO": "No"} ), ) self.image_name = ImageSubscriber( "Select image on which to display outlines", "None", doc="""\ *(Used only when a blank image has not been selected)* Choose the image to serve as the background for the outlines. You can choose from images that were loaded or created by modules previous to this one. """, ) self.line_mode = Choice( "How to outline", ["Inner", "Outer", "Thick"], value="Inner", doc="""\ Specify how to mark the boundaries around an object: - *Inner:* outline the pixels just inside of objects, leaving background pixels untouched. - *Outer:* outline pixels in the background around object boundaries. When two objects touch, their boundary is also marked. - *Thick:* any pixel not completely surrounded by pixels of the same label is marked as a boundary. This results in boundaries that are 2 pixels thick. """, ) self.output_image_name = ImageName( "Name the output image", "OrigOverlay", doc="""\ Enter the name of the output image with the outlines overlaid. This image can be selected in later modules (for instance, **SaveImages**). """, ) self.wants_color = Choice( "Outline display mode", [WANTS_COLOR, WANTS_GRAYSCALE], doc="""\ Specify how to display the outline contours around your objects. Color outlines produce a clearer display for images where the cell borders have a high intensity, but take up more space in memory. Grayscale outlines are displayed with either the highest possible intensity or the same intensity as the brightest pixel in the image. """, ) self.spacer = Divider(line=False) self.max_type = Choice( "Select method to determine brightness of outlines", [MAX_IMAGE, MAX_POSSIBLE], doc="""\ *(Used only when outline display mode is grayscale)* The following options are possible for setting the intensity (brightness) of the outlines: - *{MAX_IMAGE}:* Set the brightness to the the same as the brightest point in the image. - *{MAX_POSSIBLE}:* Set to the maximum possible value for this image format. If your image is quite dim, then putting bright white lines onto it may not be useful. It may be preferable to make the outlines equal to the maximal brightness already occurring in the image. """.format( **{"MAX_IMAGE": MAX_IMAGE, "MAX_POSSIBLE": MAX_POSSIBLE} ), ) self.outlines = [] self.add_outline(can_remove=False) self.add_outline_button = DoSomething( "", "Add another outline", self.add_outline )
def create_settings(self): super(RunStarDist, self).create_settings() self.model = Choice( text="Model", choices=MODEL_OPTIONS, value=GREY_1, doc="""\ StarDist comes with models for detecting nuclei. Alternatively, you can supply a custom-trained model generated outside of CellProfiler within Python. Custom models can be useful if working with unusual cell types. The inbuilt fluorescent and DSB models expect greyscale images. The H&E model expects a color image as input (from brightfield). Custom models will require images of the type they were trained with. It should be noted that the models supplied with StarDist do not support 3D images, but it's possible to train and use your own. """, ) self.tile_image = Binary( text="Tile input image?", value=False, doc="""\ If enabled, the input image will be broken down into overlapping tiles. This can help to conserve memory when working with large images. The image is split into a set number of vertical and horizontal tiles. The total number of tiles will be the result of multiplying the horizontal and vertical tile number.""", ) self.n_tiles_x = Integer(text="Horizontal tiles", value=1, minval=1, doc="""\ Specify the number of tiles to break the image down into along the x-axis (horizontal).""" ) self.n_tiles_y = Integer(text="Vertical tiles", value=1, minval=1, doc="""\ Specify the number of tiles to break the image down into along the y-axis (vertical).""" ) self.save_probabilities = Binary( text="Save probability image?", value=False, doc=""" If enabled, the probability scores from the model will be recorded as a new image. Probability scales from 0-1, with 1 representing absolute certainty of a pixel being in a cell. You may want to use a custom threshold to manually generate objects.""", ) self.probabilities_name = ImageName( "Name the probability image", "Probabilities", doc= "Enter the name you want to call the probability image produced by this module.", ) self.model_directory = Directory("Model folder", doc=f"""\ *(Used only when using a custom pre-trained model)* Select the folder containing your StarDist model. This should have the config, threshold and weights files exported after training.""") self.gpu_test = DoSomething( "", "Test GPU", self.do_check_gpu, doc=f"""\ Press this button to check whether a GPU is correctly configured. If you have a dedicated GPU, a failed test usually means that either your GPU does not support deep learning or the required dependencies are not installed. Make sure you followed the setup instructions here: https://www.tensorflow.org/install/gpu If you don't have a GPU or it's not configured, StarDist will instead run on the CPU. This will be slower but should work on any system. """, )
def create_settings(self): super(RunCellpose, self).create_settings() self.expected_diameter = Integer( text="Expected object diameter", value=15, minval=0, doc="""\ The average diameter of the objects to be detected. Setting this to 0 will attempt to automatically detect object size. Note that automatic diameter mode does not work when running on 3D images. Cellpose models come with a pre-defined object diameter. Your image will be resized during detection to attempt to match the diameter expected by the model. The default models have an expected diameter of ~16 pixels, if trying to detect much smaller objects it may be more efficient to resize the image first using the Resize module. """, ) self.mode = Choice( text="Detection mode", choices=[MODE_NUCLEI, MODE_CELLS, MODE_CUSTOM], value=MODE_NUCLEI, doc="""\ CellPose comes with models for detecting nuclei or cells. Alternatively, you can supply a custom-trained model generated using the command line or Cellpose GUI. Custom models can be useful if working with unusual cell types. """, ) self.use_gpu = Binary(text="Use GPU", value=False, doc=f"""\ If enabled, Cellpose will attempt to run detection on your system's graphics card (GPU). Note that you will need a CUDA-compatible GPU and correctly configured PyTorch version, see this link for details: {CUDA_LINK} If disabled or incorrectly configured, Cellpose will run on your CPU instead. This is much slower but more compatible with different hardware setups. Note that, particularly when in 3D mode, lack of GPU memory can become a limitation. If a model crashes you may need to re-start CellProfiler to release GPU memory. Resizing large images prior to running them through the model can free up GPU memory. """) self.use_averaging = Binary(text="Use averaging", value=True, doc="""\ If enabled, CellPose will run it's 4 inbuilt models and take a consensus to determine the results. If disabled, only a single model will be called to produce results. Disabling averaging is faster to run but less accurate.""" ) self.supply_nuclei = Binary(text="Supply nuclei image as well?", value=False, doc=""" When detecting whole cells, you can provide a second image featuring a nuclear stain to assist the model with segmentation. This can help to split touching cells.""") self.nuclei_image = ImageSubscriber( "Select the nuclei image", doc="Select the image you want to use as the nuclear stain.") self.save_probabilities = Binary( text="Save probability image?", value=False, doc=""" If enabled, the probability scores from the model will be recorded as a new image. Probability >0 is considered as being part of a cell. You may want to use a higher threshold to manually generate objects.""", ) self.probabilities_name = ImageName( "Name the probability image", "Probabilities", doc= "Enter the name you want to call the probability image produced by this module.", ) self.model_directory = Directory( "Location of the pre-trained model file", doc=f"""\ *(Used only when using a custom pre-trained model)* Select the location of the pre-trained CellPose model file that will be used for detection.""" ) def get_directory_fn(): """Get the directory for the rules file name""" return self.model_directory.get_absolute_path() def set_directory_fn(path): dir_choice, custom_path = self.model_directory.get_parts_from_path( path) self.model_directory.join_parts(dir_choice, custom_path) self.model_file_name = Filename("Pre-trained model file name", "cyto_0", get_directory_fn=get_directory_fn, set_directory_fn=set_directory_fn, doc=f"""\ *(Used only when using a custom pre-trained model)* This file can be generated by training a custom model withing the CellPose GUI or command line applications.""" ) self.gpu_test = DoSomething( "", "Test GPU", self.do_check_gpu, doc=f"""\ Press this button to check whether a GPU is correctly configured. If you have a dedicated GPU, a failed test usually means that either your GPU does not support deep learning or the required dependencies are not installed. If you have multiple GPUs on your system, this button will only test the first one. """, ) self.flow_threshold = Float( text="Flow threshold", value=0.4, minval=0, doc= """Flow error threshold. All cells with errors below this threshold are kept. Recommended default is 0.4""", ) self.dist_threshold = Float( text="Cell probability threshold", value=0.0, minval=0, doc=f"""\ Cell probability threshold (all pixels with probability above threshold kept for masks). Recommended default is 0.0. """, )
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 = .ImageSubscriber(...) # Ask the user for the name of the output image self.output_image = .ImageName(...) # Ask the user for a parameter self.smoothing_size = .Float(...) """ self.object_name = LabelSubscriber( "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 **Identify** modules (e.g., "*IdentifyPrimaryObjects*", "*IdentifySecondaryObjects*" etc.).""", ) self.filtered_objects = LabelName( "Name the edited objects", "EditedObjects", doc="""\ Enter the name for the objects that remain after editing. These objects will be available for use by subsequent modules.""", ) self.allow_overlap = Binary( "Allow overlapping objects?", False, doc="""\ **EditObjectsManually** 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. Select "*Yes*" to allow overlaps or select "*No*" to prevent them. """ % globals(), ) self.renumber_choice = 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: - *%(R_RENUMBER)s:* The 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. - *%(R_RETAIN)s:* This option 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). """ % globals(), ) self.wants_image_display = Binary( "Display a guiding image?", True, doc="""\ Select "*Yes*" to display an image and outlines of the objects. Select "*No*" if you do not want a guide image while editing. """ % globals(), ) self.image_name = ImageSubscriber( "Select the guiding image", "None", doc="""\ *(Used only if a guiding image is desired)* This is the image that will appear when editing objects. Choose an image supplied by a previous module. """, )
def create_settings(self): self.image_name = ImageSubscriber( "Select the input image", "None", doc="""Select the image to be smoothed.""", ) self.filtered_image_name = ImageName( "Name the output image", "FilteredImage", doc="""Enter a name for the resulting image.""", ) self.smoothing_method = 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 = 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* 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* to manually enter an artifact diameter. """ % globals(), ) self.object_size = Float( "Typical artifact diameter", 16.0, doc="""\ *(Used only if choosing the artifact diameter automatically is set to “No”)* 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. {} For most smoothing methods, selecting a diameter over ~50 will take substantial amounts of time to process. """.format( HELP_ON_MEASURING_DISTANCES ), ) self.sigma_range = Float( "Edge intensity difference", 0.1, doc="""\ *(Used only if “{smooth_help}” 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. {pixel_help} """.format( smooth_help=SMOOTH_KEEPING_EDGES, pixel_help=HELP_ON_PIXEL_INTENSITIES ), ) self.clip = Binary( "Clip intensities to 0 and 1?", True, doc="""\ *(Used only if "{fit}" is selected)* The *{fit}* 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* to set all output image pixels less than zero to zero and all pixels greater than one to one. Select *No* to allow values less than zero and greater than one in the output image. """.format( fit=FIT_POLYNOMIAL ), )
def create_settings(self): self.scheme_choice = Choice( "Select a color scheme", [SCHEME_RGB, SCHEME_CMYK, SCHEME_STACK, SCHEME_COMPOSITE], doc="""\ This module can use one of two color schemes to combine images: - *%(SCHEME_RGB)s*: Each input image determines the intensity of one of the color channels: red, green, and blue. - *%(SCHEME_CMYK)s*: Three of the input images are combined to determine the colors (cyan, magenta, and yellow) and a fourth is used only for brightness. The cyan image adds equally to the green and blue intensities. The magenta image adds equally to the red and blue intensities. The yellow image adds equally to the red and green intensities. - *%(SCHEME_STACK)s*: The channels are stacked in the order listed, from top to bottom. An arbitrary number of channels is allowed. For example, you could create a 5-channel image by providing 5 grayscale images. The first grayscale image you provide will fill the first channel, the second grayscale image you provide will fill the second channel, and so on. - *%(SCHEME_COMPOSITE)s*: A color is assigned to each grayscale image. Each grayscale image is converted to color by multiplying the intensity by the color and the resulting color images are added together. An arbitrary number of channels can be composited into a single color image. """ % globals(), ) self.wants_rescale = Binary( "Rescale intensity", True, doc="""\ Choose whether to rescale each channel individually to the range of 0-1. This prevents clipping of channels with intensity above 1 and can help to balance the brightness of the different channels. This option also ensures that channels occupy the full intensity range available, which is useful for displaying images in other software. This rescaling is applied before any multiplication factors set in this module's options. Using a multiplication factor >1 would therefore result in clipping.""" ) # # # # # # # # # # # # # # # # # # RGB settings # # # # # # # # # # # # # # # # # self.red_image_name = ImageSubscriber( "Select the image to be colored red", can_be_blank=True, blank_text=LEAVE_THIS_BLACK, doc="""\ *(Used only if "%(SCHEME_RGB)s" is selected as the color scheme)* Select the input image to be displayed in red. """ % globals(), ) self.green_image_name = ImageSubscriber( "Select the image to be colored green", can_be_blank=True, blank_text=LEAVE_THIS_BLACK, doc="""\ *(Used only if "%(SCHEME_RGB)s" is selected as the color scheme)* Select the input image to be displayed in green. """ % globals(), ) self.blue_image_name = ImageSubscriber( "Select the image to be colored blue", can_be_blank=True, blank_text=LEAVE_THIS_BLACK, doc="""\ *(Used only if "%(SCHEME_RGB)s" is selected as the color scheme)* Select the input image to be displayed in blue. """ % globals(), ) self.rgb_image_name = ImageName( "Name the output image", "ColorImage", doc="""Enter a name for the resulting image.""", ) self.red_adjustment_factor = Float( "Relative weight for the red image", value=1, minval=0, doc="""\ *(Used only if "%(SCHEME_RGB)s" is selected as the color scheme)* Enter the relative weight for the red image. 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. """ % globals(), ) self.green_adjustment_factor = Float( "Relative weight for the green image", value=1, minval=0, doc="""\ *(Used only if "%(SCHEME_RGB)s" is selected as the color scheme)* Enter the relative weight for the green image. 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. """ % globals(), ) self.blue_adjustment_factor = Float( "Relative weight for the blue image", value=1, minval=0, doc="""\ *(Used only if "%(SCHEME_RGB)s" is selected as the color scheme)* Enter the relative weight for the blue image. 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. """ % globals(), ) # # # # # # # # # # # # # # # # CYMK settings # # # # # # # # # # # # # # # self.cyan_image_name = ImageSubscriber( "Select the image to be colored cyan", can_be_blank=True, blank_text=LEAVE_THIS_BLACK, doc="""\ *(Used only if "%(SCHEME_CMYK)s" is selected as the color scheme)* Select the input image to be displayed in cyan. """ % globals(), ) self.magenta_image_name = ImageSubscriber( "Select the image to be colored magenta", can_be_blank=True, blank_text=LEAVE_THIS_BLACK, doc="""\ *(Used only if "%(SCHEME_CMYK)s" is selected as the color scheme)* Select the input image to be displayed in magenta. """ % globals(), ) self.yellow_image_name = ImageSubscriber( "Select the image to be colored yellow", can_be_blank=True, blank_text=LEAVE_THIS_BLACK, doc="""\ *(Used only if "%(SCHEME_CMYK)s" is selected as the color scheme)* Select the input image to be displayed in yellow. """ % globals(), ) self.gray_image_name = ImageSubscriber( "Select the image that determines brightness", can_be_blank=True, blank_text=LEAVE_THIS_BLACK, doc="""\ *(Used only if "%(SCHEME_CMYK)s" is selected as the color scheme)* Select the input image that will determine each pixel's brightness. """ % globals(), ) self.cyan_adjustment_factor = Float( "Relative weight for the cyan image", value=1, minval=0, doc="""\ *(Used only if "%(SCHEME_CMYK)s" is selected as the color scheme)* Enter the relative weight for the cyan image. If all relative weights are equal, all colors contribute equally in the final image. To weight colors relative to each other, increase or decrease the relative weights. """ % globals(), ) self.magenta_adjustment_factor = Float( "Relative weight for the magenta image", value=1, minval=0, doc="""\ *(Used only if "%(SCHEME_CMYK)s" is selected as the color scheme)* Enter the relative weight for the magenta image. If all relative weights are equal, all colors contribute equally in the final image. To weight colors relative to each other, increase or decrease the relative weights. """ % globals(), ) self.yellow_adjustment_factor = Float( "Relative weight for the yellow image", value=1, minval=0, doc="""\ *(Used only if "%(SCHEME_CMYK)s" is selected as the color scheme)* Enter the relative weight for the yellow image. If all relative weights are equal, all colors contribute equally in the final image. To weight colors relative to each other, increase or decrease the relative weights. """ % globals(), ) self.gray_adjustment_factor = Float( "Relative weight for the brightness image", value=1, minval=0, doc="""\ *(Used only if "%(SCHEME_CMYK)s" is selected as the color scheme)* Enter the relative weight for the brightness image. If all relative weights are equal, all colors contribute equally in the final image. To weight colors relative to each other, increase or decrease the relative weights. """ % globals(), ) # # # # # # # # # # # # # # # # Stack settings # # # # # # # # # # # # # # # self.stack_channels = [] self.stack_channel_count = HiddenCount(self.stack_channels) self.add_stack_channel_cb(can_remove=False) self.add_stack_channel = 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): """Create the module settings create_settings is called at the end of initialization. """ self.object = LabelSubscriber( text="Select the object whose measurements will be displayed", value="None", doc=textwrap.dedent("""\ Choose the name of objects identified by some previous module (such as **IdentifyPrimaryObjects** or **IdentifySecondaryObjects**) whose measurements are to be displayed. """), ) self.x_axis = Measurement( text="Select the object measurement to plot", object_fn=self.get_object, value="None", doc= "Choose the object measurement made by a previous module to plot.", ) self.bins = Integer( text="Number of bins", value=100, minval=1, maxval=1000, doc= "Enter the number of equally-spaced bins that you want used on the X-axis.", ) self.xscale = Choice( text="How should the X-axis be scaled?", choices=["linear", "log"], value=None, doc=textwrap.dedent("""\ The measurement data can be scaled with either a **{LINEAR}** scale or a **{LOG_NATURAL}** (natural log) scaling. Log scaling is useful when one of the measurements being plotted covers a large range of values; a log scale can bring out features in the measurements that would not easily be seen if the measurement is plotted linearly. """.format( LINEAR="linear", LOG_NATURAL="log", )), ) self.yscale = Choice( text="How should the Y-axis be scaled?", choices=["linear", "log"], value=None, doc=textwrap.dedent("""\ The Y-axis can be scaled either with either a **{LINEAR}** scale or a **{LOG_NATURAL}** (natural log) scaling. Log scaling is useful when one of the measurements being plotted covers a large range of values; a log scale can bring out features in the measurements that would not easily be seen if the measurement is plotted linearly. """.format( LINEAR="linear", LOG_NATURAL="log", )), ) self.title = Text( text="Enter a title for the plot, if desired", value="", doc=textwrap.dedent("""\ Enter a title for the plot. If you leave this blank, the title will default to *(cycle N)* where *N* is the current image cycle being executed. """), ) self.wants_xbounds = Binary( text="Specify min/max bounds for the X-axis?", value=False, doc=textwrap.dedent("""\ Select "**{YES}**" to specify minimum and maximum values for the plot on the X-axis. This is helpful if an outlier bin skews the plot such that the bins of interest are no longer visible. """.format(YES="Yes")), ) self.xbounds = FloatRange( text="Minimum/maximum values for the X-axis", doc="Set lower/upper limits for X-axis of the histogram.", )
def create_settings(self): """Create the settings for the module Create the settings for the module during initialization. """ self.image_name = ImageSubscriber( "Select the input image", "None", doc="""\ The name of a binary image from a previous module. **IdentifyDeadWorms** will use this image to establish the foreground and background for the fitting operation. You can use **ApplyThreshold** to threshold a grayscale image and create the binary mask. You can also use a module such as **IdentifyPrimaryObjects** to label each worm and then use **ConvertObjectsToImage** to make the result a mask. """, ) self.object_name = LabelName( "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 **IdentifySecondaryObjects**""", ) self.worm_width = 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 = 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 = 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 = Binary( "Automatically calculate distance parameters?", True, doc="""\ This setting determines whether or not **IdentifyDeadWorms** automatically calculates the parameters used to determine whether two found-worm centers belong to the same worm. Select "*Yes*" to have **IdentifyDeadWorms** automatically calculate the distance from the worm length and width. Select "*No*" to set the distances manually. """ % globals(), ) self.space_distance = Float( "Spatial distance", 5, minval=1, doc="""\ *(Used only if not automatically calculating distance parameters)* 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 = Float( "Angular distance", 30, minval=1, doc="""\ *(Used only if automatically calculating distance parameters)* **IdentifyDeadWorms** 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): """Create the settings here and set the module name (initialization) """ self.source_choice = 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 = LabelSubscriber( "Select object for mask", "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 = ImageSubscriber( "Select image for mask", "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 = ImageSubscriber( "Select the input image", "None", doc="Select the image that you want to mask.", ) self.masked_image_name = ImageName( "Name the output image", "MaskBlue", doc="Enter the name for the output masked image.", ) self.invert_mask = Binary( "Invert the mask?", False, doc="""\ This option reverses the foreground/background relationship of the mask. - Select "*No*" to produce the mask from the foreground (white portion) of the masking image or the area within the masking objects. - Select "*Yes*" to instead produce the mask from the *background* (black portions) of the masking image or the area *outside* the masking objects. """ % globals(), )
def create_settings(self): self.ground_truth = ImageSubscriber( "Select the image to be used as the ground truth basis for calculating the amount of overlap", "None", doc="""\ This binary (black and white) image is known as the “ground truth” image. It can be the product of segmentation performed by hand, or the result of another segmentation algorithm whose results you would like to compare.""", ) self.test_img = ImageSubscriber( "Select the image to be used to test for overlap", "None", doc="""\ This binary (black and white) image is what you will compare with the ground truth image. It is known as the “test image”.""", ) self.wants_emd = Binary( "Calculate earth mover's distance?", False, doc="""\ The earth mover’s distance computes the shortest distance that would have to be travelled to move each foreground pixel in the test image to some foreground pixel in the reference image. “Earth mover’s” refers to an analogy: the pixels are “earth” that has to be moved by some machine at the smallest possible cost. It would take too much memory and processing time to compute the exact earth mover’s distance, so **MeasureImageOverlap** chooses representative foreground pixels in each image and assigns each foreground pixel to its closest representative. The earth mover’s distance is then computed for moving the foreground pixels associated with each representative in the test image to those in the reference image.""", ) self.max_points = Integer( "Maximum # of points", value=250, minval=100, doc="""\ *(Used only when computing the earth mover’s distance)* This is the number of representative points that will be taken from the foreground of the test image and from the foreground of the reference image using the point selection method (see below).""", ) self.decimation_method = Choice( "Point selection method", choices=[DM_KMEANS, DM_SKEL], doc="""\ *(Used only when computing the earth mover’s distance)* The point selection setting determines how the representative points are chosen. - *{DM_KMEANS}:* Select to pick representative points using a K-Means clustering technique. The foregrounds of both images are combined and representatives are picked that minimize the distance to the nearest representative. The same representatives are then used for the test and reference images. - *{DM_SKEL}:* Select to skeletonize the image and pick points equidistant along the skeleton. |image0| *{DM_KMEANS}* is a choice that’s generally applicable to all images. *{DM_SKEL}* is best suited to long, skinny objects such as worms or neurites. .. |image0| image:: {PROTIP_RECOMMEND_ICON} """.format( **{ "DM_KMEANS": DM_KMEANS, "DM_SKEL": DM_SKEL, "PROTIP_RECOMMEND_ICON": _help.PROTIP_RECOMMEND_ICON, }), ) self.max_distance = Integer( "Maximum distance", value=250, minval=1, doc="""\ *(Used only when computing the earth mover’s distance)* This setting sets an upper bound to the distance penalty assessed during the movement calculation. As an example, the score for moving 10 pixels from one location to a location that is 100 pixels away is 10\*100, but if the maximum distance were set to 50, the score would be 10\*50 instead. The maximum distance should be set to the largest reasonable distance that pixels could be expected to move from one image to the next.""", ) self.penalize_missing = Binary( "Penalize missing pixels", value=False, doc="""\ *(Used only when computing the earth mover’s distance)* If one image has more foreground pixels than the other, the earth mover’s distance is not well-defined because there is no destination for the extra source pixels or vice-versa. It’s reasonable to assess a penalty for the discrepancy when comparing the accuracy of a segmentation because the discrepancy represents an error. It’s also reasonable to assess no penalty if the goal is to compute the cost of movement, for example between two frames in a time-lapse movie, because the discrepancy is likely caused by noise or artifacts in segmentation. Set this setting to “Yes” to assess a penalty equal to the maximum distance times the absolute difference in number of foreground pixels in the two images. Set this setting to “No” to assess no penalty.""", )
def create_settings(self): # the list of per image settings (name & scaling factor) self.images = [] # create the first two images (the default number) self.add_image(False) self.add_image(False) # other settings self.operation = Choice( "Operation", [ O_ADD, O_SUBTRACT, O_DIFFERENCE, O_MULTIPLY, O_DIVIDE, O_AVERAGE, O_MINIMUM, O_MAXIMUM, O_INVERT, O_LOG_TRANSFORM, O_LOG_TRANSFORM_LEGACY, O_AND, O_OR, O_NOT, O_EQUALS, O_NONE, ], doc="""\ Select the operation to perform. Note that if more than two images are chosen, then operations will be performed sequentially from first to last, e.g., for “Divide”, (Image1 / Image2) / Image3 - *%(O_ADD)s:* Adds the first image to the second, and so on. - *%(O_SUBTRACT)s:* Subtracts the second image from the first. - *%(O_DIFFERENCE)s:* The absolute value of the difference between the first and second images. - *%(O_MULTIPLY)s:* Multiplies the first image by the second. - *%(O_DIVIDE)s:* Divides the first image by the second. - *%(O_AVERAGE)s:* Calculates the mean intensity of the images loaded in the module. This is equivalent to the Add option divided by the number of images loaded by this module. If you would like to average all of the images in an entire pipeline, i.e., across cycles, you should instead use the **CorrectIlluminationCalculate** module and choose the *All* (vs. *Each*) option. - *%(O_MINIMUM)s:* Returns the element-wise minimum value at each pixel location. - *%(O_MAXIMUM)s:* Returns the element-wise maximum value at each pixel location. - *%(O_INVERT)s:* Subtracts the image intensities from 1. This makes the darkest color the brightest and vice-versa. Note that if a mask has been applied to the image, the mask will also be inverted. - *%(O_LOG_TRANSFORM)s:* Log transforms each pixel’s intensity. The actual function is log\ :sub:`2`\ (image + 1), transforming values from 0 to 1 into values from 0 to 1. - *%(O_LOG_TRANSFORM_LEGACY)s:* Log\ :sub:`2` transform for backwards compatibility. - *%(O_NONE)s:* This option is useful if you simply want to select some of the later options in the module, such as adding, multiplying, or exponentiating your image by a constant. The following are operations that produce binary images. In a binary image, the foreground has a truth value of “true” (ones) and the background has a truth value of “false” (zeros). The operations, *%(O_OR)s, %(O_AND)s and %(O_NOT)s* will convert the input images to binary by changing all zero values to background (false) and all other values to foreground (true). - *%(O_AND)s:* a pixel in the output image is in the foreground only if all corresponding pixels in the input images are also in the foreground. - *%(O_OR)s:* a pixel in the output image is in the foreground if a corresponding pixel in any of the input images is also in the foreground. - *%(O_NOT)s:* the foreground of the input image becomes the background of the output image and vice-versa. - *%(O_EQUALS)s:* a pixel in the output image is in the foreground if the corresponding pixels in the input images have the same value. Note that *%(O_INVERT)s*, *%(O_LOG_TRANSFORM)s*, *%(O_LOG_TRANSFORM_LEGACY)s* and *%(O_NONE)s* operate on only a single image. """ % globals(), ) self.divider_top = Divider(line=False) self.exponent = Float( "Raise the power of the result by", 1, doc="""\ Enter an exponent to raise the result to *after* the chosen operation.""", ) self.after_factor = Float( "Multiply the result by", 1, doc="""\ Enter a factor to multiply the result by *after* the chosen operation.""", ) self.addend = Float( "Add to result", 0, doc="""\ Enter a number to add to the result *after* the chosen operation.""", ) self.truncate_low = Binary( "Set values less than 0 equal to 0?", True, doc="""\ Values outside the range 0 to 1 might not be handled well by other modules. Select *Yes* to set negative values to 0. """ % globals(), ) self.truncate_high = Binary( "Set values greater than 1 equal to 1?", True, doc="""\ Values outside the range 0 to 1 might not be handled well by other modules. Select *Yes* to set values greater than 1 to a maximum value of 1. """ % globals(), ) self.replace_nan = Binary( "Replace invalid values with 0?", True, doc="""\ Certain operations are mathematically invalid (divide by zero, raise a negative number to the power of a fraction, etc.). This setting will set pixels with invalid values to zero. Disabling this setting will represent these pixels as "nan" ("Not A Number"). "nan" pixels cannot be displayed properly and may cause errors in other modules. """ % globals(), ) self.ignore_mask = Binary( "Ignore the image masks?", False, doc="""\ Select *Yes* to set equal to zero all previously masked pixels and operate on the masked images as if no mask had been applied. Otherwise, the smallest image mask is applied after image math has been completed. """ % globals(), ) self.output_image_name = ImageName( "Name the output image", "ImageAfterMath", doc="""\ Enter a name for the resulting image.""", ) self.add_button = DoSomething("", "Add another image", self.add_image) self.divider_bottom = Divider(line=False)
def create_settings(self): self.directory = Directory("Output file location", dir_choices=[ ABSOLUTE_FOLDER_NAME, DEFAULT_OUTPUT_FOLDER_NAME, DEFAULT_OUTPUT_SUBFOLDER_NAME, DEFAULT_INPUT_FOLDER_NAME, DEFAULT_INPUT_SUBFOLDER_NAME ], doc=""" This setting lets you choose the folder for the output files. %(IO_FOLDER_CHOICE_HELP_TEXT)s %(IO_WITH_METADATA_HELP_TEXT)s """ % globals()) self.directory.dir_choice = DEFAULT_OUTPUT_FOLDER_NAME self.wants_file_name_suffix = Binary( "Append a suffix to the file name?", False, doc=""" Select *"YES"* to add a suffix to the file name. Select *"NO"* to use the file name as-is. """ % globals()) self.file_name_suffix = Text("Text to append to the file name", "", metadata=True, doc=""" "*(Used only when constructing the filename from the image filename)*" Enter the text that should be appended to the filename specified above. """) self.wants_overwrite_without_warning = Binary( "Overwrite without warning?", False, doc="""This setting either prevents or allows overwriting of old .txt files by **ExportToACC** without confirmation. Select "*YES*" to overwrite without warning any .txt file that already exists. Select "*NO*" to prompt before overwriting when running CellProfiler in the GUI and to fail when running headless. """ % globals()) self.nan_representation = Choice("Representation of Nan/Inf", [NANS_AS_NANS, NANS_AS_NULLS], doc=""" This setting controls the output for numeric fields if the calculated value is infinite (*"Inf"*) or undefined (*"NaN*"). CellProfiler will produce Inf or NaN values under certain rare circumstances, for instance when calculating the mean intensity of an object within a masked region of an image. - "*%(NANS_AS_NULLS)s:*" Output these values as empty fields. - "*%(NANS_AS_NANS)s:*" Output them as the strings "NaN", "Inf" or "-Inf". """ % globals()) self.pick_columns = Binary("Select the measurements to export", False, doc=""" Select *"YES"* to provide a button that allows you to select which measurements you want to export. This is useful if you know exactly what measurements you want included in the final spreadheet(s). """ % globals()) self.columns = MeasurementMultiChoice( "Press button to select measurements to export", doc=""" "*(Used only when selecting the columns of measurements to export)*" This setting controls the columns to be exported. Press the button and check the measurements or categories to export.""") self.file_image_name = FileImageSubscriber( "Select image name for file prefix", "None", doc=""" Select an image loaded using **NamesAndTypes**. The original filename will be used as the prefix for the output filename.""" % globals())
def create_settings(self): self.object_name = LabelSubscriber( "Select the input objects", "None", doc="Select the objects that you want to expand or shrink.", ) self.output_object_name = LabelName( "Name the output objects", "ShrunkenNuclei", doc="Enter a name for the resulting objects.", ) self.operation = Choice( "Select the operation", O_ALL, doc="""\ Choose the operation that you want to perform: - *{O_SHRINK_INF}:* Remove all pixels but one from filled objects. Thin objects with holes to loops unless the “fill” option is checked. Objects are never lost using this module (shrinking stops when an object becomes a single pixel). - *{O_EXPAND_INF}:* Expand objects, assigning every pixel in the image to an object. Background pixels are assigned to the nearest object. - *{O_DIVIDE}:* 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). - *{O_SHRINK}:* 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. Objects are never lost using this module (shrinking stops when an object becomes a single pixel). - *{O_EXPAND}:* 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. - *{O_SKELETONIZE}:* Erode each object to its skeleton. - *{O_SPUR}:* 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 *Number of pixels by which to expand or shrink*. """.format( **{ "O_DIVIDE": O_DIVIDE, "O_EXPAND": O_EXPAND, "O_EXPAND_INF": O_EXPAND_INF, "O_SHRINK": O_SHRINK, "O_SHRINK_INF": O_SHRINK_INF, "O_SKELETONIZE": O_SKELETONIZE, "O_SPUR": O_SPUR, }), ) self.iterations = Integer( "Number of pixels by which to expand or shrink", 1, minval=1, doc="""\ *(Used only if "{O_SHRINK}", "{O_EXPAND}", or "{O_SPUR}" is selected)* Specify the number of pixels to add or remove from object borders. """.format(**{ "O_EXPAND": O_EXPAND, "O_SHRINK": O_SHRINK, "O_SPUR": O_SPUR }), ) self.wants_fill_holes = Binary( "Fill holes in objects so that all objects shrink to a single point?", False, doc="""\ *(Used only if one of the “Shrink” options selected)* Select *{YES}* to ensure that each object will shrink to a single point, by filling the holes in each object. Select *{NO}* 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. """.format(**{ "NO": "No", "YES": "Yes" }), )
def create_settings(self): # # The superclass (ImageProcessing) defines two # settings for image input and output: # # - x_name: an ImageNameSubscriber which "subscribes" to all # ImageNameProviders in prior modules. Modules before yours will # put images into CellProfiler. The ImageNameSubscriber gives # your user a list of these images which can then be used as inputs # in your module. # - y_name: an ImageName makes the image available to subsequent # modules. super(ImageTemplate, self).create_settings() # # reST help that gets displayed when the user presses the # help button to the right of the edit box. # # The superclass defines some generic help test. You can add # module-specific help text by modifying the setting's "doc" # string. # self.x_name.doc = """\ This is the image that the module operates on. You can choose any image that is made available by a prior module. **ImageTemplate** will do something to this image. """ # # Here's a choice box - the user gets a drop-down list of what # can be done. # self.gradient_choice = Choice( text="Gradient choice:", # The choice takes a list of possibilities. The first one # is the default - the one the user will typically choose. choices=[ GRADIENT_DIRECTION_X, GRADIENT_DIRECTION_Y, GRADIENT_MAGNITUDE ], # The default value is the first choice in choices. You can # specify a different initial value using the value keyword. value=GRADIENT_MAGNITUDE, # # Here, in the documentation, we do a little trick so that # we use the actual text that's displayed in the documentation. # # {GRADIENT_MAGNITUDE} will get changed into "Gradient magnitude" # etc. Python will look in keyword arguments for format() # for the "GRADIENT_" names and paste them in where it sees # a matching {GRADIENT_...}. # doc="""\ Choose what to calculate: - *{GRADIENT_MAGNITUDE}*: calculate the magnitude of the gradient at each pixel. - *{GRADIENT_DIRECTION_X}*: get the relative contribution of the gradient in the X direction (.5 = no contribution, 0 to .5 = decreasing with increasing X, .5 to 1 = increasing with increasing X). - *{GRADIENT_DIRECTION_Y}*: get the relative contribution of the gradient in the Y direction. """.format( **{ "GRADIENT_MAGNITUDE": GRADIENT_MAGNITUDE, "GRADIENT_DIRECTION_X": GRADIENT_DIRECTION_X, "GRADIENT_DIRECTION_Y": GRADIENT_DIRECTION_Y, }), ) # # A binary setting displays a checkbox. # self.automatic_smoothing = Binary( text="Automatically choose the smoothing scale?", value=True, # The default value is to choose automatically doc= "The module will automatically choose a smoothing scale for you if you leave this checked.", ) # # We do a little smoothing which supplies a scale to the gradient. # # We use a float setting so that the user can give us a number # for the scale. The control will turn red if the user types in # an invalid scale. # self.scale = Float( text="Scale", value=1, # The default value is 1 - a short-range scale minval=0.1, # We don't let the user type in really small values maxval=100, # or large values doc="""\ This is a scaling factor that supplies the sigma for a gaussian that's used to smooth the image. The gradient is calculated on the smoothed image, so large scales will give you long-range gradients and small scales will give you short-range gradients. """, )