def rag_solidity(labels, connectivity=2):

    graph = RAG()

    # The footprint is constructed in such a way that the first
    # element in the array being passed to _add_edge_filter is
    # the central value.
    fp = ndi.generate_binary_structure(labels.ndim, connectivity)
    for d in range(fp.ndim):
        fp = fp.swapaxes(0, d)
        fp[0, ...] = 0
        fp = fp.swapaxes(0, d)

    # For example
    # if labels.ndim = 2 and connectivity = 1
    # fp = [[0,0,0],
    #       [0,1,1],
    #       [0,1,0]]
    #
    # if labels.ndim = 2 and connectivity = 2
    # fp = [[0,0,0],
    #       [0,1,1],
    #       [0,1,1]]

    ndi.generic_filter(labels,
                       function=_add_edge_filter,
                       footprint=fp,
                       mode='nearest',
                       output=np.zeros(labels.shape, dtype=np.uint8),
                       extra_arguments=(graph, ))

    # remove bg_label
    # graph.remove_node(-1)
    graph.remove_node(0)

    for n in graph:
        mask = (labels == n)
        solidity = 1. * mask.sum() / convex_hull_image(mask).sum()
        graph.node[n].update({
            'labels': [n],
            'solidity': solidity,
            'mask': mask
        })

    if LooseVersion(networkx.__version__) >= '2':
        edges_iter = graph.edges(data=True)
    else:
        edges_iter = graph.edges_iter(data=True)
    for x, y, d in edges_iter:
        new_mask = np.logical_or(graph.node[x]['mask'], graph.node[y]['mask'])
        new_solidity = 1. * new_mask.sum() / convex_hull_image(new_mask).sum()
        org_solidity = np.mean(
            [graph.node[x]['solidity'], graph.node[y]['solidity']])
        d['weight'] = org_solidity / new_solidity

    return graph
def _solidity_weight_func(graph, src, dst, n):
    """Callback to handle merging nodes by recomputing solidity."""
    org_solidity = np.mean([graph.node[src]['solidity'],
                            graph.node[dst]['solidity']])
    new_mask1 = np.logical_or(graph.node[src]['mask'], graph.node[n]['mask'])
    new_mask2 = np.logical_or(graph.node[dst]['mask'], graph.node[n]['mask'])
    new_solidity1 = 1. * new_mask1.sum() / convex_hull_image(new_mask1).sum()
    new_solidity2 = 1. * new_mask2.sum() / convex_hull_image(new_mask2).sum()
    weight1 = org_solidity / new_solidity1
    weight2 = org_solidity / new_solidity2
    return min([weight1, weight2])
def _solidity_weight_func(graph, src, dst, n):
    """Callback to handle merging nodes by recomputing solidity."""
    org_solidity = np.mean(
        [graph.node[src]['solidity'], graph.node[dst]['solidity']])
    new_mask1 = np.logical_or(graph.node[src]['mask'], graph.node[n]['mask'])
    new_mask2 = np.logical_or(graph.node[dst]['mask'], graph.node[n]['mask'])
    new_solidity1 = 1. * new_mask1.sum() / convex_hull_image(new_mask1).sum()
    new_solidity2 = 1. * new_mask2.sum() / convex_hull_image(new_mask2).sum()
    weight1 = org_solidity / new_solidity1
    weight2 = org_solidity / new_solidity2
    return {'weight': min([weight1, weight2])}
def rag_solidity(labels, connectivity=2):

    graph = RAG()

    # The footprint is constructed in such a way that the first
    # element in the array being passed to _add_edge_filter is
    # the central value.
    fp = ndi.generate_binary_structure(labels.ndim, connectivity)
    for d in range(fp.ndim):
        fp = fp.swapaxes(0, d)
        fp[0, ...] = 0
        fp = fp.swapaxes(0, d)

    # For example
    # if labels.ndim = 2 and connectivity = 1
    # fp = [[0,0,0],
    #       [0,1,1],
    #       [0,1,0]]
    #
    # if labels.ndim = 2 and connectivity = 2
    # fp = [[0,0,0],
    #       [0,1,1],
    #       [0,1,1]]

    ndi.generic_filter(
        labels,
        function=_add_edge_filter,
        footprint=fp,
        mode='nearest',
        output=np.zeros(labels.shape, dtype=np.uint8),
        extra_arguments=(graph,))

    # remove bg_label
    # graph.remove_node(-1)
    graph.remove_node(0)

    for n in graph:
        mask = (labels == n)
        solidity = 1. * mask.sum() / convex_hull_image(mask).sum()
        graph.node[n].update({'labels': [n],
                              'solidity': solidity,
                              'mask': mask})

    for x, y, d in graph.edges_iter(data=True):
        new_mask = np.logical_or(graph.node[x]['mask'], graph.node[y]['mask'])
        new_solidity = 1. * new_mask.sum() / convex_hull_image(new_mask).sum()
        org_solidity = np.mean([graph.node[x]['solidity'],
                                graph.node[y]['solidity']])
        d['weight'] = org_solidity / new_solidity

    return graph
