def low_signal_threshold(container, _id=0): """ Creates a grain mask by blurring the image and then doing Otsu\'s power scaled threshold. The gaussian filtered image is added to the container. Parameters ---------- container: gwy.container _id: int Key of data in container to process. """ # get sigma from settings, ie. value last used in toolbox->filters sigma = get_gaussian_sigma() # create undo point gwy.gwy_app_undo_checkpoint(container, container.keys_by_name()) # get datafield 0 for each container for func to operate on data = container[gwy.gwy_app_get_data_key_for_id(_id)] # create new blurred data blurred = data.duplicate() # do gaussian filter blurred.filter_gaussian(sigma) # add to container gwy.gwy_app_data_browser_add_data_field(blurred, container, False) # create grain mask grains = threshold_otsu_power(blurred) # add grain field to container and set mask colour container.set_object_by_name(gwy.gwy_app_get_mask_key_for_id(_id), grains) set_mask_colour(container, _id)
def run(): # do thresholding on main (id=0) data _id = 0 # get containers containers = gwy.gwy_app_data_browser_get_containers() # get current image data for container in containers: # get datafield and compute threshold datafield = container.get_object(gwy.gwy_app_get_data_key_for_id(_id)) # create grain mask grains = create_mask(datafield, datafield.otsu_threshold()) # add mask field to container container.set_object(gwy.gwy_app_get_mask_key_for_id(_id), grains) # set mask colour and opacity set_mask_colour(container, _id)
def set_mask_colour(container, _id, rgba=(0.75, 0.0, 0.0, 0.5)): """ Convenience function to set mask colour parameters within container. Parameters ---------- container: gwy.Container _id: int Mask key in container. rgba: tuple of floats, length 4 Values range from 0..1. (Red, Green, Blue, Alpha). """ mask_key = gwy.gwy_app_get_mask_key_for_id(_id) # set mask colour and opacity for color, val in zip(("red", "green", "blue", "alpha"), rgba): container[os.path.join(mask_key, color)] = val
def run(): # get current data and correct container for file _id = gwy.gwy_app_data_browser_get_current(gwy.APP_DATA_FIELD_ID) container = gwy.gwy_app_data_browser_get_current(gwy.APP_CONTAINER) # create undo point gwy.gwy_undo_qcheckpoint(container, container.keys()) # get datafield and compute threshold datafield = container.get_object(gwy.gwy_app_get_data_key_for_id(_id)) threshold = threshold_otsu_median(datafield) # create grain mask grains = create_mask(datafield, threshold) # add mask field to container container.set_object(gwy.gwy_app_get_mask_key_for_id(_id), grains) # set mask colour and opacity set_mask_colour(container, _id)
def analyse_particles_otsu_median(container, datafield_id=0, filter_size=5, save=False): """ Compute grains on an image through histogram clustering, with the median of the class (rather than the mean) as the class descriptor. (Translates closely to the mode of class z-scale histogram). DOI: 10.1016/j.aasri.2012.11.074 Calculates threshold, then puts a mask on the image. Grains are saved as JSON and .gwy files. Parameters ---------- container: gwy.Container Container where data is stored/shown. datafield_id: int The id of the data to analyse within container. Deafault is 0, ie. first data channel. filter_size: int Remove found grains smaller than this, in pixels. Default is 5. save: boolean Whether to save the data as JSON and .gwy. Default is True. Returns ------- grain_datafield: gwy.DataField Binary datafield where grains are foreground. """ # key for putting data in container data_key = os.path.join(os.sep, str(datafield_id), "data") mask_key = os.path.join(os.sep, str(datafield_id), "mask") # get datafield datafield = container.get_object_by_name( gwy.gwy_app_get_data_key_for_id(datafield_id)) # calculate threhshold threshold = threshold_otsu_median(datafield) # --- CREATE MASK BELOW AND ADD TO CONTAINER grain_datafield = datafield.new_alike(True) # get relative threshold rel_threshold = 100.0 * get_relative_value(threshold, datafield) # threshold --> false means mark above threshold datafield.grains_mark_height(grain_datafield, rel_threshold, False) # NB. reordered operations remove_touching_border and area_filter # on date 5.2.2019 # before this date order went border then size # grain_datafield.grains_remove_by_size(filter_size) # added 5.2.2019 # grain_datafield_full = grain_datafield.duplicate() # container.set_object_by_name(os.path.join(os.sep, str(datafield_id), 'mask_including_edges'), \ # grain_datafield_full) # remove grains touching image edegs -> skews data # grain_datafield.grains_remove_touching_border() container.set_object_by_name(gwy.gwy_app_get_mask_key_for_id(datafield_id), grain_datafield) # set mask colour and opacity container[os.path.join(mask_key, "alpha")] = 0.25 container[os.path.join(mask_key, "blue")] = 1.0 if save: save_dict = dict( THRESHOLD=threshold, RELATIVE_THRESHOLD=rel_threshold, GRAIN_DATAFIELD_INCLUDING_EDGES=grain_datafield_full.get_data(), ) save_gwy_grain_mask_to_JSON(container, datafield_id=datafield_id, grain_data_to_save=save_dict) return grain_datafield