Exemple #1
0
def get_center_of_mass(img, thr=127, gmax = 255, ksize=(5,5)):
	
	img = jpg_to_cv2gray(img)
	blur = cv2.GaussianBlur(img, ksize=ksize,sigmaX = 0)
	ret, thresh1 = cv2.threshold(blur, thr, gmax, cv2.THRESH_BINARY)
	edged = cv2.Canny(blur, 10, 250)
	cenofmass = com(edged)
	cenofmass = int(cenofmass[0]), int(cenofmass[1])
	return cenofmass[1], cenofmass[0]
Exemple #2
0
def get_z_crops(x, ix, min_pix=1500, n_comps=2, rad_crit=20000):
    final_slices = []

    for six in range(x.shape[0]):

        tx = np.copy(x[six]) < -600
        img_center = np.array(tx.shape) / 2
        tx = clear_border(tx)

        clusters, n_cands = lb(tx)
        count = np.unique(clusters, return_counts=True)
        keep_comps = np.array([
            ii for ii in np.argwhere((count[1] > min_pix)) if ii > 0
        ]).astype(int)

        if len(keep_comps) > n_comps - 1:
            coms = com(tx, clusters, index=keep_comps)
            keep_com = [
                ix for ix, ii in enumerate(coms[0])
                if ((ii[0] - img_center[0])**2 +
                    (ii[1] - img_center[1])**2 < rad_crit)
            ]
            keep_comps = keep_comps[keep_com]

            if len(keep_comps) > n_comps - 1:
                final_slices.append(six)
                #      print('appending', six)

    z_min = np.min(final_slices) - 7
    z_max = np.max(final_slices) + 7
    dist = z_max - z_min
    if dist >= 151:
        print('trying again with min pix', min_pix + 500, rad_crit - 500, ix,
              dist)
        z_min, z_max = get_z_crops(x,
                                   ix,
                                   min_pix=min_pix + 500,
                                   rad_crit=rad_crit - 500)
    if dist <= 43:
        print('trying again with one component', min_pix - 100, rad_crit + 100,
              ix, dist)
        z_min, z_max = get_z_crops(x,
                                   ix,
                                   n_comps=1,
                                   min_pix=min_pix - 100,
                                   rad_crit=rad_crit + 100)

    print(z_min, z_max, z_max - z_min, ix)
    return z_min, z_max
def mod_region_test(composite, mod_id, algorithm, **kwargs):

  region_test_path = os.path.join(composite.experiment.video_path, 'regions', composite.series.name)
  if not os.path.exists(region_test_path):
    os.makedirs(region_test_path)

  for t in range(composite.series.ts):
    zbf = composite.gons.get(t=t, channel__name='-zbf').load()
    region_mask = composite.masks.get(t=t, channel__name__contains=kwargs['channel_unique_override']).load()

    mask_edges = mask_edge_image(region_mask)

    zbf_mask_r = zbf.copy()
    zbf_mask_g = zbf.copy()
    zbf_mask_b = zbf.copy()

    # edges
    zbf_mask_r[mask_edges>0] = 100
    zbf_mask_g[mask_edges>0] = 100
    zbf_mask_b[mask_edges>0] = 100

    # region labels
    # prepare drawing
    blank_slate = np.zeros(zbf.shape)
    blank_slate_img = Image.fromarray(blank_slate)
    draw = ImageDraw.Draw(blank_slate_img)
    for unique in [u for u in np.unique(region_mask) if u>0]:
      if composite.series.region_instances.filter(region_track_instance__t=t, mode_gray_value_id=unique).count()>0:
        region = composite.series.region_instances.get(region_track_instance__t=t, mode_gray_value_id=unique).region

        # get coords (isolate mask, cut to black, use r/c)
        isolated_mask = region_mask==unique
        cut, (r0,c0,rs,cs) = cut_to_black(isolated_mask)
        com_r, com_c = com(isolated_mask)

        draw.text((com_c+30, com_r+30), '{}'.format(region.name), font=ImageFont.load_default(), fill='rgb(0,0,255)')

    blank_slate = np.array(blank_slate_img)
    zbf_mask_r[blank_slate>0] = 0
    zbf_mask_g[blank_slate>0] = 0
    zbf_mask_b[blank_slate>0] = 255

    whole = np.dstack([zbf_mask_r, zbf_mask_g, zbf_mask_b])

    imsave(join(region_test_path, 'regions_{}_s{}_t{}.tiff'.format(composite.experiment.name, composite.series.name, str_value(t, composite.series.ts))), whole)