Ejemplo n.º 5
0
    def convex_image(self):
        # TODO: grlee77: avoid host/device transfers
        # from ..morphology.convex_hull import convex_hull_image
        from skimage.morphology.convex_hull import convex_hull_image

        # CuPy Backend: copy required here to avoid unexpected behavior
        #               reported in https://github.com/cupy/cupy/issues/4354
        return cp.asarray(convex_hull_image(cp.asnumpy(self.image))).copy()
Ejemplo n.º 6
0
def infer_order_hull(inmodal):
    num = inmodal.shape[0]
    order_matrix = np.zeros((num, num), dtype=np.int)
    occ_value_matrix = np.zeros((num, num), dtype=np.float32)
    for i in range(num):
        for j in range(i + 1, num):
            if bordering(inmodal[i], inmodal[j]):
                amodal_i = convex_hull.convex_hull_image(inmodal[i])
                amodal_j = convex_hull.convex_hull_image(inmodal[j])
                occ_value_matrix[i, j] = ((amodal_i > inmodal[i]) &
                                          (inmodal[j] == 1)).sum()
                occ_value_matrix[j, i] = ((amodal_j > inmodal[j]) &
                                          (inmodal[i] == 1)).sum()
    order_matrix[occ_value_matrix > occ_value_matrix.transpose()] = -1
    order_matrix[occ_value_matrix < occ_value_matrix.transpose()] = 1
    order_matrix[(occ_value_matrix == 0)
                 & (occ_value_matrix == 0).transpose()] = 0
    return order_matrix
Ejemplo n.º 7
0
def infer_amodal_hull(inmodal, bboxes, order_matrix, order_grounded=True):
    amodal = []
    num = inmodal.shape[0]
    for i in range(num):
        m = inmodal[i]
        hull = convex_hull.convex_hull_image(m).astype(np.uint8)
        if order_grounded:
            assert order_matrix is not None
            ancestors = get_ancestors(order_matrix, i)
            eraser = (inmodal[ancestors, ...].sum(axis=0) > 0).astype(
                np.uint8)  # union
            hull[(eraser == 0) & (m == 0)] = 0
        amodal.append(hull)
    return amodal
Ejemplo n.º 8
0
def _rotate_tooth_image(image, mt_masks):
    """
    Rotate the tooth image by using the gravity centers of mineralized tissues.

    Parameters
    ----------
    image: PIL.Image
        The initial tooth image
    mt_masks: [np.array]
        List of masks of mineralized tissues

    Returns
    -------
    (angle, angle deg, rotated image)
    angle: float
        The rotation angle in radiangs
    angle deg: float
        The rotation angle in degrees
    rotated image: PIL.Image
        The tooth image, rotated
    rotated mt masks: [np.array]
        A list of rotated masks
    """
    from skimage.morphology.convex_hull import convex_hull_image

    mt_merged_mask = np.zeros(mt_masks[0].shape)
    for mask in mt_masks:
        mt_merged_mask[mask > 0] = 1
    hull_mask = convex_hull_image(mt_merged_mask)

    hull_gc = _mask_gravity_center(hull_mask)
    hull_gc = (int(hull_gc[1]), int(hull_gc[0]))
    mt_merged_gc = _mask_gravity_center(mt_merged_mask)
    mt_merged_gc = (int(mt_merged_gc[1]), int(mt_merged_gc[0]))

    angle = math.atan2(mt_merged_gc[1] - hull_gc[1], mt_merged_gc[0] - hull_gc[0]) + math.pi / 2
    angle_deg = angle * 180 / math.pi

    rotated_image = image.rotate(angle_deg, expand=True)

    rotated_mt_masks = [ _pillow_image_to_np_binary(_np_binary_to_pillow_image(mt_mask).rotate(angle_deg, expand=True)) for mt_mask in mt_masks]

    return (angle, angle_deg, rotated_image, rotated_mt_masks)