def com_calc(img, max_size, min_size, lung_img):
    '''
    Calculate the center of mass of each of the labeled regions in img,
    excluding regions that are outside the lung given in lung_img, or the
    range size [min_size, max_size], which are reported treated as fractions of
    the input lung.
    '''
    from scipy.ndimage.measurements import center_of_mass as com
    # pylint: disable=E1101

    arr = sitk.GetArrayFromImage(img)
    lung_arr = sitk.GetArrayFromImage(lung_img)

    # Take elements from arr only when lung_arr is not zero, i.e. take only
    # regions in the lung.
    arr = np.where(lung_arr != 0, arr,
                   np.zeros(arr.shape,
                            dtype=arr.dtype))

    counts = np.bincount(np.ravel(arr))

    # volume per voxel is encoded in img spacing, with units mm^3
    vox_vol = reduce(lambda x, y: x * y, img.GetSpacing())

    # the size of the lung is the size of a voxel times the number of voxels
    lung_size = np.count_nonzero(lung_arr)*vox_vol

    # print sorted(counts)[-10:], sorted([c for c in counts if c != 0])[0:10]
    # print np.count_nonzero(lung_arr)*vox_vol

    logging.debug("Availiable labels and sizes: %s",
                  [p for p in enumerate(counts) if p[1] > 0])

    # We gate the deterministic seeds for their regions being of a reasonable
    # size.
    labels = [label for (label, n_vox) in enumerate(counts)
              if min_size*lung_size < n_vox*vox_vol < max_size*lung_size]

    # we don't want to calculate the COM of the background, no matter what
    # our min/max sizes are
    try:
        labels.remove(0)
    except ValueError:
        #Zero wasn't in the list
        pass

    # compute the center of mass for each of the elements up to 100 elements
    com_list = com(np.where(arr != 0, np.ones(arr.shape), np.zeros(arr.shape)),
                   labels=arr, index=labels)

    logging.debug("Label-COM correspondence: %s", dict(zip(labels, com_list)))

    # these are array-indexed and we take our seeds to be image-indexed
    # plus, they're floats and need to be cast back to integers
    seeds = [[int(k) for k in reversed(s)] for s in com_list
             if lung_arr[s] == 1]

    info = {'nseeds': len(seeds),
            'max_size': max_size,
            'min_size': min_size,
            'seeds': [s for s in seeds]}  # deep (enough) copy

    logging.info("%s in-lung of %s seeds from %s watershed labels",
                 len(seeds), len(labels), len(counts))

    return (seeds, info)
Exemple #5
0
from util import *

img, id = get_img(ret_id=True, denoise=False)
img = threshold(img, int(1.2*np.mean(img)), ttype=tz)

centroids = load_all_centroids(id)
centrs = arr([[c[1], c[0]] for c in centroids])
print '%d centroids' % len(centrs)

from skimage.morphology import label
comps = label(img > int(1.0*np.mean(img)))
#comps = label(img)
print '%d components' % (len(np.unique(comps))-1)

from scipy.ndimage.measurements import center_of_mass as com
comp_centrs = arr(list(map(
    lambda c: [c[1], c[0]],
    [com(img * (comps==i)) 
        for i in range(1, len(np.unique(comps))-1)])))

_, ax = plt.subplots(1, 2)
gray_imshow(ax[0], img)
ax[0].scatter(centrs[:,0], centrs[:,1], s=10, c='r')

#gray_imshow(ax[1], comps, cmap='jet')
gray_imshow(ax[1], img)
ax[1].scatter(comp_centrs[:,0], comp_centrs[:,1], s=10, c='b')

#gray_imshow(ax[2], comps, cmap='jet')
plt.show()
        r"^(?P<experiment>.+)_s(?P<series>.+)_ch(?P<channel>.+)_t(?P<t>[0-9]+)_z(?P<z>[0-9]+)\.(?P<extension>.+)$", n
    ).group("z")
)
load = lambda p, n: exposure.rescale_intensity(imread(join(p, n)) * 1.0)

bf = {z(name): {"img": load(bf_path, name), "name": name} for name in os.listdir(bf_path) if ".DS" not in name}
zmod = load(t_path, "050714_s13_ch-zmod_t30_z0.tiff")
zmean = load(t_path, "050714_s13_ch-zmean_t30_z0.tiff")
zbf = load(t_path, "050714_s13_ch-zbf_t30_z0.tiff")
marker = load(t_path, "primary_t30.tif")

# vars
r0, r1 = 360, 475  # bounding box
c0, c1 = 230, 305

_C = com(marker != 0)  # marker location
marker_r, marker_c = int(_C[0]), int(_C[1])
cut = lambda img: img[r0:r1, c0:c1]
cut_r, cut_c = marker_r - r0, marker_c - c0

# generate zcomp
zcomp = zbf * zmean


def binary_edge(binary):
    return binary - erode(binary)


def edges_touching(binary_inside, binary_outside):
    # 1. get edge of outside
    binary_outside_edge = binary_edge(binary_outside).astype(int)
Exemple #7
0
c_mask3 = path3.contains_points(points)
c_mask3 = np.rot90(np.flip(c_mask3.reshape((y_dim, x_dim)), 1))

c_mask4 = path4.contains_points(points)
c_mask4 = np.rot90(np.flip(c_mask4.reshape((y_dim, x_dim)), 1))

#################################################
#################################################
#################################################

weight1 = np.flip(c_mask1 * imghmi, 0)
weight2 = np.flip(c_mask2 * imghmi, 0)
weight3 = np.flip(c_mask3 * imghmi, 0)
weight4 = np.flip(c_mask4 * imghmi, 0)

cm1 = np.array(com(weight1)).astype(int)
cm2 = np.array(com(weight2)).astype(int)
cm3 = np.array(com(weight3)).astype(int)
cm4 = np.array(com(weight4)).astype(int)

combined = weight1 + weight2 + weight3 + weight4

plt.imshow(combined, cmap="gray", vmin=-120, vmax=120)
plt.autoscale(False)
plt.plot(cm1[1], cm1[0], 'g+')
plt.plot(cm2[1], cm2[0], 'g+')
plt.plot(cm3[1], cm3[0], 'g+')
plt.plot(cm4[1], cm4[0], 'g+')
plt.savefig('resulthmi3.png', bbox_inches='tight', dpi=300)

debug()
    def report(self,
               volume=None,
               threshold=None,
               out_file='ClusterReport.csv'):
        # To take care if user has given a 4D contrast
        if volume != None:
            self.volume = volume

        if len(self.brain.shape) > 3:
            brain = np.array(self.brain[:, :, :, self.volume])
        else:
            brain = np.array(self.brain)

        if threshold != None:
            self.thresh = threshold

        # Total number of brain voxels
        num_brain_voxels = len(np.where(brain != 0)[0])
        """
        Brain_zero is used later to calculate the center of gravity of the
        cluster voxels overlapping with atlas voxels
        """

        brain_zero = np.zeros(brain.shape)

        # Apply thresholding
        brain[(brain < self.thresh) & (brain > -self.thresh)] = 0

        # Find clusters
        clusters, num_clusters = lb(brain)

        df_report = pd.DataFrame()

        # List to store cluster size information
        full_cluster_voxels_percentage_list = []

        atlas_path = self.atlas_dict['atlas_path']
        atlas_labels_path = self.atlas_dict['atlas_labels_path']
        atlas_xml_zero_start_index = \
                           self.atlas_dict['atlas_xml_zero_start_index']

        atlas_obj = au.queryAtlas(
            atlas_path,
            atlas_labels_path,
            atlas_xml_zero_start_index=atlas_xml_zero_start_index)

        for cluster_number in range(1, num_clusters + 1):
            # Coordinates that are present in cluster given by cluster_number
            cluster_indices = np.where(clusters == cluster_number)

            # Number of voxels belonging to the cluster -> cluster_number
            num_cluster_voxels = len(cluster_indices[0])

            # Percentage of total brain voxels in a cluster
            full_cluster_voxels_percentage = \
                                    num_cluster_voxels * 100 / num_brain_voxels

            # To create a list to be added to dataframe
            full_cluster_voxels_percentage_list.append(
                full_cluster_voxels_percentage)

            # Find the atlas labels/regions that the cluster spans
            atlas_regions_labels = np.unique(self.atlas[cluster_indices])
            # print(atlas_regions_labels)

            # iterate over all the labes/regions
            for label in atlas_regions_labels:
                # Lists to be used for dataFrame creation
                cog_value_list = []
                number_overlapping_cluster_voxels_list = []
                overlapping_cluster_voxels_percentage_list = []
                MNI_cog_list = []
                cog_region_name_list = []

                cog_unweighted_value_list = []
                cog_weighted_value_list = []
                cog_weighted_value_list = []
                MNI_cog_unweighted_list = []
                MNI_cog_weighted_list = []
                cog_region_name_weighted_list = []
                cog_region_name_unweighted_list = []

                # Find all the coordinates of the labels

                # Skipping the Label 0
                if label == 0:
                    continue

                atlas_label_indices = np.where(self.atlas == label)
                """ Find the cluster coordinates overlapping the label/region
                under consideration """

                # Changing the form of cluster indices to (x,y,z) tuple

                cluster_indices_zip = zip(cluster_indices[0],
                                          cluster_indices[1],
                                          cluster_indices[2])

                cluster_indices_tuple_list = list(cluster_indices_zip)

                # Changing the form of atlas indices to (x,y,z) tuple

                atlas_label_indices_zip = \
                zip(atlas_label_indices[0], atlas_label_indices[1],
                                            atlas_label_indices[2])

                atlas_label_indices_tuple_list = list(atlas_label_indices_zip)

                # Number of voxels belonging to the atlas region
                num_atlas_region_voxels = len(atlas_label_indices_tuple_list)

                # 1. Find intersecion of the above two lists
                overlapping_coordinates = \
                list(set(cluster_indices_tuple_list).intersection(
                                           set(atlas_label_indices_tuple_list)))
                """
                2. Make an brain array and initialize the overlapping
                coordinates with the values from brain

                # Transform coordinates list to list of indices as
                returned by np.where()
                # Ref: https://stackoverflow.com/questions/12974474/
                how-to-unzip-a-list-of-tuples-into-individual-lists

                """
                overlapping_indices_zip = zip(*overlapping_coordinates)

                overlapping_indices_tuple_list = list(overlapping_indices_zip)

                # Number of voxels in the overlap of cluster and atlas region
                number_overlapping_cluster_voxels = \
                                            len(overlapping_coordinates)

                # Creating list to be added to dataframe
                number_overlapping_cluster_voxels_list.append(
                    number_overlapping_cluster_voxels)

                #Percentage of voxels in the overlap of cluster and atlas region
                overlapping_cluster_voxels_percentage = \
                number_overlapping_cluster_voxels*100 / num_atlas_region_voxels

                # Creating list to be added to dataframe
                overlapping_cluster_voxels_percentage_list.append(
                    overlapping_cluster_voxels_percentage)

                # Assigning the overlap to the empty brain to find COG later
                brain_zero[overlapping_indices_tuple_list] = \
                                           brain[overlapping_indices_tuple_list]
                """
                3. Then use the already created functions to do the following:
                    a. Find the representative coordinate of the intersection

                Create a dummy atlas (roi_mask) with just one region and label
                that as 1

                Ref: https://stackoverflow.com/questions/32322281/
                numpy-matrix-binarization-using-only-one-expression
                """

                roi_mask_for_unweighted_cog = np.where(brain_zero != 0, 1, 0)
                roi_mask_for_weighted_cog = brain_zero

                cog_unweighted = com(roi_mask_for_unweighted_cog)
                cog_weighted = com(roi_mask_for_weighted_cog)

                # convert the coordinates to int (math.floor)
                cog_unweighted = tuple(map(int, cog_unweighted))
                cog_weighted = tuple(map(int, cog_weighted))
                """
                If the COG lies outside the overlapping coordinates then find
                the coordinate that lies on the overlapping region and is
                closest to the COG.
                """

                if not roi_mask_for_unweighted_cog[cog_unweighted]:
                    cog_unweighted = \
                              tuple(self.getNearestVoxel(roi_mask_for_unweighted_cog,
                                                   cog_unweighted))

                if not roi_mask_for_weighted_cog[cog_weighted]:
                    cog_weighted= \
                              tuple(self.getNearestVoxel(roi_mask_for_weighted_cog,
                                                   cog_weighted))

                # print('COM Unweighted', cog_unweighted)
                # print('COM Weighted', cog_weighted)

                # Finding the values at the cluster representative coordinates
                cog_unweighted_value = brain[cog_unweighted]
                cog_weighted_value = brain[cog_weighted]

                # Lists to be added to dataframe
                cog_unweighted_value_list.append(cog_unweighted_value)
                cog_weighted_value_list.append(cog_weighted_value)

                # b. Convert the cartesian coordinates to MNI
                MNI_cog_unweighted = self._XYZ2MNI(cog_unweighted)
                MNI_cog_weighted = self._XYZ2MNI(cog_weighted)

                # Convert the list of coordinates to string to get rid of:
                # Exception: Data must be 1-dimensional

                str_cog_unweighted = ''
                for i in MNI_cog_unweighted:
                    str_cog_unweighted = str_cog_unweighted + ' ' + str(i)

                str_cog_weighted = ''
                for i in MNI_cog_weighted:
                    str_cog_weighted = str_cog_weighted + ' ' + str(i)

                # Lists to be added to dataframe
                MNI_cog_unweighted_list.append(str_cog_unweighted)
                MNI_cog_weighted_list.append(str_cog_weighted)

                # c. Report the name of the region

                # Names of the regions of COG
                cog_region_name_weighted = \
                              atlas_obj.getAtlasRegions(MNI_cog_weighted)[1]
                cog_region_name_unweighted = \
                            atlas_obj.getAtlasRegions(MNI_cog_unweighted)[1]

                # print('Region name weighted COG: ',cog_region_name_weighted)
                #
                # print('Region name unweighter COG: ',cog_region_name_unweighted)

                # List created to be added to dataframe
                cog_region_name_weighted_list.append(cog_region_name_weighted)
                cog_region_name_unweighted_list.append(
                    cog_region_name_unweighted)

                #  To choose from weighted and unweighted COG options
                WEIGHTED = True

                if WEIGHTED:
                    MNI_cog_list = MNI_cog_weighted_list
                    cog_region_name_list = cog_region_name_weighted_list
                    cog_value_list = cog_weighted_value_list
                else:
                    pass

                # Sort the Regions bsed on cog value

                # Get the indices of elements after they are sorted
                sorted_indices = np.argsort(cog_value_list)

                #  Sort the lists according to the above sorted_indices
                cog_value_list = np.array(cog_value_list)[sorted_indices]
                number_overlapping_cluster_voxels_list = \
                np.array(number_overlapping_cluster_voxels_list)[sorted_indices]

                overlapping_cluster_voxels_percentage_list = \
                np.array(overlapping_cluster_voxels_percentage_list)[sorted_indices]

                MNI_cog_list = np.array(MNI_cog_list)[sorted_indices]
                cog_region_name_list = np.array(
                    cog_region_name_list)[sorted_indices]
                """
                TODO:
                Convert MNI coordinates from list to string (x,y,z)
                The next error that I will have to deal with is unequal length
                arrays. For that append each list with spaces.
                Then care about ordering the dictionary.
                """
                # Creating a dictionary to create dataframe
                df_dict = OrderedDict()

                df_dict['Cluster Number'] = [cluster_number]
                df_dict['Max Value'] = cog_value_list
                df_dict['Num Voxels'] = number_overlapping_cluster_voxels_list
                df_dict['Percentage of Voxel' ] = \
                                     overlapping_cluster_voxels_percentage_list
                df_dict['MNI Coordinates'] = MNI_cog_list
                df_dict['Region Name'] = cog_region_name_list

                df = pd.DataFrame(df_dict)

                df_report = df_report.append(df)

                # Empty the lists to be filled again
                cog_value_list = []
                number_overlapping_cluster_voxels_list = []
                overlapping_cluster_voxels_percentage_list = []
                MNI_cog_list = []
                cog_region_name_list = []
                """
                TODO:
                The order of the columns is not maintained
                Test again about the validity of results. The number of voxels
                is very low. Check it!

                DONE:
                Store each of the coordinates in cog_list, names in
                name_list, values in value_list, number of voxels etc.
                Find the max of the value_list and corresponding name in
                name_list and also calculate other details and store them in
                lists.

                Create a distionary with all the above created lists.

                Create a empty data frame and add the above created dictionary
                in it.

                ATLAS NAME
                SIZE (MM)

                In one For loop create the details about cluster1 and store them
                in lists as said above. As said above, add these lists in a
                dictionary.
                Then this dictionary is added to a dataframe.

                The table should look like the following:

                ROI1 Cluster1 MaxValue COG Region Total_#_voxels %_voxels
                              MaxValue COG Region #_voxels %_voxles_overlap
                              Value2   COG Region #_voxels %_voxles_overlap
                              Value3   COG Region #_voxels %_voxles_overlap
                              .        .
                              .        .
                              .        .
                     Cluster2 MaxValue COG Region Total_#_voxels
                               MaxValue COG Region #_voxels %_voxles_overlap
                               Value2   COG Region #_voxels %_voxles_overlap
                               Value3   COG Region #_voxels %_voxles_overlap
                               .        .
                               .        .
                               .        .

                """

                pass

                brain_zero.fill(0)

                # d. Number and Percentage of voxels overlapping the region
                # e. Peak coordinate of the cluster
        df_report.to_csv(out_file, index=False)
        return os.path.abspath(out_file), df_report