Ejemplo n.º 9
0
def star(a, dtype=np.uint8):
    """Generates a star shaped structuring element.

    Much faster than skimage.morphology version
    """

    if a == 1:
        bfilter = np.zeros((3, 3), dtype)
        bfilter[:] = 1
        return bfilter

    m = 2 * a + 1
    n = a // 2
    selem_square = np.zeros((m + 2 * n, m + 2 * n), dtype=np.uint8)
    selem_square[n:m + n, n:m + n] = 1

    c = (m + 2 * n - 1) // 2
    if True:
        # We can do this much faster with opencv
        b = (m + 2 * n) - 1
        vertices = np.array([
            [0, c],
            [c, 0],
            [b, c],
            [c, b],
            [0, c],
        ])
        pts = vertices.astype(int)[:, None, :]
        mask = np.zeros_like(selem_square)
        mask = cv2.fillConvexPoly(mask, pts, color=1)
        selem_rotated = mask
    else:
        from skimage.morphology.convex_hull import convex_hull_image
        selem_rotated = np.zeros((m + 2 * n, m + 2 * n), dtype=np.float32)
        selem_rotated[0, c] = selem_rotated[-1, c] = 1
        selem_rotated[c, 0] = selem_rotated[c, -1] = 1
        selem_rotated = convex_hull_image(selem_rotated).astype(int)

    selem = np.add(selem_square, selem_rotated, out=selem_square)
    selem[selem > 0] = 1

    return selem.astype(dtype)
def _solidity_merge_func(graph, src, dst):
    """Callback called before merging two nodes of a solidity graph."""
    new_mask = np.logical_or(graph.node[src]['mask'], graph.node[dst]['mask'])
    graph.node[dst]['mask'] = new_mask
    graph.node[dst]['solidity'] = \
        1. * np.sum(new_mask) / np.sum(convex_hull_image(new_mask))