def com_calc(img, max_size, min_size, lung_img):
    '''
    Calculate the center of mass of each of the labeled regions in img,
    excluding regions that are outside the lung given in lung_img, or the
    range size [min_size, max_size], which are reported treated as fractions of
    the input lung.
    '''
    from scipy.ndimage.measurements import center_of_mass as com
    # pylint: disable=E1101

    arr = sitk.GetArrayFromImage(img)
    lung_arr = sitk.GetArrayFromImage(lung_img)

    # Take elements from arr only when lung_arr is not zero, i.e. take only
    # regions in the lung.
    arr = np.where(lung_arr != 0, arr, np.zeros(arr.shape, dtype=arr.dtype))

    counts = np.bincount(np.ravel(arr))

    # volume per voxel is encoded in img spacing, with units mm^3
    vox_vol = reduce(lambda x, y: x * y, img.GetSpacing())

    # the size of the lung is the size of a voxel times the number of voxels
    lung_size = np.count_nonzero(lung_arr) * vox_vol

    # print sorted(counts)[-10:], sorted([c for c in counts if c != 0])[0:10]
    # print np.count_nonzero(lung_arr)*vox_vol

    logging.debug("Availiable labels and sizes: %s",
                  [p for p in enumerate(counts) if p[1] > 0])

    # We gate the deterministic seeds for their regions being of a reasonable
    # size.
    labels = [
        label for (label, n_vox) in enumerate(counts)
        if min_size * lung_size < n_vox * vox_vol < max_size * lung_size
    ]

    # we don't want to calculate the COM of the background, no matter what
    # our min/max sizes are
    try:
        labels.remove(0)
    except ValueError:
        #Zero wasn't in the list
        pass

    # compute the center of mass for each of the elements up to 100 elements
    com_list = com(np.where(arr != 0, np.ones(arr.shape), np.zeros(arr.shape)),
                   labels=arr,
                   index=labels)

    logging.debug("Label-COM correspondence: %s", dict(zip(labels, com_list)))

    # these are array-indexed and we take our seeds to be image-indexed
    # plus, they're floats and need to be cast back to integers
    seeds = [[int(k) for k in reversed(s)] for s in com_list
             if lung_arr[s] == 1]

    info = {
        'nseeds': len(seeds),
        'max_size': max_size,
        'min_size': min_size,
        'seeds': [s for s in seeds]
    }  # deep (enough) copy

    logging.info("%s in-lung of %s seeds from %s watershed labels", len(seeds),
                 len(labels), len(counts))

    return (seeds, info)
def Workflow_npm1_comb(struct_img,
                       mitotic_stage,
                       rescale_ratio,
                       output_type,
                       output_path,
                       fn,
                       output_func=None):
    ##########################################################################
    # PARAMETERS:
    #   note that these parameters are supposed to be fixed for the structure
    #   and work well accross different datasets

    intensity_norm_param = [20, 25]
    gaussian_smoothing_sigma = 0.25
    gaussian_smoothing_truncate_range = 4.0
    dot_2d_sigma = 1
    dot_2d_sigma_extra = 3
    dot_2d_cutoff = 0.035
    dot_2d_cutoff_extra = 0.01
    minArea = 2
    low_level_min_size = 700
    ##########################################################################

    out_img_list = []
    out_name_list = []

    ###################
    # PRE_PROCESSING
    ###################
    # intenisty normalization (min/max)
    struct_img = np.reciprocal(struct_img)  # inverting to detect dark spot
    struct_img = intensity_normalization(struct_img,
                                         scaling_param=intensity_norm_param)

    out_img_list.append(struct_img.copy())
    out_name_list.append('im_norm')

    # rescale if needed
    # if rescale_ratio>0:
    #     struct_img = resize(struct_img, [1, rescale_ratio, rescale_ratio], method="cubic")
    #     struct_img = (struct_img - struct_img.min() + 1e-8)/(struct_img.max() - struct_img.min() + 1e-8)
    #     gaussian_smoothing_truncate_range = gaussian_smoothing_truncate_range * rescale_ratio

    # smoothing with gaussian filter
    structure_img_smooth = image_smoothing_gaussian_3d(
        struct_img,
        sigma=gaussian_smoothing_sigma,
        truncate_range=gaussian_smoothing_truncate_range)

    out_img_list.append(structure_img_smooth.copy())
    out_name_list.append('im_smooth')

    ###################
    # core algorithm
    ###################

    # step 1: low level thresholding
    # global_median_1 = np.percentile(structure_img_smooth,35)
    global_median_2 = np.percentile(structure_img_smooth,
                                    30)  # 70 for M6M7, 30 for rest

    # th_low_level_1 = global_median_1
    th_low_level_2 = global_median_2
    # bw_low_level = (structure_img_smooth > th_low_level_1) + (structure_img_smooth > th_low_level_2)
    bw_low_level = structure_img_smooth > th_low_level_2
    bw_low_level = remove_small_objects(bw_low_level,
                                        min_size=low_level_min_size,
                                        connectivity=1,
                                        in_place=True)
    seg = dilation(bw_low_level, selem=ball(2))

    seg = np.invert(seg)
    seg = seg.astype(np.uint8)
    seg[seg > 0] = 255

    ####################
    # POST-Processing using other segmentations structures
    ####################

    other_segs_path = "/allen/aics/assay-dev/computational/data/dna_cell_seg_on_production_data/NPM1/new_dna_mem_segmentation/"
    mem_segs_path = other_segs_path + fn + "_mem_segmentation.tiff"
    dna_segs_path = other_segs_path + fn + "_dna_segmentation.tiff"

    if not os.path.exists(mem_segs_path):
        mem_segs_path = other_segs_path + fn + ".ome_mem_segmentation.tiff"
        dna_segs_path = other_segs_path + fn + ".ome_dna_segmentation.tiff"

    mito_seed_path_root = "/allen/aics/assay-dev/computational/data/NPM1_segmentation_improvement/images_with_mitosis/M67/mito_seg/"
    mito_seed_path = mito_seed_path_root + fn + ".tiff"

    # Generate seed for mitotic cell
    if not os.path.exists(mito_seed_path):
        mito_seed_path = mito_seed_path_root + fn + ".ome.tiff"
    mito_seed_3d = imread(mito_seed_path)

    mito_seed_img = np.amax(mito_seed_3d, axis=0)
    mito_seed = com(mito_seed_img)

    # label the segmentations
    # mem_label, num_feat_mem = labeling(imread(mem_segs_path)) # not labeling correctly
    dna_label, num_feat_dna = labeling(imread(dna_segs_path))

    # label
    # label_mito = mem_label[int(np.floor(mem_label.shape[0]/2)),int(mito_seed[0]),int(mito_seed[1])]

    # seg = seg * ((mem_label == label_mito)*1)
    seg[mito_seed_3d == 0] = 0
    seg[dna_label > 0] = 0

    out_img_list.append(seg.copy())
    out_name_list.append('bw_fine')

    fn += "_combined"

    if output_type == 'default':
        # the default final output
        save_segmentation(seg, False, output_path, fn)
    elif output_type == 'AICS_pipeline':
        # pre-defined output function for pipeline data
        save_segmentation(seg, True, output_path, fn)
    elif output_type == 'customize':
        # the hook for passing in a customized output function
        output_fun(out_img_list, out_name_list, output_path, fn)
    else:
        # the hook for pre-defined RnD output functions (AICS internal)
        img_list, name_list = NPM1_output(out_img_list, out_name_list,
                                          output_type, output_path, fn)
        if output_type == 'QCB':
            return img_list, name_list
	def get_com(self):
		datmax = self.datas.max()
		mask = (self.datas > datmax * 0.25)
		self.center = com(self.datas.T, mask.T)