Ejemplo n.º 11
0
def calculate_df(event_path,oi_stage):

    
    # initialize lists to hold data across events
    mask_array = []
    time_array = []
    perimeter_array = []
    area_array = []
    circ_array = []
    deform_array = []
    r_um_array = []
    xcm_pix_array, ycm_pix_array = [],[]
    xcm_um_array, ycm_um_array = [],[]
    tf_array = []
    event = []
    
    perimeter_array_cx = []
    area_array_cx = []
    circ_array_cx = []
    deform_array_cx = []
    r_um_array_cx = []
    
    ellipse_xc_um_array = []
    ellipse_yc_um_array = []
    ellipse_a_array, ellipse_b_array = [],[]
    aspect_array = []
    r_um_elps_array = []
    
    df_raw = pd.read_pickle(event_path)   
    
    for j in df_raw.keys():

        num = len(df_raw[j]['mask'])
        xcm_pix = np.empty(num)
        ycm_pix = np.empty(num)
        xcm_um = np.empty(num)
        ycm_um = np.empty(num)
        area = np.empty(num)
        per = np.empty(num)
        circ = np.empty(num)
        deform = np.empty(num)
        r_um = np.empty(num)
        tf = np.empty(num)
        masks = []
        
        area_cx = np.empty(num)
        per_cx = np.empty(num)
        circ_cx = np.empty(num)
        deform_cx = np.empty(num)
        r_um_cx = np.empty(num)
        
        ellipse_xc_um = np.empty(num)
        ellipse_yc_um = np.empty(num)
        ellipse_a = np.empty(num)
        ellipse_b = np.empty(num)
        aspect = np.empty(num)
        r_um_elps = np.empty(num)

        for i in range(num):

            frame = np.reshape(df_raw[j]['mask'][i],(140,880))
            masks.append(frame)
            
            hull = convex_hull.convex_hull_image(frame)
            
            
            xpix = np.where(frame==1)[1]
            ypix  = np.where(frame==1)[0]
            xc_pix ,yc_pix  = oi_stage.get_channel_coordinates(xpix, ypix)

            xc_um  = oi_stage.pixels_to_meters(xc_pix)
            yc_um  = oi_stage.pixels_to_meters(yc_pix)
            
            xcm_pix = np.mean(xc_pix)
            ycm_pix = np.mean(yc_pix)
            xcm_um[i]  = np.mean(xc_um)
            ycm_um[i]  = np.mean(yc_um)

            area[i]  = np.sum(frame)
            per[i]  = measure.perimeter(frame)
            circ[i]  = 2*np.sqrt(np.pi)*np.sqrt(area[i])/per[i]
            deform[i]  = 1 - circ[i]
            r_um[i]  = (oi_stage.pixels_to_meters(np.sqrt(area[i]/np.pi))+oi_stage.pixels_to_meters(per[i]/(2*np.pi)))/2
            tf[i] = df_raw[j]['time'][i]
            
            area_cx[i]  = np.sum(hull)
            per_cx[i]  = measure.perimeter(hull)
            circ_cx[i]  = 2*np.sqrt(np.pi)*np.sqrt(area[i])/per[i]
            deform_cx[i]  = 1 - circ[i]
            r_um_cx[i]  = (oi_stage.pixels_to_meters(np.sqrt(area[i]/np.pi))+oi_stage.pixels_to_meters(per[i]/(2*np.pi)))/2
    
            
            #ellipse_pixels = np.where(processed_frame == 1)
            ellipse = oi.fit_ellipse_image_aligned(xpix, ypix)
            ellipse_x, ellipse_y = oi.get_ellipse_center(ellipse)
            ellipse_xc,ellipse_yc = oi_stage.get_channel_coordinates(ellipse_x,ellipse_y)
            ellipse_xc_um[i] = oi_stage.pixels_to_meters(ellipse_xc)
            ellipse_yc_um[i] = oi_stage.pixels_to_meters(ellipse_yc)
            ellipse_a[i], ellipse_b[i] = oi.get_ellipse_axes_lengths(ellipse)
            aspect[i] = ellipse_a[i]/ellipse_b[i]
            r_um_elps[i] = np.sqrt(ellipse_a[i]*ellipse_b[i])
            
            
        event.append(j)
        mask_array.append(masks)
        time_array.append(tf)
        perimeter_array.append(per)
        area_array.append(area)
        circ_array.append(circ)
        deform_array.append(deform)
        r_um_array.append(r_um)
        xcm_um_array.append(xcm_um) 
        ycm_um_array.append(ycm_um)
        
        
        perimeter_array_cx.append(per_cx)
        area_array_cx.append(area_cx)
        circ_array_cx.append(circ_cx)
        deform_array_cx.append(deform_cx)
        r_um_array_cx.append(r_um_cx)

        ellipse_xc_um_array.append(ellipse_xc_um)
        ellipse_yc_um_array.append(ellipse_yc_um)
        ellipse_a_array.append(ellipse_a)
        ellipse_b_array.append(ellipse_b)
        aspect_array.append(aspect)
        r_um_elps_array.append(r_um_elps)

    d = {'event':event,'tf':time_array,'mask':mask_array,'perimeter':perimeter_array,'area':area_array,
         'circ':circ_array,'deform':deform_array,'r_um':r_um_array,'xcm_um':xcm_um_array,'yc_um':ycm_um_array,
        'perimeter_cx':perimeter_array_cx,'area_cx':area_array_cx,'circ_cx':circ_array_cx,'deform_cx':deform_array_cx,
         'r_um_cx':r_um_array_cx,'xc_um_el':ellipse_xc_um_array,'yc_um_el':ellipse_yc_um_array,'a':ellipse_a_array,
         'b':ellipse_b_array,'aspect':aspect_array,'r_um_el':r_um_elps_array}   

    df = pd.DataFrame(data=d)
    df['cell'] = particle_type
    df['date'] = date
    df['run'] = file_index
    
    #Remove events with empty time series. Artifact of event detection
    df = df[df.tf.map(lambda a: a.size!=0)]
    
    return df
Ejemplo n.º 12
0
    def convex_image(self):
        # from ..morphology.convex_hull import convex_hull_image
        # TODO: grlee77: avoid host/device transfers
        from skimage.morphology.convex_hull import convex_hull_image

        return cp.asarray(convex_hull_image(cp.asnumpy(self.image)))
Ejemplo n.º 13
0
def bug_tertiary():
    rp = regionprops(SAMPLE)[0]
    img = rp.image
    conv_img = convex_hull_image(img)
    return