Exemple #12
0
from scipy.ndimage.measurements import center_of_mass as com
from PIL import Image
import numpy as np
from math import *
from matplotlib.pyplot import imsave
import glob


paths = glob.glob('*/')
print(paths)

for path in paths:
    for filename in glob.glob(path + '*.jpg'):

        img = Image.open(filename)
        img_array = np.array(img)

        x_cen, y_cen, z = com(img_array)
        dx_cen = floor(64 - x_cen)
        dy_cen = floor(64 - y_cen)

        img_out = np.roll(img_array, dx_cen, axis=0)
        img_out = np.roll(img_out, dy_cen, axis=1)

        imsave(filename,img_out,format='jpeg',cmap='gray')
    print(path)

Exemple #13
0
	#*************************************#

	RECORDER.sys_text("Generating AIA304 binary mask [r-mask]")

	LOW_BRIGHTNESS_THRESHOLD = 400
	r_mask = np.logical_and(img304 > LOW_BRIGHTNESS_THRESHOLD, img304 < np.inf)
	r_mask = r_mask.astype(np.uint8)
	r_mask = cv.dilate(r_mask, np.ones((3,3)).astype(bool).astype(int), iterations = 1)

	img304 *= r_mask

	#*************************************#

	RECORDER.sys_text("Generating AIA304 elliptical mask [e-mask]")

	center = com(r_mask)
	x_center = int(center[0] + 0.5)
	y_center = int(center[1] + 0.5)
	dim = img304.shape[0]
	threshold_percent_1 = 0.98
	threshold_percent_2 = 0.96
	threshold_percent_3 = 0.94

	total = float(len(np.where(r_mask == 1)[0]))
	rad = 2.0
	y, x = np.ogrid[-x_center:dim - x_center, -y_center:dim - y_center]
	e_mask = None
	mask_out = None

	while True:
		temp_in = x**2 + y**2 <= rad**2
Exemple #14
0
def mod_step13_cell_masks(composite, mod_id, algorithm):
  # paths
  template = composite.templates.get(name='mask') # MASK TEMPLATE

  # create batches
  batch = 0
  max_batch_size = 100

  # channel
  cell_mask_channel, cell_mask_channel_created = composite.channels.get_or_create(name='cellmask')

  # mean
  # mask_mean_max = np.max([mask.mean for mask in composite.masks.all()])

  # iterate over frames
  for t in range(composite.series.ts):
    print('step13 | processing mod_step13_cell_masks t{}...                                         '.format(t), end='\r')

    # one mask for each marker
    markers = composite.series.markers.filter(t=t)

    # 1. get masks
    mask_gon_set = composite.gons.filter(channel__name__in=['pmodreduced','bfreduced'], t=t)
    bulk = create_bulk_from_image_set(mask_gon_set)

    for m, marker in enumerate(markers):
      print('step13 | processing mod_step13_cell_masks t{}, marker {}/{}...                                         '.format(t, m, len(markers)), end='\r')
      if composite.gons.filter(marker=marker).count()==0:
        # marker parameters
        r, c, z = marker.r, marker.c, marker.z
        other_marker_positions = [(m.r,m.c) for m in markers.exclude(pk=marker.pk)]

        # get primary mask
        primary_mask = np.zeros(composite.series.shape(), dtype=float) # blank image

        mask_uids = [(i, uid) for i,uid in enumerate(bulk.gon_stack[r,c,:]) if uid>0]
        for i,uid in mask_uids:
          gon_pk = bulk.rv[i]
          mask = composite.masks.get(gon__pk=gon_pk, mask_id=uid)
          mask_array = (bulk.slice(pk=mask.gon.pk)==mask.mask_id).astype(float)

          # modify mask array based on parameters
          mask_z, mask_max_z, mask_mean, mask_std = mask.z, mask.max_z, mask.mean, mask.std

          z_term = 1.0 / (1.0 + 0.1*np.abs(z - mask_z)) # suppress z levels at increasing distances from marker
          max_z_term = 1.0 / (1.0 + 0.1*np.abs(z - mask_max_z)) # suppress z levels at increasing distances from marker
          # mean_term = mask_mean / mask_mean_max # raise mask according to mean
          std_term = 1.0

          mask_array = mask_array * z_term * max_z_term * std_term

          # add to primary mask
          primary_mask += mask_array

        # get secondary mask - get unique masks that touch the edge of the primary mask
        secondary_mask = np.zeros(composite.series.shape(), dtype=float) # blank image

        secondary_mask_uids = []
        edges = np.where(edge_image(primary_mask>0))
        for r, c in zip(*edges):
          for i,uid in enumerate(bulk.gon_stack[r,c,:]):
            if (i,uid) not in secondary_mask_uids and (i,uid) not in mask_uids and uid>0:
              secondary_mask_uids.append((i,uid))

        for i,uid in secondary_mask_uids:
          print('step13 | processing mod_step13_cell_masks t{}, marker {}/{}, secondary {}/{}...                                         '.format(t, m, len(markers), i, len(secondary_mask_uids)), end='\r')
          gon_pk = bulk.rv[i]
          mask = composite.masks.get(gon__pk=gon_pk, mask_id=uid)
          mask_array = (bulk.slice(pk=mask.gon.pk)==mask.mask_id).astype(float)

          # modify mask array based on parameters
          mask_z, mask_max_z, mask_mean, mask_std = mask.z, mask.max_z, mask.mean, mask.std

          z_term = 1.0 / (1.0 + 0.1*np.abs(z - mask_z)) # suppress z levels at increasing distances from marker
          max_z_term = 1.0 / (1.0 + 0.1*np.abs(z - mask_max_z)) # suppress z levels at increasing distances from marker
          # mean_term = mask_mean / mask_mean_max # raise mask according to mean
          std_term = 1.0

          foreign_marker_condition = 1.0 # if the mask contains a different marker
          foreign_marker_match = False
          foreign_marker_counter = 0
          while not foreign_marker_match and foreign_marker_counter!=len(other_marker_positions)-1:
            r, c = other_marker_positions[foreign_marker_counter]
            foreign_marker_match = (mask_array>0)[r,c]
            if foreign_marker_match:
              foreign_marker_condition = 0.0
            foreign_marker_counter += 1

          mask_array = mask_array * z_term * max_z_term * std_term * foreign_marker_condition

          # add to primary mask
          secondary_mask += mask_array

        print('step13 | processing mod_step13_cell_masks t{}, marker {}/{}, saving square mask...                                         '.format(t, m, len(markers)), end='\n' if t==composite.series.ts-1 else '\r')
        cell_mask = primary_mask + secondary_mask

        # finally, mean threshold mask
        cell_mask[cell_mask<nonzero_mean(cell_mask)] = 0
        cell_mask[cell_mask<nonzero_mean(cell_mask)] = 0

        # cut to size
        # I want every mask to be exactly the same size -> 128 pixels wide
        # I want the centre of the mask to be in the centre of image
        # Add black space around even past the borders of larger image
        # 1. determine centre of mass
        com_r, com_c = com(cell_mask>0)
        mask_square = np.zeros((256,256), dtype=float)

        if not np.isnan(com_r):
          # 2. cut to black and preserve boundaries
          cut, (cr, cc, crs, ccs) = cut_to_black(cell_mask)

          # 3. place cut inside square image using the centre of mass and the cut boundaries to hit the centre
          dr, dc = int(128 + cr - com_r), int(128 + cc - com_c)

          # 4. preserve coordinates of square to position gon
          small_r, small_c = mask_square[dr:dr+crs,dc:dc+ccs].shape
          mask_square[dr:dr+crs,dc:dc+ccs] = cut[:small_r,:small_c]

        # check batch and make folders, set url
        if not os.path.exists(os.path.join(composite.experiment.cp2_path, composite.series.name, str(batch))):
          os.makedirs(os.path.join(composite.experiment.cp2_path, composite.series.name, str(batch)))

        if len(os.listdir(os.path.join(composite.experiment.cp2_path, composite.series.name, str(batch))))>=max_batch_size:
          batch += 1
          if not os.path.exists(os.path.join(composite.experiment.cp2_path, composite.series.name, str(batch))):
            os.makedirs(os.path.join(composite.experiment.cp2_path, composite.series.name, str(batch)))

        root = os.path.join(composite.experiment.cp2_path, composite.series.name, str(batch)) # CP PATH

        # cell mask gon
        cell_mask_gon = composite.gons.create(experiment=composite.experiment, series=composite.series, channel=cell_mask_channel, template=template)
        cell_mask_gon.set_origin(cr-dr, cc-dc, z, t)
        cell_mask_gon.set_extent(crs, ccs, 1)

        id_token = generate_id_token('img','Gon')
        cell_mask_gon.id_token = id_token

        file_name = template.rv.format(id_token)
        url = os.path.join(root, file_name)

        imsave(url, mask_square.copy())
        cell_mask_gon.paths.create(composite=composite, channel=cell_mask_channel, template=template, url=url, file_name=file_name, t=t, z=z)

        # associate with marker
        marker.gon = cell_mask_gon
        cell_mask_gon.marker = marker
        marker.save()

        cell_mask_gon.save()