def _solidity_merge_func(graph, src, dst):
    """Callback called before merging two nodes of a solidity graph."""
    new_mask = np.logical_or(graph.node[src]['mask'], graph.node[dst]['mask'])
    graph.node[dst]['mask'] = new_mask
    graph.node[dst]['solidity'] = \
        1. * np.sum(new_mask) / np.sum(convex_hull_image(new_mask))
Ejemplo n.º 15
0
def localize_apices_engine(image,
                           mt_masks,
                           debug=False,
                           output_dir='.',
                           image_name=''):
    # load the masks

    # check the mask length
    if len(mt_masks) < 2:
        raise ValueError('2 MT masks are needed to infer')
    mt_masks = utils._find_greatest_mt_masks(mt_masks)
    angle, _, rotated_image, mt_masks = utils._rotate_tooth_image(
        image, mt_masks)
    width, height = rotated_image.size

    apical_mt_mask, coronal_mt_mask = mt_masks
    mt_merged_mask = apical_mt_mask | coronal_mt_mask

    # gradient cancel masks
    coronal_distance = ndi.distance_transform_edt(
        np.where(coronal_mt_mask > 0, 0, 1))
    apical_distance = ndi.distance_transform_edt(
        np.where(apical_mt_mask > 0, 0, 1))
    hull = convex_hull_image(apical_mt_mask | coronal_mt_mask)
    cancel_mask = np.where(
        np.abs(coronal_distance - apical_distance) < 2, 1, 0)
    thin_cancel_mask = skeletonize(cancel_mask) & hull
    apical_hull = convex_hull_image(apical_mt_mask)

    utils._apply_mask_to_image(rotated_image, cancel_mask, (0, 255, 0))
    utils._apply_mask_to_image(rotated_image,
                               thin_cancel_mask, (255, 255, 0),
                               alpha=1)
    utils._apply_mask_to_image(rotated_image,
                               coronal_mt_mask, (255, 0, 0),
                               alpha=0.2)
    utils._apply_mask_to_image(rotated_image,
                               apical_hull, (0, 0, 255),
                               alpha=0.2)

    # display outlines
    coronal_outline, apical_outline, coronal_outline_mask, apical_outline_mask = display_outlines(
        rotated_image, coronal_mt_mask, apical_mt_mask)

    # display hull
    utils._apply_mask_to_image(rotated_image, hull, (255, 0, 255), alpha=0.05)

    # temporary endpoints
    temporary_endpoints = get_temporary_endpoints(rotated_image,
                                                  thin_cancel_mask, hull)
    if len(temporary_endpoints) < 2:
        _logger.error(
            'can not find endpoints if less than 2 potential endpoints')
        return
    coronal_dp_points, apical_dp_points = get_dp_points(
        width, height, rotated_image, thin_cancel_mask, apical_outline_mask,
        apical_mt_mask, coronal_outline_mask, coronal_mt_mask)

    # get the split points
    apical_split_point, coronal_split_point = get_dentin_pulp_split_points(
        rotated_image, coronal_mt_mask, apical_mt_mask, coronal_outline,
        apical_outline, coronal_outline_mask, apical_outline_mask)
    utils._add_mark(rotated_image, apical_split_point, (255, 128, 0))
    utils._add_mark(rotated_image, coronal_split_point, (255, 128, 0))
    apical_dp_points.append(apical_split_point)
    coronal_dp_points.append(coronal_split_point)

    # reorder the points
    ordered_apical_dp_points = reorder_dentin_pulp_points(
        apical_dp_points, apical_outline)
    ordered_coronal_dp_points = reorder_dentin_pulp_points(
        coronal_dp_points, coronal_outline)
    for point in ordered_apical_dp_points + ordered_coronal_dp_points:
        rotated_image.putpixel(point, (255, 128, 0))

    # clean the dp points
    left_middle_endpoint, right_middle_endpoint = temporary_endpoints[
        0], temporary_endpoints[1]
    if left_middle_endpoint[0] > right_middle_endpoint[0]:
        left_middle_endpoint, right_middle_endpoint = right_middle_endpoint, left_middle_endpoint
    left_coronal_points, left_apical_points, right_apical_points, right_coronal_points = clean_dp_points(
        rotated_image, temporary_endpoints, apical_split_point,
        coronal_split_point, ordered_apical_dp_points,
        ordered_coronal_dp_points, mt_merged_mask)

    # find the new endpoints
    draw = ImageDraw.Draw(rotated_image)
    endpoint_pairs = select_endpoint_pairs(
        left_middle_endpoint, right_middle_endpoint, left_coronal_points,
        left_apical_points, right_apical_points, right_coronal_points)
    for endpoint_pair in endpoint_pairs:
        for point in endpoint_pair:
            utils._add_mark(rotated_image, point, (255, 0, 0))
        draw.line(endpoint_pair, (255, 0, 0))

    (tooth_height, min_y,
     max_y) = utils._get_tooth_height(apical_mt_mask | coronal_mt_mask)
    draw.line((width // 2, min_y, width // 2, max_y), (0, 0, 255))

    (i3m, min_apex_opening,
     max_apex_opening) = utils._compute_i3m(endpoint_pairs, tooth_height)

    result = {
        'output_image': rotated_image,
        'I3M': i3m,
        'min_apex_opening': min_apex_opening,
        'max_apex_opening': max_apex_opening,
        'height': tooth_height
    }

    # draw the rotated image if debug
    if debug:
        image_path = os.path.join(output_dir, f'{image_name}-debug.png')
        rotated_image.save(image_path)

    return result
Ejemplo n.º 16
0
def segment_lesion(image, mode="KMeans"):
    ## Unsupervised Segmentation
    # K-Means Clustering
    if (mode == "KMeans"):
        # K-Means Clustering
        deim = denoise(cv2.cvtColor(image, cv2.COLOR_RGB2GRAY), weight=150)
        kmeans = KMeans(n_clusters=2, random_state=0,
                        n_jobs=-1).fit(deim.reshape(-1, 1))
        mask = (kmeans.labels_).reshape(deim.shape[0],
                                        deim.shape[1]).astype('uint8')

    # Expectation-Maximization Gaussian Mixture Model
    elif (mode == "EM"):
        # K-Means Clustering
        feature_vector = (denoise(cv2.cvtColor(image, cv2.COLOR_RGB2GRAY),
                                  weight=150)).reshape(-1, 1)
        kmeans = KMeans(n_clusters=2, random_state=0,
                        n_jobs=-1).fit(feature_vector)
        KMpredict = kmeans.predict(feature_vector)

        # Expectation Step: Initialization with K-Means
        KM_BG = feature_vector[KMpredict == 0]
        KM_FG = feature_vector[KMpredict == 1]

        # Expectation Step: Mean and Covariance
        mean_BG = np.mean(KM_BG, axis=0)
        mean_FG = np.mean(KM_FG, axis=0)
        covar_BG = np.cov(KM_BG, rowvar=False)
        covar_FG = np.cov(KM_FG, rowvar=False)

        # Expectation Step: Prior Probabilities
        prob_BG = KM_BG.shape[0] / feature_vector.shape[0]
        prob_FG = KM_FG.shape[0] / feature_vector.shape[0]

        # Iterative Update
        min_change = 0.01
        max_steps = 5

        for i in range(max_steps):
            # Expectation Step: Probability Density Function
            PDF_BG = multivariate_normal.pdf(feature_vector,
                                             mean=mean_BG,
                                             cov=covar_BG)
            PDF_FG = multivariate_normal.pdf(feature_vector,
                                             mean=mean_FG,
                                             cov=covar_FG)
            weights_BG = (prob_BG * PDF_BG) / ((prob_FG * PDF_FG) +
                                               (prob_BG * PDF_BG))
            weights_FG = (prob_FG * PDF_FG) / ((prob_FG * PDF_FG) +
                                               (prob_BG * PDF_BG))
            weights = np.concatenate(
                (weights_BG.reshape(-1, 1), weights_FG.reshape(-1, 1)), axis=1)
            log_B = sum((np.log(sum(weights))))

            # Maximization Step: New Probabilities
            _, counts = np.unique(np.argmax(weights, axis=1),
                                  return_counts=True)
            prob_BG = counts[0] / feature_vector.shape[0]
            prob_FG = counts[1] / feature_vector.shape[0]

            # Maximization Step: New Mean and Covariance
            mean_BG = (1 / counts[0]) * (weights[:, 0] @ feature_vector)
            mean_FG = (1 / counts[1]) * (weights[:, 1] @ feature_vector)
            covar_BG = (1 / counts[0]) * (
                weights[:, 0] * np.transpose(feature_vector - mean_BG)) @ (
                    feature_vector - mean_BG)
            covar_FG = (1 / counts[1]) * (
                weights[:, 1] * np.transpose(feature_vector - mean_FG)) @ (
                    feature_vector - mean_FG)

            # Maximization Step: Probability Density Function
            PDF_BG = multivariate_normal.pdf(feature_vector,
                                             mean=mean_BG,
                                             cov=covar_BG)
            PDF_FG = multivariate_normal.pdf(feature_vector,
                                             mean=mean_FG,
                                             cov=covar_FG)
            weights_BG = (prob_BG * PDF_BG) / ((prob_FG * PDF_FG) +
                                               (prob_BG * PDF_BG))
            weights_FG = (prob_FG * PDF_FG) / ((prob_FG * PDF_FG) +
                                               (prob_BG * PDF_BG))
            weights = np.concatenate(
                (weights_BG.reshape(-1, 1), weights_FG.reshape(-1, 1)), axis=1)
            log_N = sum((np.log(sum(weights))))

            # Update Trackers, Verify Conditions
            change_log = np.linalg.norm(log_N - log_B)
            if (change_log <= min_change):
                continue
            else:
                break

        # Output Image Reconstruction
        mask = (np.argmax(weights, axis=1)).reshape(-1, 1)
        mask = np.reshape(mask,
                          (image.shape[0], image.shape[1])).astype('uint8')

    # Chan-Vese Active Contours
    elif (mode == "active_contours"):
        # Morphological ACWE
        image = img_as_float(cv2.cvtColor(image, cv2.COLOR_RGB2GRAY))

        # Initial level Set
        init_ls = checkerboard_level_set(image.shape, 6)

        # List with Intermediate Results for Plotting the Evolution
        evolution = []
        callback = store_evolution_in(evolution)
        mask = morphological_chan_vese(image,
                                       5,
                                       init_level_set=init_ls,
                                       smoothing=10,
                                       iter_callback=callback).astype(np.uint8)

    # Watershed
    elif (mode == "mod_watershed"):

        ret, thresh = cv2.threshold(cv2.cvtColor(image,
                                                 cv2.COLOR_RGB2GRAY), 0, 255,
                                    cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
        kernel = np.ones((3, 3), np.uint8)
        opening = cv2.morphologyEx(thresh,
                                   cv2.MORPH_OPEN,
                                   kernel,
                                   iterations=2)

        sure_bg = cv2.dilate(opening, kernel, iterations=3)
        dist_transform = cv2.distanceTransform(opening, cv2.DIST_L2, 5)
        ret, sure_fg = cv2.threshold(dist_transform,
                                     0.01 * dist_transform.max(), 255, 0)

        ls = np.uint8(sure_fg) / 255
        circle_mask = create_circular_mask(image.shape[0],
                                           image.shape[1],
                                           radius=220)
        ls = ls * circle_mask

        # Discard Edge-to-Edge Connected Component
        large = getLargestCC(ls).astype(np.uint8)
        if (corner_mean(large) > 1):
            large = getLargestCC(ls - large).astype(np.uint8)

        # Post-Process Masks
        post = ndimage.binary_fill_holes(large, structure=np.ones(
            (5, 5))).astype(bool)

    else:
        print("ERROR: Undefined Segmentation Mode")

    ## Segmentation Label Selection
    # Define Target Scope
    candidate_mask_1 = mask.copy() * create_circular_mask(
        image.shape[0], image.shape[1], radius=230)
    candidate_mask_2 = (np.invert(mask.copy()) + 2) * create_circular_mask(
        image.shape[0], image.shape[1], radius=230)

    # Compute Area of Convex Hulls
    convex_hull_1 = convex_hull_image(candidate_mask_1)
    convex_hull_2 = convex_hull_image(candidate_mask_2)

    # Set Segmentation Component Labels
    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (10, 10))
    if (np.sum(convex_hull_1) < np.sum(convex_hull_2)):
        dilation = cv2.dilate(candidate_mask_1, kernel, iterations=1)
        mask = ndimage.binary_fill_holes(dilation, structure=np.ones((5, 5)))
    else:
        dilation = cv2.dilate(candidate_mask_2, kernel, iterations=1)
        mask = ndimage.binary_fill_holes(dilation, structure=np.ones((5, 5)))
    if (np.sum(mask) < 5000):
        mask = create_circular_mask(image.shape[0], image.shape[1], radius=230)
    return mask
Ejemplo n.º 17
0
def bug_quaternary():
    img = SAMPLE.astype(np.bool)
    conv_img = convex_hull_image(img)
    return