def parasites(image, cells, voronoi):
    img = Functions.global_otsu(image)
    cells = Functions.global_otsu(cells)
    s_elem = Functions.fig(Functions.fig_size)

    # Remove cells

    for i in range(Functions.iterations):
        cells = binary_dilation(cells, s_elem)
    return_image = Functions.subtraction(img, cells)

    # Remove stuff from cells

    for i in range(Functions.iterations-1):
        return_image = binary_erosion(return_image)
    return_image = binary_opening(return_image)
    for i in range(Functions.iterations - 1):
        return_image = binary_dilation(return_image)

    # Remove bigger objects

    removal_image = return_image.copy()

    for i in range(Functions.iterations + 5):
        removal_image = binary_erosion(removal_image)
    removal_image = binary_opening(removal_image)
    for i in range(Functions.iterations + 10):
        removal_image = binary_dilation(removal_image)

    return_image = Functions.subtraction(return_image, removal_image)

    # Remove voronoi lines for better quality
    return Functions.subtraction(return_image, voronoi)
Esempio n. 2
0
def process_cell(img):

    # la binariza en caso de que sea escala de grises
    if not img.dtype == 'bool':
        img = img > 0  # Binarizar

    # Calcular máscaras para limpiar lineas largas verticales
    h_k = 0.8
    sum0 = np.sum(img, 0)  # Aplastar la matriz a una fila con las sumas de los valores de cada columna.
    thr0 = sum0 < h_k * img.shape[0]
    thr0 = thr0.reshape(len(thr0), 1) # Convertirlo a vector de una dimensión

    # Calcular máscaras para limpiar lineas largas horizontales
    w_k = 0.5
    sum1 = np.sum(img, 1)
    thr1 = sum1 < w_k * img.shape[1]
    thr1 = thr1.reshape(len(thr1), 1)

    mask = thr0.transpose() * thr1 # Generar máscara final para la celda
    mask_lines = mask.copy()

    elem = morphology.square(5)
    mask = morphology.binary_erosion(mask, elem) # Eliminar ruido

    img1 = np.bitwise_and(mask, img) # Imagen filtrada

    # segmentación del bloque de números
    kerw = 5  # Kernel width
    thr_k = 0.8

    # Calcular mascara para marcar inicio y fin de región con dígitos horizontalmente
    sum0 = np.sum(img1, 0)
    sum0 = signal.medfilt(sum0, kerw)
    thr0 = sum0 > thr_k * np.median(sum0)
    thr0 = np.bitwise_and(thr0.cumsum() > 0, np.flipud(np.flipud(thr0).cumsum() > 0))
    thr0 = thr0.reshape(len(thr0), 1)

    # Calcular mascara para marcar inicio y fin de región con dígitos verticalmente
    sum1 = np.sum(img1, 1)
    sum1 = signal.medfilt(sum1, kerw)
    thr1 = sum1 > thr_k * np.median(sum1)
    thr1 = np.bitwise_and(thr1.cumsum() > 0, np.flipud(np.flipud(thr1).cumsum() > 0))
    thr1 = thr1.reshape(len(thr1), 1)

    # Mascara final para inicio y fin de caracteres (bounding box of digit region)
    mask = thr0.transpose() * thr1
    mask = morphology.binary_dilation(mask, morphology.square(2))


    img = np.bitwise_and(mask_lines.astype(img.dtype), img)  # Aplicar máscara para quitar lineas
    img = morphology.binary_dilation(img, morphology.disk(1)) # Dilatación para unir números quebrados por la máscara anterior
    img = morphology.binary_erosion(img, morphology.disk(1)) # Volver a la fomorma 'original' con los bordes unidos

    return np.bitwise_and(mask, img)
def eroding3D(data, selem=skimor.disk(3), slicewise=False, sliceId=0):
    if slicewise:
        if sliceId == 0:
            for i in range(data.shape[0]):
                data[i, :, :] = skimor.binary_erosion(data[i, :, :], selem)
        elif sliceId == 2:
            for i in range(data.shape[2]):
                data[:, :, i] = skimor.binary_erosion(data[:, :, i], selem)
    else:
        data = scindimor.binary_erosion(data, selem)
    return data
Esempio n. 4
0
    def __call__(self, image, range_, shrink_per_label=False):

        radius = np.abs(range_[0])
        struct = median(disk(radius), disk(1))

        if shrink_per_label:
            out = np.zeros(image.shape, dtype=np.int16)
            for label in np.unique(image)[1:]:
                bin_ = (image == label).astype(np.uint8) # ev. as bool
                bin_ = binary_erosion(bin_, struct)
                out += (bin_*label).astype(out.dtype)
        else:
            out = binary_erosion(image.astype(np.uint8), struct)

        return out*image.astype(np.int16)
def cleanImage(img, min_size, scale_factor, img_otsu=None, saver=lambda n,x: x):
    img, exposure_data = normalize_exposure2(img)
    img = saver("01-exposure", img)
    img_otsu = ski.filter.threshold_otsu(img) if not img_otsu else img_otsu
    print('otsu:',img_otsu, ski.filter.threshold_otsu(img))

    img = saver("02-zoom", scipy.ndimage.zoom(img, scale_factor, order=3))
    print("shape after zoom:", img.shape)
#     img_pil = PIL.Image.fromarray(img).resize((np.array(img.shape)*scale_factor).tolist()[:2], resample=PIL.Image.BICUBIC)
#     img = saver("02-zoom", PIL2array(img_pil))
    print("img:",img.shape,img.dtype)

    img_cleaned = saver("03-bw", (img > img_otsu))
#     img_cleaned = saver("03-bw", (img > 0.2))

    dbg = DebugData()

    img_cleaned = morphology.binary_erosion(img_cleaned,morphology.disk(int(2*scale_factor)))
    img_cleaned = saver("04-erosion", img_cleaned, dbg=dbg)

    img_cleaned = morphology.remove_small_objects(img_cleaned, min_size=int(min_size*scale_factor), connectivity=2)
    img_cleaned = saver("05-remove", img_cleaned)


    cleaned_sum = np.sum(img_cleaned)
    print("img_cleaned size:",cleaned_sum)
#     if cleaned_sum < 1000 or cleaned_sum > 300000:
#         display(Image(str(dbg.saved_path)))
#         raise Exception("Image not cleaned correctly"+str(locals()))

    return img_cleaned, exposure_data
Esempio n. 6
0
def estimate_rotation(img):
    assert(img.dtype == 'bool')

    # elimina bloques rellenos para acelerar la deteccion de lineas
    elem = morphology.square(2)
    aux = morphology.binary_dilation(img, elem) - morphology.binary_erosion(img, elem)

    # Detección de lineas usando transformada de Hough probabilística
    thres = 50
    minlen = 0.1 * min(aux.shape)
    maxgap = 0.01 * minlen
    lines = transform.probabilistic_hough(aux, threshold=thres, line_length=minlen, line_gap=maxgap)

    # me aseguro que el primer punto de cada línea sea el más próximo al origen
    for lin in lines:
        (x0,y0), (x1,y1) = lin
        if x1*x1+y1*y1 < x0*x0+y0*y0:
            (x0, x1) = (x1, x0)
            (y0, y1) = (y1, y0)

    # orientación dominante
    angle_half_range = np.math.pi / 4
    nbins = int(2 * angle_half_range * (180./np.math.pi) / 0.2)

    orient = []
    for lin in lines:
        (x0,y0), (x1,y1) = lin
        orient.append(np.math.atan2(y1-y0, x1-x0))

    (h, binval) = np.histogram(orient, range=(-angle_half_range, angle_half_range), bins=nbins)
    alpha = binval[h.argmax()] * (180./ np.math.pi)
    return alpha + 0.5 * (binval[1] - binval[0]) * (180./ np.math.pi)
Esempio n. 7
0
def calculate_masked_stats():
    plate_no = "59798"
    parsed = get_plate_files(plate_no)
    for w in ['w2']:
        files = filter(lambda f: f.wave == w[1], parsed)
        # accum = np.zeros((2160, 2160), dtype=np.uint32)
        # files = filter(lambda x: 's1' not in x and 's7' not in x, all_files)
        nof = len(files)
        for i, frame in enumerate(files[0:5], 1):
            LogHelper.logText(frame.fullpath)
            img = imread(frame.fullpath)
            t = filters.threshold_yen(img)
            b1 = img > t
            b2 = binary_erosion(b1, square(2))
            b3 = binary_dilation(b2, square(10))
            b4 = binary_closing(b3, square(3))
            imm = np.ma.masked_where(b4, img)
            mn, mx = np.percentile(imm, (1, 99))
            LogHelper.logText(
                '%3d of %d, %4d-%4d-%4d-%5d, %.0f-%.0f'
                % (i, nof, imm.min(), mn, mx, imm.max(), imm.mean(), imm.std())
            )
            im2 = imm.filled(int(imm.mean()))
            out_name = "{0}\\{5}-{1}{2}-{3}-{4}.tif".format(ROOT_DIR, frame.row, frame.column, frame.site, LogHelper.init_ts, frame.experiment)
            imsave(out_name, im2)
Esempio n. 8
0
def get_segmented_lungs(im):

    binary = im < -320
    cleared = clear_border(binary) 
    cleared=morph(cleared,5)
    label_image = label(cleared)
  
    areas = [r.area for r in regionprops(label_image)]
    areas.sort()
    if len(areas) > 2:
        for region in regionprops(label_image):
            if region.area < areas[-2]:
                for coordinates in region.coords:
                       label_image[coordinates[0], coordinates[1]] = 0
    binary = label_image > 0  
    selem = disk(2)
    binary = binary_erosion(binary, selem)
 
    selem = disk(10)
    binary = binary_closing(binary, selem)
    edges = roberts(binary)
    binary = ndi.binary_fill_holes(edges)
 
    get_high_vals = binary == 0
    im[get_high_vals] = 0
  
    binary = morphology.dilation(binary,np.ones([5,5]))
    return binary
def double_erosion(binary, selem):
    '''Returns the result of two sequential binary erosions'''

    for i in (1,2):
        binary = binary_erosion(binary, selem)

    return binary
def cleanImageOld(img, min_size, scale_factor, img_otsu=None, saver=lambda n,x: x):
    img, exposure_data = normalize_exposure2(img)
    img = saver("01-exposure", img)
    img_otsu = ski.filter.threshold_otsu(img) if not img_otsu else img_otsu
    
    img = saver("02-zoom", scipy.ndimage.zoom(img, scale_factor, order=3))
    print("img:",img.shape,img.dtype)
    
    img_cleaned = saver("03-bw", (img > img_otsu))
    
    dbg = DebugData()   
    
    img_cleaned = morphology.binary_erosion(img_cleaned,
                                            morphology.disk(int(2*scale_factor)))
    
    img_cleaned = saver("04-erosion", img_cleaned, dbg=dbg)
    
    img_cleaned = morphology.remove_small_objects(
                    img_cleaned, min_size=int(min_size*scale_factor), connectivity=2)
                    
    img_cleaned = saver("05-remove", img_cleaned)

    
    cleaned_sum = np.sum(img_cleaned)
    print("img_cleaned size:",cleaned_sum)
    
    return img_cleaned, exposure_data
Esempio n. 11
0
def get_mask(srcpath):
    """
    Read the mask for a given filepath. It is assumed
    that the 4th band corresponds to a mask. If a 4th
    band does not exist, a square mask is generated with
    border pixels marked out.

    :param srcpath:
    """

    with rio.drivers():
        with rio.open(srcpath) as src:
            count = src.count

            if count < 4:
                mask = np.ones(src.shape, dtype=np.uint8)
                mask[0, :] = 0
                mask[-1, :] = 0
                mask[:, 0] = 0
                mask[:, -1] = 0
            else:
                mask = src.read(4).astype(np.bool)
                mask = binary_erosion(mask, disk(3)).astype(np.uint8)

                # height, width = src.shape
                # h2, w2 = height / 2, width / 2
                # mask = np.zeros(src.shape, dtype=np.uint8)
                # r = 600
                # mask[h2 - r: h2 + r + 1, w2 - r: w2 + r + 1] = disk(r)

    return mask
Esempio n. 12
0
def binarize_canny(pic_source, sensitivity = 5.):

    ht = 5. + ((10 - sensitivity)/5.)*20.

#    print ht

    edges = canny_filter(pic_source, sigma = 3, high_threshold = ht, low_threshold = 2.)

    selem_morph = np.array([0,1,0,1,1,1,0,1,0], dtype=bool).reshape((3,3))

    for i in (1,2):
        edges = binary_dilation(edges, selem_morph)

#    misc.imsave('/home/varnivey/Data/Biophys/Burnazyan/Experiments/fluor_calc/test/edges.jpg', edges)

#    binary = ndimage.binary_fill_holes(edges)

    labels = measure_label(edges)

    labelcount = np.bincount(labels.ravel())

    bg = np.argmax(labelcount)

    edges[labels != bg] = 255

    selem_med = np.ones((3,3), dtype = bool)

    binary = median_filter(edges, selem_med)

    for i in (1,2,3):
        binary = binary_erosion(edges, selem_morph)

    return edges
Esempio n. 13
0
def get_segmented_lungs(im, plot=False):
    # Step 1: Convert into a binary image.
    binary = im < -400
    # Step 2: Remove the blobs connected to the border of the image.
    cleared = clear_border(binary)
    # Step 3: Label the image.
    label_image = label(cleared)
    # Step 4: Keep the labels with 2 largest areas.
    areas = [r.area for r in regionprops(label_image)]
    areas.sort()
    if len(areas) > 2:
        for region in regionprops(label_image):
            if region.area < areas[-2]:
                for coordinates in region.coords:
                       label_image[coordinates[0], coordinates[1]] = 0
    binary = label_image > 0
    # Step 5: Erosion operation with a disk of radius 2. This operation is seperate the lung nodules attached to the blood vessels.
    selem = disk(2)
    binary = binary_erosion(binary, selem)
    # Step 6: Closure operation with a disk of radius 10. This operation is    to keep nodules attached to the lung wall.
    selem = disk(10) # CHANGE BACK TO 10
    binary = binary_closing(binary, selem)
    # Step 7: Fill in the small holes inside the binary mask of lungs.
    edges = roberts(binary)
    binary = ndi.binary_fill_holes(edges)
    # Step 8: Superimpose the binary mask on the input image.
    get_high_vals = binary == 0
    im[get_high_vals] = -2000
    return im, binary
Esempio n. 14
0
def removeChessboard(img):

    # Get the major lines in the image
    edges, dilatedEdges, (h, theta, d) = findLines(img)

    # Create image with ones to fill inn lines
    lines = np.ones(img.shape[:2])

    # Add lines to image as zeroes
    for _, angle, dist in zip(*hough_line_peaks(h, theta, d)):
        y0 = (dist - 0 * np.cos(angle)) / np.sin(angle)
        y1 = (dist - img.shape[1] * np.cos(angle)) / np.sin(angle)
        x, y = line(int(y1), 0, int(y0), img.shape[1] - 1)
        x = np.clip(x, 0, img.shape[0] - 1)
        y = np.clip(y, 0, img.shape[1] - 1)
        lines[x, y] = 0

    # Remove border edges from image with all edges
    w = 4
    edges = np.pad(edges[w:img.shape[0] - w, w:img.shape[1] - w], w, mode='constant')

    # Erode the lines bigger, such that they cover the original lines
    lines = binary_erosion(lines, square(13))

    # Remove major lines and close shape paths
    removedChessboard = binary_closing(edges * lines, square(8))

    return removedChessboard
 def get_outline(im):
     """Return segmentation outline."""
     binary_mask_im = im != 0
     salem = disk(4)
     erosion_mask_im = binary_erosion(binary_mask_im, salem)
     outline_mask_im = np.logical_xor(binary_mask_im, erosion_mask_im)
     return im * outline_mask_im
Esempio n. 16
0
def colors_peripheral_vs_central(image_roi, attrs={}, debug=False):
    image_roi, center = pad_for_rotation(image_roi)
    lesion_mask = image_roi[..., 3]

    goal = lesion_mask.sum() * 0.7
    inner = lesion_mask.copy()
    while inner.sum() > goal:
        inner = binary_erosion(inner, disk(1))
    outer = np.logical_and(lesion_mask, np.logical_not(inner))

    if debug:
        print """\
=== Colors Peripheral vs Central ===
lesion area: %d
inner goal: %d
inner area: %d
outer area: %d
""" % (lesion_mask.sum(), goal, inner.sum(), outer.sum())

    if debug:
        plt.subplot(131)
        plt.imshow(lesion_mask)
        plt.subplot(132)
        plt.imshow(inner)
        plt.subplot(133)
        plt.imshow(outer)
        plt.show()

    outer = np.nonzero(outer)
    inner = np.nonzero(inner)

    image_lab = rgb2lab(image_roi[..., :3])
    L, a, b = np.dsplit(image_lab, 3)

    delta_L = np.mean(L[outer]) - np.mean(L[inner])
    delta_a = np.mean(a[outer]) - np.mean(a[inner])
    delta_b = np.mean(b[outer]) - np.mean(b[inner])

    density_L = (
        np.histogram(L[outer], 100, (0.,100.), density=True)[0] *
        np.histogram(L[inner], 100, (0.,100.), density=True)[0]
    ).sum()
    density_a = (
        np.histogram(a[outer], 254, (-127.,127.), density=True)[0] *
        np.histogram(a[inner], 254, (-127.,127.), density=True)[0]
    ).sum()
    density_b = (
        np.histogram(b[outer], 254, (-127.,127.), density=True)[0] *
        np.histogram(b[inner], 254, (-127.,127.), density=True)[0]
    ).sum()

    attrs.update([
        ('Colors PvsC mean difference L', delta_L),
        ('Colors PvsC mean difference a', delta_a),
        ('Colors PvsC mean difference b', delta_b),
        ('Colors PvsC density baysian L', density_L),
        ('Colors PvsC density baysian a', density_a),
        ('Colors PvsC density baysian b', density_b),
    ])
Esempio n. 17
0
 def seg_sect(self, img):
     img_canny = canny(img, sigma=self.sigma,
                       low_threshold=self.low_threshold)
     
     img_dilate = binary_dilation(img_canny, square(3))
     img_erode = binary_erosion(img_dilate, square(3))
     img_fill = binary_fill_holes(img_erode)
     
     return img_fill
def mixing_region(filename):
    white = io.imread(filename)
    val = filter.threshold_otsu(white)
    light_mask = white > val
    regions = morphology.label(light_mask)
    index_large_region = np.argmax(np.bincount(regions.ravel()))
    fluid_mask = regions == index_large_region
    fluid_mask = morphology.binary_erosion(fluid_mask, selem=np.ones((3, 3)))
    return fluid_mask
Esempio n. 19
0
def cells(image):
    img = Functions.global_otsu(image)
    s_elem = Functions.fig(Functions.fig_size)
    for i in range(Functions.iterations):
        img = binary_erosion(img, s_elem)
    for i in range(Functions.iterations):
        img = binary_dilation(img, s_elem)

    return Functions.watershed_separation(img, s_elem)
Esempio n. 20
0
def erode(data, radius):
    """
    Erode data using ball structuring element
    :param data: 2d or 3d array
    :param radius: radius of structuring element
    :return: data eroded
    """
    from skimage.morphology import binary_erosion, ball
    selem = ball(radius)
    return binary_erosion(data, selem=selem, out=None)
Esempio n. 21
0
    def compute_perim_mask(self, mask, thick):
        """returns mask for perimeter
        needs cell mask
        """
        # create mask

        eroded = morphology.binary_erosion(mask, np.ones((thick * 2 - 1, thick - 1))).astype(float)
        perim = mask - eroded

        return perim
Esempio n. 22
0
def border_scores(image, center, major_axis, attrs={}, debug=False):
    eroded = binary_erosion(image[...,3], disk(4))
    border = eroded - binary_erosion(eroded, disk(1))
    border_mask = binary_dilation(border, disk(7))

    rn = roberts_negative_diagonal(image[...,0], border_mask)
    rp = roberts_positive_diagonal(image[...,0], border_mask)
    gn = roberts_negative_diagonal(image[...,1], border_mask)
    gp = roberts_positive_diagonal(image[...,1], border_mask)
    bn = roberts_negative_diagonal(image[...,2], border_mask)
    bp = roberts_positive_diagonal(image[...,2], border_mask)
    gradient = np.sqrt(rn**2 + rp**2 + gn**2 + gp**2 + bn**2 + bp**2)

    border_scores = [
        np.average(gradient, weights=section) * 255
        for section in _make_partitions(8, border_mask, center, major_axis)
        if section.sum() > 0
    ]

    attrs.update(('--Border Scores Section %d' % i, score)
                 for i, score in enumerate(border_scores, 1))
    attrs.update([
        ('Border Scores Average', np.mean(border_scores)),
        ('Border Scores Stddev', np.std(border_scores)),
    ])

    if debug:
        print "--- Border Scores ---"
        print " | ".join("%.3f" % score for score in border_scores)
        print

        plt.subplot(121)
        imgplot = plt.imshow((image[...,:3].T * border_mask.T).T)
        imgplot.set_interpolation('nearest')

        plt.subplot(122)
        imgplot = plt.imshow(gradient)
        imgplot.set_interpolation('nearest')
        plt.show()
    
    attrs['--Border Score'] = sum(score >= 10 for score in border_scores)
    return attrs 
Esempio n. 23
0
def get_contour(image):
    image_data = plt.imread(image)

    gimg = color.colorconv.rgb2grey(image_data)
    bwimg = gimg > 0
    bwimg = binary_dilation(bwimg, None)
    bwimg = ndimage.binary_fill_holes(bwimg)
    bwimg = binary_erosion(bwimg)
    contours = [approximate_polygon(new_s, 0.9) for new_s in measure.find_contours(bwimg, 0.5)]

    return bwimg, contours
Esempio n. 24
0
def binary_find_boundaries(image):
    if image.dtype != np.bool:
        raise ValueError('image must have dtype = \'bool\'')
    if image.ndim == 2:
        selem = disk(1)
    elif image.ndim == 3:
        selem = ball(1)
    else:
        raise ValueError('image must be 2D or 3D')
    eroded = binary_erosion(image, selem)
    return (image & (~eroded))
Esempio n. 25
0
def unet_candidates():
    cands = glob.glob("../data/predictions_epoch9_23_all/*.png")
    #df = pd.DataFrame(columns=['seriesuid','coordX','coordY','coordZ','class'])
    data = []
    imname = ""
    origin = []
    spacing = []
    nrimages = 0
    for name in tqdm(cands):

        #image = imread(name)
        image_t = imread(name)
        image_t = image_t.transpose()
        #Thresholding
        image_t[image_t<THRESHOLD] = 0
        image_t[image_t>0] = 1
        #erosion
        selem = morphology.disk(1)
        image_eroded = image_t
        image_eroded = morphology.binary_erosion(image_t,selem=selem)

        label_im, nb_labels = ndimage.label(image_eroded)
        imname3 = os.path.split(name)[1].replace('.png','')

        splitted = imname3.split("slice")
        slice = splitted[1]
        imname2 = splitted[0][:-1]
        centers = []
        for i in xrange(1,nb_labels+1):
            blob_i = np.where(label_im==i,1,0)
            mass = center_of_mass(blob_i)
            centers.append([mass[1],mass[0]])


        if imname2 != imname:
            if os.path.isfile("../data/1_1_1mm_512_x_512_annotation_masks/spacings/{0}.pickle".format(imname2)):
                with open("../data/1_1_1mm_512_x_512_annotation_masks/spacings/{0}.pickle".format(imname2), 'rb') as handle:
                    dic = pickle.load(handle)
                    origin = dic["origin"]
                    spacing = dic["spacing"]

            imname = imname2
            nrimages +=1

        for center in centers:
            coords = voxel_2_world([int(slice),center[1]+(512-324)*0.5,center[0]+(512-324)*0.5],origin,spacing)
            data.append([imname2,coords[2],coords[1],coords[0],'?'])

        #if nrimages == 5:
        #    break

    df = pd.DataFrame(data,columns=CANDIDATES_COLUMNS)
    save_candidates("../data/candidates_unet_final_23.csv",df)
def process(filename, plot=False):
    # read in image filename
    imagepath = os.path.join(os.getcwd(), filename)
    orig_img = io.imread(filename,True,'pil')
    # binarize image
    img = orig_img > 0.9 # binary threshold
    # convert to grayscale (easier for viewing)
    img = rgb2gray(img)
    imshow(img)
    # use erosion to expland black areas in the document. This will
    # group together small text and make it easier to find contours
    # of signatures, which are usually separated from text
    eroded_img = binary_erosion(img,rectangle(30,10))
    # get contours of eroded image
    contours, lengths = compute_contours(eroded_img)
    # compute X and Y gradients over the contours. We expect that signatures
    # will have have a constant gradient that is close to the length of
    # the contour. We take the sum of the X-gradient to remove contours
    # that are vertically biased
    c_grad_x = map(lambda x: np.gradient(x[:,1]), contours)
    c_grad_y = map(lambda x: np.gradient(x[:,0]), contours)
    stuffs = []
    for i,(x,y) in enumerate(zip(c_grad_x,c_grad_y)):
        stuffs.append( (sum(map(abs, x)), len(x)) )
    d = pd.DataFrame.from_records(stuffs)
    d['diff'] = abs(d[0] - d[1])
    d = d[d['diff'] > d['diff'].mean()]
    contours = [contours[i] for i in d.index]
    # compute bounding boxes for resulting contours
    boxes = get_boundingboxes(contours)
    # given a box, does sobel on the bounding box of that block
    # computes contours within the subimage and returns them
    def process_block(box):
        mask = get_mask_from_boundingbox(img,box)
        sobel_img = sobel(img,mask)
        contours, lengths = compute_contours(sobel_img)
        return len(contours),contours,lengths
    # get all blocks
    blocks = [process_block(box) for box in boxes]
    # retrieve the blocks that have the fewest number of contours
    num_contours = pd.Series(block[0] for block in blocks)
    num_contours = num_contours[num_contours < num_contours.mean()]
    # plot only those contours
    ret_contours = []
    for block in [blocks[i] for i in num_contours.index]:
        len_con,contours,lengths = block
        lengths = pd.Series(lengths)
        lengths = lengths[lengths > lengths.mean()]
        for i in lengths.index:
            contour = contours[i]
            ret_contours.append(contour)
            plt.plot(contour[:,1],contour[:,0])
    return ret_contours
Esempio n. 27
0
def erode(infile):
    """ use skimage.morphology to quickly erode binary mask"""
    img = nibabel.load(infile)
    dat = img.get_data().squeeze()
    kernel = np.zeros((3,3,3))
    kernel[1,:,:] = 1
    kernel[:,1,:] = 1
    kernel[:,:,1] = 1
    eroded = binary_erosion(dat, kernel)
    eroded = eroded.astype(int)
    newfile = filemanip.fname_presuffix(infile, 'e')
    newimg = nibabel.Nifti1Image(eroded, img.get_affine())
    newimg.to_filename(newfile)
    return newfile
Esempio n. 28
0
def create_mask(frame):
    """"Create a big mask that encompasses all the cells"""
    
    # detect ridges
    ridges = enhance_ridges(frame)

    # threshold ridge image
    thresh = filters.threshold_otsu(ridges)
    thresh_factor = 1.1
    prominent_ridges = ridges > thresh_factor*thresh
    prominent_ridges = morphology.remove_small_objects(prominent_ridges, min_size=128)

    # the mask contains the prominent ridges
    mask = morphology.convex_hull_image(prominent_ridges)
    mask = morphology.binary_erosion(mask, disk(10))
    return mask
Esempio n. 29
0
def erode(infile):
    """ use skimage.morphology to quickly erode binary mask"""
    img = nibabel.load(infile)
    dat = img.get_data().squeeze()
    ## make kernel
    tmp = np.diag([0,1,0])
    mid = np.zeros((3,3))
    mid[1,:] = 1
    mid[:,1] = 1
    kernel = np.hstack((tmp, mid, tmp))
    kernel.shape = (3,3,3)
    ## erode with kernel
    eroded = binary_erosion(dat, kernel)
    eroded = eroded.astype(int)
    newfile = filemanip.fname_presuffix(infile, 'e')
    newimg = nibabel.Nifti1Image(eroded, img.get_affine())
    newimg.to_filename(newfile)
    return newfile
Esempio n. 30
0
def erode(image, struct=None):
    """
    Erode edges of white phase.

    :param image: data
    :type image: :py:class:`numpy.ndarray`

    :type struct: :py:class:`numpy.ndarray`
    :type struct: :py:class:`numpy.ndarray`

    :return: modified image data
    :rtype: :py:class:`numpy.ndarray`
    """
    if not struct:
        struct = morphology.disk(1)

    i = morphology.binary_erosion(image, struct)

    return i > i.mean()
Esempio n. 31
0
def setup_stress_field(mask,
                       distribution="uniform",
                       sigma_n=1,
                       sigma_shear=0,
                       sigma_gf=4,
                       diameter_gf=4):
    mask = mask.astype(bool)
    sigma_x = np.zeros(mask.shape)
    sigma_y = np.zeros(mask.shape)
    sigma_xy = np.zeros(mask.shape)

    if distribution == "uniform":
        sigma_x[binary_erosion(
            mask
        )] = sigma_n  # binary errosion because boundary effects of gradient
        sigma_y[binary_erosion(mask)] = sigma_n
        sigma_xy[binary_erosion(mask)] = sigma_shear
    if distribution == "gaussian_flattened_circle":
        center = regionprops(mask.astype(int))[0].centroid
        shape_length = regionprops(mask.astype(int))[0].equivalent_diameter
        circ = circle(center[0], center[1], radius=shape_length / diameter_gf)
        sigma_x[circ] = 1
        sigma_y[circ] = 1
        sigma_x = gaussian_filter(sigma_x, sigma=sigma_gf)
        sigma_y = gaussian_filter(sigma_y, sigma=sigma_gf)
        sigma_x[~mask] = 0
        sigma_y[~mask] = 0
        # normalizing to get sum on mean of stress of at each pixel to 1
        sigma_x[mask] = (sigma_x[mask] / (np.sum(sigma_x[mask])) *
                         np.sum(mask))
        sigma_y[mask] = (sigma_y[mask] / (np.sum(sigma_y[mask])) *
                         np.sum(mask))
        # sigma_x[binary_erosion(mask)] = sigma_n  # binary errosion because boundary effects of gradient
        # sigma_y[binary_erosion(mask)] = sigma_n

    if distribution == "gaussian_flattened_rectangle":
        sigma_x[binary_erosion(mask, iterations=diameter_gf)] = 1
        sigma_y[binary_erosion(mask, iterations=diameter_gf)] = 1
        sigma_x = gaussian_filter(sigma_x, sigma=sigma_gf)
        sigma_y = gaussian_filter(sigma_y, sigma=sigma_gf)
        sigma_x[~mask] = 0
        sigma_y[~mask] = 0
        # normalizing to get sum on mean of stress of at each pixel to 1
        sigma_x[mask] = (sigma_x[mask] / (np.sum(sigma_x[mask])) *
                         np.sum(mask))
        sigma_y[mask] = (sigma_y[mask] / (np.sum(sigma_y[mask])) *
                         np.sum(mask))
        # sigma_x[binary_erosion(mask)] = sigma_n  # binary errosion because boundary effects of gradient
        # sigma_y[binary_erosion(mask)] = sigma_n

    if distribution == "gaussian":
        center = regionprops(mask.astype(int))[0].centroid
        sigma_x[int(center[0]), int(center[1])] = 1
        sigma_y[int(center[0]), int(center[1])] = 1
        sigma_x = gaussian_filter(sigma_x, sigma=sigma_gf)
        sigma_y = gaussian_filter(sigma_y, sigma=sigma_gf)
        mask = mask.astype(bool)
        sigma_x[~mask] = 0
        sigma_y[~mask] = 0
        # normalizing to get sum on mean of stress of at each pixel to 1
        sigma_x[mask] = (sigma_x[mask] / (np.sum(sigma_x[mask])) *
                         np.sum(mask))
        sigma_y[mask] = (sigma_y[mask] / (np.sum(sigma_y[mask])) *
                         np.sum(mask))
        # sigma_x[binary_erosion(mask)] = sigma_n  # binary errosion because boundary effects of gradient
        # sigma_y[binary_erosion(mask)] = sigma_n

    stress_tensor = np.zeros((mask.shape[0], mask.shape[1], 2, 2))
    stress_tensor[:, :, 0, 0] = sigma_x
    stress_tensor[:, :, 0, 1] = sigma_xy
    stress_tensor[:, :, 1, 0] = sigma_xy
    stress_tensor[:, :, 1, 1] = sigma_y

    return stress_tensor
def get_segmented_lungs(raw_im):
    '''
    对肺部CT图像实现实质
    This funtion segments the lungs from the given 2D slice.
    :param raw_im: 输入原始图像
    :return: binaty 二值图掩码 ,im 原始图像叠加二值图掩码后结果
    '''
    im = raw_im.copy()
    '''
    将2D Slice转为二值图
    Step 1: Convert into a binary image. 
    '''
    binary = im < -567.5
    # binary = im < -500
    # thresh = threshold_otsu(binary)
    # binary = binary > thresh
    '''
    删除连接到图像边界的噪点。
    Step 2: Remove the blobs connected to the border of the image.
    '''
    cleared = clear_border(binary)
    '''
    标记图像
    Step 3: Label the image.
    '''
    label_image = label(cleared)
    '''
    保持标记有两个最大的区域
    Step 4: Keep the labels with 2 largest areas.
    '''
    areas = [r.area for r in regionprops(label_image)]
    areas.sort()
    if len(areas) > 2:
        for region in regionprops(label_image):
            if region.area < areas[-2]:
                for coordinates in region.coords:
                    label_image[coordinates[0], coordinates[1]] = 0
    binary = label_image > 0
    '''
    半径为2 pixels,腐蚀操作。
    Step 5: Erosion operation with a disk of radius 2. This operation is 
    seperate the lung nodules attached to the blood vessels.
    '''
    selem = disk(2)
    binary = binary_erosion(binary, selem)
    '''
    半径为10 pixels,闭合操作。
    Step 6: Closure operation with a disk of radius 10. This operation is 
    to keep nodules attached to the lung wall.
    '''
    selem = disk(7)
    binary = binary_closing(binary, selem)
    '''
    将二值图中的部分噪点填充。
    Step 7: Fill in the small holes inside the binary mask of lungs.
    '''
    edges = roberts(binary)
    binary = ndimage.binary_fill_holes(edges)
    '''
    在输入图像上叠加二进制掩码。
    Step 8: Superimpose the binary mask on the input image.
    '''
    get_high_vals = binary == 0
    im[get_high_vals] = 0

    return binary, im
Esempio n. 33
0
def deepcell_transform(maskstack, dilation_radius=None, data_format=None):
    """
    Transforms a label mask for a z stack edge, interior, and background
    # Arguments:
        maskstack: label masks of uniquely labeled instances
        dilation_radius:  width to enlarge the edge feature of each instance
    # Returns:
        deepcell_stacks: masks of:
        [background_edge_feature, interior_edge_feature, interior_feature, background]
    """
    if data_format is None:
        data_format = K.image_data_format()

    if data_format == 'channels_first':
        channel_axis = 1
    else:
        channel_axis = len(maskstack.shape) - 1

    maskstack = np.squeeze(maskstack, axis=channel_axis)

    # Detect the edges and interiors
    new_masks = np.zeros(maskstack.shape)
    edge_masks = np.zeros(maskstack.shape)
    strel = ball(1) if maskstack.ndim > 3 else disk(1)
    for cell_label in np.unique(maskstack):
        if cell_label != 0:
            for i in range(maskstack.shape[0]):
                # get the cell interior
                img = maskstack[i] == cell_label
                img = binary_erosion(img, strel)
                new_masks[i] += img

    interior_masks = np.multiply(new_masks, maskstack)
    edge_masks = (maskstack - interior_masks > 0).astype('int')
    interior_masks = (interior_masks > 0).astype('int')

    # dilate the background masks and subtract from all edges for background-edges
    dilated_background = np.zeros(maskstack.shape)
    for i in range(maskstack.shape[0]):
        background = (maskstack[i] == 0).astype('int')
        dilated_background[i] = binary_dilation(background, strel)

    background_edge_masks = (edge_masks - dilated_background > 0).astype('int')

    # edges that are not background-edges are interior-edges
    interior_edge_masks = (edge_masks - background_edge_masks > 0).astype('int')

    if dilation_radius:
        dil_strel = ball(dilation_radius) if maskstack.ndim > 3 else disk(dilation_radius)
        # Thicken cell edges to be more pronounced
        for i in range(edge_masks.shape[0]):
            interior_edge_masks[i] = binary_dilation(interior_edge_masks[i], selem=dil_strel)
            background_edge_masks[i] = binary_dilation(background_edge_masks[i], selem=dil_strel)

        # Thin the augmented edges by subtracting the interior features.
        interior_edge_masks = (interior_edge_masks - interior_masks > 0).astype('int')
        background_edge_masks = (background_edge_masks - interior_masks > 0).astype('int')

    background_masks = (1 - background_edge_masks - interior_edge_masks - interior_masks > 0)
    background_masks = background_masks.astype('int')

    all_stacks = [
        background_edge_masks,
        interior_edge_masks,
        interior_masks,
        background_masks
    ]

    deepcell_stacks = np.stack(all_stacks, axis=channel_axis)
    return deepcell_stacks
Esempio n. 34
0
def get_segmentation_mask(im, z=-1, plot=False, savefig=False):
    '''
    This funtion segments the lungs from a given 2D slice.
    '''

    if plot == True:
        f, plots = plt.subplots(8, 1, figsize=(5, 40))
    '''
    Step 1: Convert into a binary image. 
    '''
    #binary = im < 604
    binary = im < -400
    if plot == True:
        plots[0].axis('off')
        plots[0].imshow(binary, cmap=plt.cm.bone)
    '''
    Step 2: Remove the blobs connected to the border of the image.
    '''
    cleared = clear_border(binary)
    if plot == True:
        plots[1].axis('off')
        plots[1].imshow(cleared, cmap=plt.cm.bone)
    '''
    Step 3: Label the image.
    '''
    label_image = label(cleared)
    if plot == True:
        plots[2].axis('off')
        plots[2].imshow(label_image, cmap=plt.cm.bone)
    '''
    Step 4: Keep the labels with 2 largest areas.
    '''
    areas = [r.area for r in regionprops(label_image)]
    areas.sort()
    if len(areas) > 2:
        for region in regionprops(label_image):
            if region.area < areas[-2]:
                for coordinates in region.coords:
                    label_image[coordinates[0], coordinates[1]] = 0
    binary = label_image > 0
    if plot == True:
        plots[3].axis('off')
        plots[3].imshow(binary, cmap=plt.cm.bone)
    '''
    Step 5: Erosion operation with a disk of radius 2. This operation is 
    seperate the lung nodules attached to the blood vessels.
    '''
    selem = disk(2)
    binary = binary_erosion(binary, selem)
    if plot == True:
        plots[4].axis('off')
        plots[4].imshow(binary, cmap=plt.cm.bone)
    '''
    Step 6: Closure operation with a disk of radius 10. This operation is 
    to keep nodules attached to the lung wall.
    '''
    selem = disk(10)
    binary = binary_closing(binary, selem)
    if plot == True:
        plots[5].axis('off')
        plots[5].imshow(binary, cmap=plt.cm.bone)
    '''
    Step 7: Fill in the small holes inside the binary mask of lungs.
    '''
    edges = roberts(binary)
    binary = ndi.binary_fill_holes(edges)
    if plot == True:
        plots[6].axis('off')
        plots[6].imshow(binary, cmap=plt.cm.bone)

    if savefig:
        print 'test_' + str(z) + '.jpg'
        plt.savefig('test_' + str(z) + '.jpg')

    return binary
def estimate(image, expected_position=None, search_rect=None, search_rect_border=0.05, expected_pixels=(10, 200), optimal_size=90, visualize=False):
    downscale_factor = 1 # legacy stuff
    h, w = image.shape[0:2]

    if search_rect is not None:
        x1, y1, x2, y2 = search_rect[0], search_rect[1], search_rect[2], search_rect[3]
        if search_rect_border > 0:
            clip = np.clip
            bx = int(w * search_rect_border)
            by = int(h * search_rect_border)
            x1 = clip(x1 - bx, 0, w-2)
            y1 = clip(y1 - by, 0, h-2)
            x2 = clip(x2 + bx, x1, w-1)
            y2 = clip(y2 + by, y1, h-1)
    else:
        # full wheel: x1=440, x2=870, y1=440, y2=720
        # wheel w=440, h=270
        x1 = int(w * (480/1280))
        x2 = int(w * (830/1280))
        y1 = int(h * (520/720))
        y2 = int(h * (720/720))
    rect_h = y2 - y1
    rect_w = x2 - x1

    if expected_position is None:
        expected_position = (
            int(w * (646/1280)),
            int(h * (684/720))
        )

    img_wheel = image[y1:y2+1, x1:x2+1, :]
    img_wheel_rs = img_wheel
    img_wheel_rsy = cv2.cvtColor(img_wheel_rs, cv2.COLOR_RGB2GRAY)
    expected_position_rs = (
        int((expected_position[0]-x1) * downscale_factor),
        int((expected_position[1]-y1) * downscale_factor)
    )

    #thresh_mask = filters.threshold_li(img_wheel_rsy)
    thresh_mask = filters.threshold_isodata(img_wheel_rsy)
    thresh = img_wheel_rsy > thresh_mask #40
    #cv2.imshow("thresh", thresh.astype(np.uint8)*255)
    #cv2.waitKey(10)
    thresh = morphology.binary_dilation(thresh, morphology.square(3))

    img_labeled, num_labels = morphology.label(
        thresh, background=0, connectivity=1, return_num=True
    )

    segments = []
    for label in range(1, num_labels+1):
        img_seg = (img_labeled == label)
        (yy, xx) = np.nonzero(img_seg)

        # size of correct segment is around 60 pixels without dilation and 90 with dilation
        # position is at around x=21, y=13
        # (both numbers for screenshots after jpg-compression/decompression at 1/4 the original
        # size, i.e. 1280/4 x 720/4)
        if expected_pixels[0] <= len(yy) <= expected_pixels[1]:
            center_x = np.average(xx)
            center_y = np.average(yy)

            # euclidean distance to expected position
            # segments which's center is at the expected position get a 0
            # segments which a further away get higher values
            dist_pos = 0.1 * math.sqrt((center_x - expected_position_rs[0]) ** 2 + (center_y - expected_position_rs[1])**2)

            # distance to optimal size (number of pixels)
            # segments that have the same number of pixels as the expected size
            # get a 0, segments with 50pecent more/less pixels get a 0
            dist_size = np.clip(
                1/(optimal_size*0.5) * abs(len(yy) - optimal_size),
                0, 1
            )
            dist = dist_pos + dist_size

            segments.append({
                "xx": xx,
                "yy": yy,
                "center_x": center_x,
                "center_y": center_y,
                "dist_pos": dist_pos,
                "dist_size": dist_size,
                "dist": dist,
                "img_seg": img_seg
            })

    if len(segments) == 0:
        return (None, None) if visualize else None

    segments = sorted(segments, key=lambda d: d["dist"])
    best_match = segments[0]
    xx = x1 + (best_match["xx"].astype(np.float32) * (1/downscale_factor)).astype(np.int32)
    yy = y1 + (best_match["yy"].astype(np.float32) * (1/downscale_factor)).astype(np.int32)

    image_segment = best_match["img_seg"]
    image_segment = morphology.binary_erosion(image_segment, morphology.square(3))

    cx, cy = int(best_match["center_x"]), int(best_match["center_y"])
    sy, sx = 10, 10
    hx1 = np.clip(cx - sx, 0, image_segment.shape[1])
    hx2 = np.clip(cx + sx + 1, 0, image_segment.shape[1])
    hy1 = np.clip(cy - sy, 0, image_segment.shape[0])
    hy2 = np.clip(cy + sy + 1, 0, image_segment.shape[0])
    hough_segment = image_segment[hy1:hy2, hx1:hx2]
    h, theta, d = hough_line(hough_segment)
    if len(h) == 0:
        return (None, None) if visualize else None

    hspaces, angles, dists = hough_line_peaks(h, theta, d, num_peaks=1)
    if len(hspaces) == 0:
        return (None, None) if visualize else None

    hspace, angle, dist = hspaces[0], angles[0], dists[0]
    line_y0 = (dist - 0 * np.cos(angle)) / np.sin(angle)
    line_y1 = (dist - hough_segment.shape[1] * np.cos(angle)) / np.sin(angle)
    slope = (line_y1 - line_y0) / (hx2 - hx1)

    left_x = cx - 3
    right_x = cx + 3
    left_y = cy + (-3) * slope
    right_y = cy + 3 * slope

    #print("x1 %d x2 %d y1 %d y2 %d | cx %d cy %d | hx1 %d hx2 %d hy1 %d hy2 %d | line_y0 %.2f line_y1 %.2f | left_x %d right_x %d left_y %d right_y %d | hs %s | is %s" % (
    #    x1, x2, y1, y2, cx, cy, hx1, hx2, hy1, hy2, line_y0, line_y1, left_x, right_x, left_y, right_y, hough_segment.shape, image_segment.shape
    #))

    #fig, ax = plt.subplots(1, 1, figsize=(5, 5))
    #ax.imshow(image_segment, cmap=plt.cm.gray)
    #ax.plot([left_x, right_x], [left_y, right_y], "-r")
    #plt.show()

    best_match["min_x"] = int(np.min(xx))
    best_match["max_x"] = int(np.max(xx))
    best_match["min_y"] = int(np.min(yy))
    best_match["max_y"] = int(np.max(yy))
    best_match["center_x"] = x1 + (best_match["center_x"] * (1/downscale_factor))
    best_match["center_y"] = y1 + (best_match["center_y"] * (1/downscale_factor))
    best_match["left_x"] = x1 + (left_x * (1/downscale_factor))
    best_match["right_x"] = x1 + (right_x * (1/downscale_factor))
    best_match["left_y"] = y1 + (left_y * (1/downscale_factor))
    best_match["right_y"] = y1 + (right_y * (1/downscale_factor))

    if visualize:
        upf = 2
        image_viz = ia.imresize_single_image(np.copy(image), (image.shape[0]*upf, image.shape[1]*upf))
        image_viz = util.draw_point(image_viz, x=int(x1)*upf, y=int(y1)*upf, size=7, color=[255, 0, 0])
        image_viz = util.draw_point(image_viz, x=(int(x2)-1)*upf, y=int(y1)*upf, size=7, color=[255, 0, 0])
        image_viz = util.draw_point(image_viz, x=(int(x2)-1)*upf, y=(int(y2)-1)*upf, size=7, color=[255, 0, 0])
        image_viz = util.draw_point(image_viz, x=int(x1)*upf, y=(int(y2)-1)*upf, size=7, color=[255, 0, 0])
        image_viz = util.draw_point(image_viz, x=int(expected_position[0])*upf, y=int(expected_position[1])*upf, size=7, color=[0, 0, 255])
        image_viz = util.draw_point(image_viz, x=best_match["min_x"]*upf, y=best_match["min_y"]*upf, size=7, color=[128, 0, 0])
        image_viz = util.draw_point(image_viz, x=(best_match["max_x"]-1)*upf, y=best_match["min_y"]*upf, size=7, color=[128, 0, 0])
        image_viz = util.draw_point(image_viz, x=(best_match["max_x"]-1)*upf, y=(best_match["max_y"]-1)*upf, size=7, color=[128, 0, 0])
        image_viz = util.draw_point(image_viz, x=best_match["min_x"]*upf, y=(best_match["max_y"]-1)*upf, size=7, color=[128, 0, 0])
        image_viz = util.draw_point(image_viz, x=int(best_match["center_x"])*upf, y=int(best_match["center_y"])*upf, size=7, color=[0, 0, 128])
        image_viz = util.draw_point(image_viz, x=int(best_match["left_x"])*upf, y=int(best_match["left_y"])*upf, size=7, color=[0, 255, 0])
        image_viz = util.draw_point(image_viz, x=int(best_match["right_x"])*upf, y=int(best_match["right_y"])*upf, size=7, color=[0, 128, 0])
        return best_match, image_viz
    else:
        return best_match
Esempio n. 36
0
def find_peaks_by_snr(image,
                      center,
                      mask=None,
                      gaussian_sigma=1.,
                      min_gradient=0.,
                      min_distance=1,
                      merge_flat_peaks=False,
                      max_peaks=500,
                      min_snr=0.,
                      min_pixels=2,
                      max_pixels=10,
                      refine_mode='mean',
                      snr_mode='rings',
                      signal_radius=1,
                      bg_inner_radius=2,
                      bg_outer_radius=3,
                      crop_size=7,
                      bg_ratio=0.7,
                      signal_ratio=0.2,
                      signal_thres=5.,
                      label_pixels=False):
    peaks_dict = {}
    if mask is not None:
        raw_image = image * mask
    else:
        raw_image = image.copy()
    if gaussian_sigma >= 0:
        image = gaussian_filter(image.astype(np.float32), gaussian_sigma)
    grad = np.gradient(image.astype(np.float32))
    grad_mag = np.sqrt(grad[0]**2. + grad[1]**2.)
    if mask is None:
        labels = None
    else:
        labels = binary_erosion(mask, disk(2)).astype(np.int)
    raw_peaks = peak_local_max(grad_mag,
                               exclude_border=5,
                               min_distance=min_distance,
                               threshold_abs=min_gradient,
                               num_peaks=max_peaks,
                               labels=labels)
    raw_peaks = np.reshape(raw_peaks, (-1, 2))
    if merge_flat_peaks:
        # do hierarchy clustering to remove flat peaks
        link = hierarchy.linkage(raw_peaks, method='single')
        r = hierarchy.cut_tree(link, height=min_distance)
        clusters = []
        for i in np.unique(r):
            clusters.append(raw_peaks[r[:, 0] == i].mean(axis=0))
        raw_peaks = np.array(clusters).reshape(-1, 2)

    peaks_dict['raw'] = raw_peaks
    if len(raw_peaks) == 0:
        return peaks_dict

    valid_peaks = np.reshape(raw_peaks, (-1, 2))
    peaks_dict['valid'] = valid_peaks

    # refine peak location
    opt_peaks = refine_peaks(raw_image, valid_peaks, mode=refine_mode)
    peaks_dict['opt'] = opt_peaks
    snr_info = calc_snr(
        raw_image,
        opt_peaks,
        mode=snr_mode,
        signal_radius=signal_radius,
        bg_inner_radius=bg_inner_radius,
        bg_outer_radius=bg_outer_radius,
        crop_size=crop_size,
        bg_ratio=bg_ratio,
        signal_ratio=signal_ratio,
        signal_thres=signal_thres,
        label_pixels=label_pixels,
    )
    strong_ids = np.where((snr_info['snr'] >= min_snr) *
                          (snr_info['signal pixel num'] >= min_pixels) *
                          (snr_info['signal pixel num'] <= max_pixels))[0]
    strong_peaks = opt_peaks[strong_ids]
    peaks_dict['strong'] = strong_peaks
    radius = np.linalg.norm(strong_peaks - center, axis=1)
    peaks_dict['info'] = {
        'pos': strong_peaks,
        'snr': snr_info['snr'][strong_ids],
        'total intensity': snr_info['total intensity'][strong_ids],
        'signal values': snr_info['signal values'][strong_ids],
        'background values': snr_info['background values'][strong_ids],
        'noise values': snr_info['noise values'][strong_ids],
        'signal pixel num': snr_info['signal pixel num'][strong_ids],
        'background pixel num': snr_info['background pixel num'][strong_ids],
        'radius': radius,
    }
    return peaks_dict
Esempio n. 37
0
            counter += 1
        else:
            if table_height < counter:
                table_height = counter
                i_max = i
            counter = 0

table_weight = 0

canny_edge_map = binary_closing(canny(matchimg, sigma=2.5),
                                selem=np.ones((4, 4)))

# поставим маркеры фона и объекта
markers = np.zeros_like(matchimg)
markers[0:10, 0:10] = 1  # маркеры фона
markers[binary_erosion(canny_edge_map) >
        0] = 2  # маркеры объекта - точки, находящиеся заведомо внутри

sobel_gradient = sobel(matchimg)
matchimg_region_segmentation = watershed(sobel_gradient, markers)

ax[0].imshow(matchimg_region_segmentation)
ax[1].imshow(
    label2rgb(matchimg_region_segmentation, image=matchimg, bg_label=-1))

ax[2].imshow(mask)

table_weight = 0
# Рассмотрим полосу в месте, где найдем высота и найдем максимальную ширину,
# она и будет являться шириной стола
def get_segmented_lungs(im, plot=False):	# im: numpy array of 2D
    
    '''
    This funtion segments the lungs from the given 2D slice.
    '''
    if plot == True:
        f, plots = plt.subplots(8, 1, figsize=(5, 40))
    '''
    Step 1: Convert into a binary image. 
    '''
    binary = im < 604	# numpy array
    if plot == True:
        plots[0].axis('off')
        plots[0].imshow(binary, cmap=plt.cm.bone) 
    '''
    Step 2: Remove the blobs connected to the border of the image.
    '''
    cleared = clear_border(binary)
    if plot == True:
        plots[1].axis('off')
        plots[1].imshow(cleared, cmap=plt.cm.bone) 
    '''
    Step 3: Label the image.
    '''
    label_image = label(cleared)
    if plot == True:
        plots[2].axis('off')
        plots[2].imshow(label_image, cmap=plt.cm.bone) 
    '''
    Step 4: Keep the labels with 2 largest areas.
    '''
    areas = [r.area for r in regionprops(label_image)]
    areas.sort()
    if len(areas) > 2:
        for region in regionprops(label_image):
            if region.area < areas[-2]:
                for coordinates in region.coords:                
                       label_image[coordinates[0], coordinates[1]] = 0
    binary = label_image > 0
    if plot == True:
        plots[3].axis('off')
        plots[3].imshow(binary, cmap=plt.cm.bone) 
    '''
    Step 5: Erosion operation with a disk of radius 2. This operation is 
    seperate the lung nodules attached to the blood vessels.
    '''
    selem = disk(2)
    binary = binary_erosion(binary, selem)
    if plot == True:
        plots[4].axis('off')
        plots[4].imshow(binary, cmap=plt.cm.bone) 
    '''
    Step 6: Closure operation with a disk of radius 10. This operation is 
    to keep nodules attached to the lung wall.
    '''
    selem = disk(10)
    binary = binary_closing(binary, selem)
    if plot == True:
        plots[5].axis('off')
        plots[5].imshow(binary, cmap=plt.cm.bone) 
    '''
    Step 7: Fill in the small holes inside the binary mask of lungs.
    '''
    edges = roberts(binary)
    binary = ndi.binary_fill_holes(edges)
    if plot == True:
        plots[6].axis('off')
        plots[6].imshow(binary, cmap=plt.cm.bone) 
    '''
    Step 8: Superimpose the binary mask on the input image.
    '''
    get_high_vals = binary == 0
    im[get_high_vals] = 0
    if plot == True:
        plots[7].axis('off')
        plots[7].imshow(im, cmap=plt.cm.bone) 
        
    return im 	# numpy array
Esempio n. 39
0
    def generate(self, annot_dict):
        '''
        Create masks from annotation dictionary

        Args:
            annot_dict (dictionary): dictionary with annotations

        Returns:
            mask_dict (dictionary): dictionary with masks
        '''

        # Get dimensions of image and created masks of same size
        # This we need to save somewhere (e.g. as part of the geojson file?)

        # Filled masks and edge mask for polygons
        mask_fill = np.zeros(self.image_size, dtype=np.uint8)
        mask_edge = np.zeros(self.image_size, dtype=np.uint8)

        rr_all = []
        cc_all = []

        if self.save_indiv is True:
            mask_edge_indiv = np.zeros(
                (self.image_size[0], self.image_size[1], len(annot_dict)),
                dtype=np.bool)
            mask_fill_indiv = np.zeros(
                (self.image_size[0], self.image_size[1], len(annot_dict)),
                dtype=np.bool)

        # Image used to draw lines - for edge mask for freelines
        #im_freeline = Image.new('1', self.image_size, color=0)
        im_freeline = Image.new('1', (self.image_size[1], self.image_size[0]),
                                color=0)
        draw = ImageDraw.Draw(im_freeline)

        # Loop over all roi
        i_roi = 0
        for roi_key, roi in annot_dict.items():
            roi_pos = roi['pos']

            # Check region type

            # freeline - line
            if roi['type'] == 'freeline' or roi['type'] == 'LineString':

                # Loop over all pairs of points to draw the line

                for ind in range(roi_pos.shape[0] - 1):
                    line_pos = ((roi_pos[ind, 1], roi_pos[ind, 0],
                                 roi_pos[ind + 1, 1], roi_pos[ind + 1, 0]))
                    draw.line(line_pos, fill=1, width=self.erose_size)

            # freehand - polygon
            elif roi['type'] == 'freehand' or roi['type'] == 'polygon' or roi[
                    'type'] == 'polyline' or roi['type'] == 'Polygon':

                # Draw polygon
                rr, cc = skimage_draw.polygon(roi_pos[:, 0], roi_pos[:, 1])

                # Make sure it's not outside
                rr[rr < 0] = 0
                rr[rr > self.image_size[0] - 1] = self.image_size[0] - 1

                cc[cc < 0] = 0
                cc[cc > self.image_size[0] - 1] = self.image_size[0] - 1

                # Test if this region has already been added
                if any(np.array_equal(rr, rr_test)
                       for rr_test in rr_all) and any(
                           np.array_equal(cc, cc_test) for cc_test in cc_all):
                    # print('Region #{} has already been used'.format(i +
                    # 1))
                    continue

                rr_all.append(rr)
                cc_all.append(cc)

                # Generate mask
                mask_fill_roi = np.zeros(self.image_size, dtype=np.uint8)
                mask_fill_roi[rr, cc] = 1

                # Erode to get cell edge - both arrays are boolean to be used as
                # index arrays later
                mask_fill_roi_erode = morphology.binary_erosion(
                    mask_fill_roi, np.ones((self.erose_size, self.erose_size)))
                mask_edge_roi = (
                    mask_fill_roi.astype('int') -
                    mask_fill_roi_erode.astype('int')).astype('bool')

                # Save array for mask and edge
                mask_fill[mask_fill_roi_erode] = 1
                mask_edge[mask_edge_roi] = 1

                if self.save_indiv is True:
                    mask_edge_indiv[:, :, i_roi] = mask_edge_roi.astype('bool')
                    mask_fill_indiv[:, :,
                                    i_roi] = mask_fill_roi_erode.astype('bool')
                    i_roi = i_roi + 1

            else:
                roi_type = roi['type']
                raise NotImplementedError(
                    f'Mask for roi type "{roi_type}" can not be created')

        del draw

        # Convert mask from free-lines to numpy array
        mask_edge_freeline = np.asarray(im_freeline)
        mask_edge_freeline = mask_edge_freeline.astype('bool')

        # Post-processing of fill and edge mask - if defined
        mask_dict = {}
        if np.any(mask_fill):

            # (1) remove edges , (2) remove small  objects
            mask_fill = mask_fill & ~mask_edge
            mask_fill = morphology.remove_small_objects(
                mask_fill.astype('bool'), self.obj_size_rem)

            # For edge - consider also freeline edge mask

            mask_edge = mask_edge.astype('bool')
            mask_edge = np.logical_or(mask_edge, mask_edge_freeline)

            # Assign to dictionary for return
            mask_dict['edge'] = mask_edge
            mask_dict['fill'] = mask_fill.astype('bool')

            if self.save_indiv is True:
                mask_dict['edge_indiv'] = mask_edge_indiv
                mask_dict['fill_indiv'] = mask_fill_indiv
            else:
                mask_dict['edge_indiv'] = np.zeros(self.image_size + (1, ),
                                                   dtype=np.uint8)
                mask_dict['fill_indiv'] = np.zeros(self.image_size + (1, ),
                                                   dtype=np.uint8)

        # Only edge mask present
        elif np.any(mask_edge_freeline):
            mask_dict['edge'] = mask_edge_freeline
            mask_dict['fill'] = mask_fill.astype('bool')

            mask_dict['edge_indiv'] = np.zeros(self.image_size + (1, ),
                                               dtype=np.uint8)
            mask_dict['fill_indiv'] = np.zeros(self.image_size + (1, ),
                                               dtype=np.uint8)

        else:
            raise Exception('No mask has been created.')

        return mask_dict
Esempio n. 40
0
    def erode(self, size=1):
        """Erode the blob"""

        mask = self.getMask()
        eroded_mask = binary_erosion(mask, square(size))
        self.updateUsingMask(self.bbox, eroded_mask)
Esempio n. 41
0
 def time_erosion(self, shape, footprint, radius, *args):
     morphology.binary_erosion(self.image, self.footprint)
Esempio n. 42
0
def process(image):
    #show_images([image])
    image  = rgb2gray(image)

    if np.max(image) <= 1:
        image = image*255
    image = image.astype('uint8')

    y,x = image.shape

    newX = x + int(x/16)
    newY = y + int(x/16)
    tempIm = np.zeros([newY,newX], dtype='uint8')
    tempIm[int(x/16):newY, int(x/16):newX] = np.copy(image)
#################################################################
    outIm = np.zeros([newY,newX], dtype='uint8')
    adabtiveThreshold(tempIm, outIm, newX, newY)

    newIm = np.copy(outIm[int(x/16):newY, int(x/16):newX])
    newY, newX = newIm.shape
###############################################################
    #show_images([newIm])
    wind = np.ones(shape=(7,7))
    im = median(newIm)

    im2 = binary_dilation(im,wind)


    im2 = binary_erosion(im2,wind)
    im2 = im2.astype('uint8')
    im2 = im2*255

    #show_images([im2])

    z = horizontalProjection(im2[int(0.15*im2.shape[0]):int(0.6*im2.shape[0]),:])

    cut = z.index(np.max(z))
    cut = cut + int(0.15*im2.shape[0])


    segIm = np.copy(im2[cut:im.shape[0],:])
    segY, segX = segIm.shape

    #show_images([segIm])


    #========================= Removing borders using vertical and horizontal projections ===============
    borders = horizontalProjection(segIm[int(0.9*segY):segY,:])
    for i in range(len(borders)):
        if borders[i] >= int(0.2*segX):
            segIm[int(0.9*segY)+i,:] = 0

    borders = horizontalProjection(segIm[0:int(0.1*segY),:])
    for i in range(len(borders)):
        if borders[i] >= int(0.2*segX):
            segIm[i,:] = 0

    borders = verticalProjection(segIm[:,0:int(0.03*segX)])
    for i in range(len(borders)):
        if borders[i] >= int(0.2*segY):
            segIm[:,i] = 0

    borders = verticalProjection(segIm[:,int(0.97*segX):segX])
    for i in range(len(borders)):
        if borders[i] >= int(0.2*segY):
            segIm[:,int(0.97*segX)+i] = 0

    borders = verticalProjection(segIm[:,int(0.49*segX):int(0.52*segX)])
    for i in range(len(borders)):
        if borders[i] >= int(0.3*segY):
            segIm[:,int(0.49*segX)+i] = 0

    #([segIm])
    #==================================================================================================

    segImNumbers = np.copy(segIm[0:segY,0:int(0.5*segX)])
    segImLetters = np.copy(segIm[0:segY,int(0.5*segX):segX])

    segYN, segXN = segImNumbers.shape
    segYL, segXL = segImLetters.shape

    xnums = slice_digits(segImNumbers)
    xletrs =slice_digits(segImLetters)


    return xnums,xletrs
Esempio n. 43
0
def cubefit_gen(cube,
                ncomp=2,
                paraname=None,
                modname=None,
                chisqname=None,
                guesses=None,
                errmap11name=None,
                multicore=None,
                mask_function=None,
                snr_min=3.0,
                linename="oneone",
                momedgetrim=True,
                saveguess=False,
                **kwargs):
    '''
    Perform n velocity component fit on the GAS ammonia 1-1 data.
    (This should be the function to call for all future codes if it has been proven to be reliable)
    # note: the method can probably be renamed to cubefit()

    Parameters
    ----------
    cube : str
        The file name of the ammonia 1-1 cube or a SpectralCube object
    ncomp : int
        The number of components one wish to fit. Default is 2
    paraname: str
        The output file name of the
    Returns
    -------
    pcube : 'pyspeckit.cubes.SpectralCube.Cube'
        Pyspeckit cube object containing both the fit and the original data cube
    '''

    if hasattr(cube, 'spectral_axis'):
        pcube = pyspeckit.Cube(cube=cube)

    else:
        cubename = cube
        cube = SpectralCube.read(cubename)
        pcube = pyspeckit.Cube(filename=cubename)

    pcube.unit = "K"

    # the following check on rest-frequency may not be necessarily for GAS, but better be safe than sorry
    # note: this assume the data cube has the right units
    if cube._wcs.wcs.restfrq == np.nan:
        # Specify the rest frequency not present
        cube = cube.with_spectral_unit(u.Hz,
                                       rest_value=freq_dict[linename] * u.Hz)
    cube = cube.with_spectral_unit(u.km / u.s, velocity_convention='radio')

    if pcube.wcs.wcs.restfrq == np.nan:
        # Specify the rest frequency not present
        pcube.xarr.refX = freq_dict[linename] * u.Hz
    pcube.xarr.velocity_convention = 'radio'

    # always register the fitter just in case different lines are used
    fitter = ammv.nh3_multi_v_model_generator(n_comp=ncomp,
                                              linenames=[linename])
    pcube.specfit.Registry.add_fitter('nh3_multi_v', fitter, fitter.npars)
    print "number of parameters is {0}".format(fitter.npars)
    print "the line to fit is {0}".format(linename)

    # Specify a width for the expected velocity range in the data
    #v_peak_hwidth = 3.0 # km/s (should be sufficient for GAS Orion, but may not be enough for KEYSTONE)
    v_peak_hwidth = 4.0  # km/s (should be sufficient for GAS Orion, but may not be enough for KEYSTONE)

    if errmap11name is not None:
        errmap11 = fits.getdata(errmap11name)
    else:
        # a quick way to estimate RMS as long as the noise dominates the spectrum by channels
        mask_finite = np.isfinite(cube._data)
        errmap11 = mad_std(cube._data[mask_finite], axis=0)
        print "median rms: {0}".format(np.nanmedian(errmap11))

    snr = cube.filled_data[:].value / errmap11
    peaksnr = np.nanmax(snr, axis=0)

    #the snr map will inetiabley be noisy, so a little smoothing
    kernel = Gaussian2DKernel(1)
    peaksnr = convolve(peaksnr, kernel)

    # trim the edges by 3 pixels to guess the location of the peak emission
    footprint_mask = np.any(np.isfinite(cube._data), axis=0)

    if np.logical_and(footprint_mask.size > 1000, momedgetrim):
        print "triming the edges to make moment maps"
        footprint_mask = binary_erosion(footprint_mask, disk(3))

    # the following function is copied directly from GAS
    def default_masking(snr, snr_min=5.0):
        planemask = (snr > snr_min)
        if planemask.size > 100:
            planemask = remove_small_objects(planemask, min_size=40)
            planemask = opening(planemask, disk(1))
        return (planemask)

    if 'maskmap' in kwargs:
        planemask = kwargs['maskmap']
    elif mask_function is None:
        planemask = default_masking(peaksnr, snr_min=snr_min)
    else:
        planemask = mask_function(peaksnr, snr_min=snr_min)

    print "planemask size: {0}, shape: {1}".format(planemask[planemask].size,
                                                   planemask.shape)

    # masking
    mask = np.isfinite(cube._data) * planemask * footprint_mask

    print "mask size: {0}, shape: {1}".format(mask[mask].size, mask.shape)

    maskcube = cube.with_mask(mask.astype(bool))
    maskcube = maskcube.with_spectral_unit(u.km / u.s,
                                           velocity_convention='radio')

    if guesses is not None:
        v_guess = guesses[::4]
        v_guess[v_guess == 0] = np.nan
    else:
        v_guess = np.nan

    if np.isfinite(v_guess).sum() > 0:
        v_guess = v_guess[np.isfinite(v_guess)]
        v_median = np.median(v_guess)
        print "The median of the user provided velocities is: {0}".format(
            v_median)
        m0, m1, m2 = main_hf_moments(maskcube,
                                     window_hwidth=v_peak_hwidth,
                                     v_atpeak=v_median)
    else:
        m0, m1, m2 = main_hf_moments(maskcube, window_hwidth=v_peak_hwidth)
        v_median = np.median(m1[np.isfinite(m1)])
        print "median velocity: {0}".format(v_median)

        if False:
            # save the moment maps for diagnostic purposes
            hdr_new = copy.deepcopy(pcube.header)
            hdr_new['CDELT3'] = 1
            hdr_new['CTYPE3'] = 'FITPAR'
            hdr_new['CRVAL3'] = 0
            hdr_new['CRPIX3'] = 1

            savename = "{0}_moments.fits".format(
                os.path.splitext(paraname)[0], "parameter_maps")
            fitcubefile = fits.PrimaryHDU(data=np.array([m0, m1, m2]),
                                          header=hdr_new)
            fitcubefile.writeto(savename, overwrite=True)

    # remove the nana values to allow np.nanargmax(m0) to operate smoothly
    m0[np.isnan(
        m0
    )] = 0.0  # I'm not sure if this is a good way to get around the sum vs nansum issue

    # define acceptable v range based on the provided or determined median velocity
    vmax = v_median + v_peak_hwidth
    vmin = v_median - v_peak_hwidth

    # find the location of the peak signal (to determine the first pixel to fit if nearest neighbour method is used)
    peakloc = np.nanargmax(m0)
    ymax, xmax = np.unravel_index(peakloc, m0.shape)

    # set the fit parameter limits (consistent with GAS DR1)
    Texmin = 3.0  # K; a more reasonable lower limit (5 K T_kin, 1e3 cm^-3 density, 1e13 cm^-2 column, 3km/s sigma)
    Texmax = 40  # K; DR1 T_k for Orion A is < 35 K. T_k = 40 at 1e5 cm^-3, 1e15 cm^-2, and 0.1 km/s yields Tex = 37K
    sigmin = 0.07  # km/s
    sigmax = 2.5  # km/s; for Larson's law, a 10pc cloud has sigma = 2.6 km/s
    taumax = 100.0  # a reasonable upper limit for GAS data. At 10K and 1e5 cm^-3 & 3e15 cm^-2 -> 70
    taumin = 0.2  # note: at 1e3 cm^-3, 1e13 cm^-2, 1 km/s linewidth, 40 K -> 0.15
    eps = 0.001  # a small perturbation that can be used in guesses

    # get the guesses based on moment maps
    # tex and tau guesses are chosen to reflect low density, diffusive gas that are likley to have low SNR
    gg = moment_guesses(m1, m2, ncomp, sigmin=sigmin, moment0=m0)

    if guesses is None:
        guesses = gg

    else:
        # fill in the blanks with moment guesses
        guesses[guesses == 0] = np.nan
        gmask = np.isfinite(guesses)
        guesses[~gmask] = gg[~gmask]

        # fill in the failed sigma guesses with moment guesses
        gmask = guesses[1::4] < sigmin
        guesses[1::4][gmask] = gg[1::4][gmask]

        print "user provided guesses accepted"

    # The guesses should be fine in the first case, but just in case, make sure the guesses are confined within the
    # appropriate limits
    guesses[::4][guesses[::4] > vmax] = vmax
    guesses[::4][guesses[::4] < vmin] = vmin
    guesses[1::4][guesses[1::4] > sigmax] = sigmax
    guesses[1::4][guesses[1::4] < sigmin] = sigmin + eps
    guesses[2::4][guesses[2::4] > Texmax] = Texmax
    guesses[2::4][guesses[2::4] < Texmin] = Texmin
    guesses[3::4][guesses[3::4] > taumax] = taumax
    guesses[3::4][guesses[3::4] < taumin] = taumin

    if saveguess:
        # save the guesses for diagnostic purposes
        hdr_new = copy.deepcopy(pcube.header)
        hdr_new['CDELT3'] = 1
        hdr_new['CTYPE3'] = 'FITPAR'
        hdr_new['CRVAL3'] = 0
        hdr_new['CRPIX3'] = 1

        savedir = "{0}/{1}".format(path.dirname(paraname), "guesses")

        try:
            os.makedirs(savedir)
        except OSError as e:
            if e.errno != errno.EEXIST:
                raise

        savename = "{0}_guesses.fits".format(
            path.splitext(paraname)[0], "parameter_maps")
        savename = "{0}/{1}".format(savedir, path.basename(savename))

        fitcubefile = fits.PrimaryHDU(data=guesses, header=hdr_new)
        fitcubefile.writeto(savename, overwrite=True)

    # set some of the fiteach() inputs to that used in GAS DR1 reduction
    if not 'integral' in kwargs:
        kwargs['integral'] = False

    if not 'verbose_level' in kwargs:
        kwargs['verbose_level'] = 3

    if not 'signal_cut' in kwargs:
        kwargs['signal_cut'] = 2

    # Now fit the cube. (Note: the function inputs are consistent with GAS DR1 whenever possible)
    print('start fit')

    # use SNR masking if not provided
    if not 'maskmap' in kwargs:
        print "mask mask!"
        kwargs['maskmap'] = planemask * footprint_mask

    if np.sum(kwargs['maskmap']) < 1:
        print("[WARNING]: maskmap has no pixel, no fitting will be performed")
        return pcube
    elif np.sum(np.isfinite(guesses)) < 1:
        print("[WARNING]: guesses has no pixel, no fitting will be performed")
        return pcube

    pcube.fiteach(fittype='nh3_multi_v',
                  guesses=guesses,
                  start_from_point=(xmax, ymax),
                  use_neighbor_as_guess=False,
                  limitedmax=[True, True, True, True] * ncomp,
                  maxpars=[vmax, sigmax, Texmax, taumax] * ncomp,
                  limitedmin=[True, True, True, True] * ncomp,
                  minpars=[vmin, sigmin, Texmin, taumin] * ncomp,
                  multicore=multicore,
                  **kwargs)

    if paraname != None:
        save_pcube(pcube, paraname, ncomp=ncomp)

    if modname != None:
        model = SpectralCube(pcube.get_modelcube(),
                             pcube.wcs,
                             header=cube.header)
        model.write(modname, overwrite=True)

    if chisqname != None:
        chisq = get_chisq(cube, pcube.get_modelcube(), expand=20)
        chisqfile = fits.PrimaryHDU(data=chisq,
                                    header=cube.wcs.celestial.to_header())
        chisqfile.writeto(chisqname, overwrite=True)

    return pcube
Esempio n. 44
0
    for clf_type in clf_types:

        min_error = 1000
        opt_no = None
        y_true_train = 440
        y_true_test = 400

        start_training_time = time.time()
        mask_predicted_ = calculate_mask_predicted(
            clf_type=clf_type,
            clf=clf,
            bands=data_train[date][y_true_train],
            mask=mask_train[date][y_true_train],
            min_plant_size=min_plant_size)
        for erosion_iterations in range(0, 10):
            mask_predicted_ = binary_erosion(mask_predicted_)
            for _ in range(erosion_iterations):
                mask_predicted_ = binary_erosion(mask_predicted_)
            mask_predicted_ = remove_small_objects(
                mask_predicted_, min_size=min_plant_size[date])
            labels, num = label(mask_predicted_, return_num=True)
            Y_predicted = num
            error = (y_true_train - Y_predicted)
            if np.abs(error) < min_error:
                min_error = np.abs(error)
                error_with_sign = error
                opt_no = erosion_iterations
                labels_opt = labels
                mask_predicted_opt = mask_predicted_
        erosion_opt_iterations[date][clf_type] = opt_no
        end_training_time = time.time()
Esempio n. 45
0
def standard_measures(mask,
                      pixelsize_tract=1,
                      pixelsize_og=1,
                      mean_normal_list=None,
                      fields=None):
    u_b, v_b, fx_b, fy_b, fx_f, fy_f, mask_fm, stress_tensor_f, stress_tensor_b = [
        fields[x] for x in [
            "u_b", "v_b", "fx_b", "fy_b", "fx_f", "fy_f", "mask_fm",
            "stress_tensor_f", "stress_tensor_b"
        ]
    ]
    mask = mask.astype(bool)
    mask_fm = mask_fm.astype(bool)

    cv_f, cv_b, cont_energy_b, cont_energy_f, contractile_force_b, contractile_force_f, \
    mean_normal_stress_b, mean_normal_stress_f, mean_shear_b, mean_shear_f, avg_normal_stress, rel_av_norm_stress,max_shear_b,max_shear_f = [
        None for i in range(14)]

    # suppress is equivalent to try and expect...pass
    with suppress(TypeError, NameError):
        shear_f = stress_tensor_f[:, :, 0, 1] / (
            pixelsize_tract)  # shear component of the stress tensor
    # max_shear_stress
    with suppress(TypeError, NameError):
        max_shear_f = np.sqrt((
            (stress_tensor_f[:, :, 0, 0] - stress_tensor_f[:, :, 1, 1]) /
            2)**2 + stress_tensor_f[:, :, 0, 1]**2) / pixelsize_tract
        max_shear_f = np.mean(max_shear_f[binary_erosion(mask)])
    with suppress(TypeError, NameError):
        mean_normal_stress_f = (
            (stress_tensor_f[:, :, 0, 0] + stress_tensor_f[:, :, 1, 1]) /
            2) / (pixelsize_tract)
        mean_normal_stress_f = np.mean(mean_normal_stress_f[binary_erosion(
            mask)])  # mask alone is one tick to big?

    with suppress(TypeError, NameError):
        mean_shear_f = np.mean(np.abs(shear_f[binary_erosion(mask)]))
    # line tension
    # forces
    with suppress(TypeError, NameError):
        energy_points_f = strain_energy_points(
            u_b, v_b, fx_f, fy_f, pixelsize_og,
            pixelsize_tract)  # contractile energy at any point
    # needs interpolation of mask possibley
    with suppress(TypeError, NameError):
        cont_energy_f = np.sum(energy_points_f[mask_fm])
    with suppress(TypeError, NameError):
        contractile_force_f, proj_x, proj_y, center = contractillity(
            fx_f, fy_f, pixelsize_tract, mask_fm)
    # shear component of the stress tensor
    with suppress(TypeError, NameError):
        shear_b = stress_tensor_b[:, :, 0, 1] / (pixelsize_tract)
    # max_shear_stress
    with suppress(TypeError, NameError):
        max_shear_b = np.sqrt((
            (stress_tensor_b[:, :, 0, 0] - stress_tensor_b[:, :, 1, 1]) /
            2)**2 + stress_tensor_b[:, :, 0, 1]**2) / pixelsize_tract
        max_shear_b = np.mean(max_shear_b[binary_erosion(mask)])
    with suppress(TypeError, NameError):
        mean_normal_stress_b = (
            (stress_tensor_b[:, :, 0, 0] + stress_tensor_b[:, :, 1, 1]) /
            2) / (pixelsize_tract)
        mean_normal_stress_b = np.mean(
            mean_normal_stress_b[binary_erosion(mask)])

    with suppress(TypeError, NameError):
        mean_shear_b = np.mean(np.abs(shear_b[binary_erosion(mask)]))
    # line tension
    # forces
    with suppress(TypeError, NameError):
        energy_points_b = strain_energy_points(
            u_b, v_b, fx_b, fy_b, pixelsize_og,
            pixelsize_tract)  # contractile energy at any point
    # needs interpolation of mask possibley
    with suppress(TypeError, NameError):
        cont_energy_b = np.sum(energy_points_b[mask_fm])
    with suppress(TypeError, NameError):
        contractile_force_b, proj_x, proj_y, center = contractillity(
            fx_b, fy_b, pixelsize_tract, mask_fm)
    with suppress(TypeError, NameError):
        cv_f = coefficient_of_variation(
            binary_erosion(mask),
            ((stress_tensor_f[:, :, 0, 0] + stress_tensor_f[:, :, 1, 1]) / 2) /
            (pixelsize_tract), 0)
    with suppress(TypeError, NameError):
        cv_b = coefficient_of_variation(
            binary_erosion(mask),
            ((stress_tensor_b[:, :, 0, 0] + stress_tensor_b[:, :, 1, 1]) / 2) /
            (pixelsize_tract), 0)
    with suppress(TypeError, NameError):
        avg_normal_stress_be = [
            np.nanmean(ms[mask]) for ms in mean_normal_list
        ]
    with suppress(TypeError, NameError):
        rel_av_norm_stress = [
            x / mean_normal_stress_b for x in avg_normal_stress_be
        ]

    measures = {
        "mask_fm": mask_fm,
        "mask": mask,
        "cv_f": cv_f,
        "cv_b": cv_b,
        "cont_energy_b": cont_energy_b,
        "cont_energy_f": cont_energy_f,
        "contractile_force_b": contractile_force_b,
        "contractile_force_f": contractile_force_f,
        "mean_normal_stress_b": mean_normal_stress_b,
        "mean_normal_stress_f": mean_normal_stress_f,
        "mean_shear_b": mean_shear_b,
        "mean_shear_f": mean_shear_f,
        "max_shear_f": max_shear_f,
        "max_shear_b": max_shear_b,
        "avg_normal_stress_be": avg_normal_stress_be,
        "rel_av_norm_stress": rel_av_norm_stress
    }
    return measures
Esempio n. 46
0
def s2_pre_processing(s2_dir,
                      temp_angle=False,
                      s2_angle_dir='/home/users/marcyin/acix/s2_angle/'):
    s2_dir = os.path.abspath(s2_dir)
    scihub = []
    aws = []
    logger = create_logger()
    logger.propagate = False
    for (dirpath, dirnames, filenames) in os.walk(s2_dir):
        if len(filenames) > 0:
            temp = [dirpath + '/' + i for i in filenames]
            for j in temp:
                if ('MTD' in j) & ('TL' in j) & ('xml' in j):
                    scihub.append(j)
                if 'metadata.xml' in j:
                    aws.append(j)
    s2_tiles = []
    for metafile in scihub + aws:
        if 'metadata.xml' in j:
            with open(metafile) as f:
                for i in f.readlines():
                    if 'TILE_ID' in i:
                        tile = i.split('</')[0].split('>')[-1]
        else:
            tile = metafile.split('/')[-4]
        top_dir = os.path.dirname(metafile)
        log_file = top_dir + '/SIAC_S2.log'
        if os.path.exists(log_file):
            os.remove(log_file)
        logger.info('Preprocessing for %s' % tile)
        logger.info('Doing per pixel angle resampling.')
        bands = [
            'B01', 'B02', 'B03', 'B04', 'B05', 'B06', 'B07', 'B08', 'B8A',
            'B09', 'B10', 'B11', 'B12'
        ]
        # if len(glob(top_dir + '/ANG_DATA/*.tif')) == 14:
        #     sun_ang_name   = top_dir + '/ANG_DATA/SAA_SZA.tif'
        #     view_angs      = glob(top_dir + '/ANG_DATA/VAA_VZA_B??.tif')
        #     toa_refs       = glob(top_dir + '/IMG_DATA/*B??.jp2')
        #     view_ang_names = sorted(view_angs, key = lambda fname: bands.index(fname.split('_')[-1].split('.tif')[0]))
        #     toa_refs       = sorted(toa_refs,  key = lambda toa_ref: bands.index('B' + toa_ref.split('B')[-1][:2]))
        #     cloud_name     = top_dir + '/cloud.tif'
        # else:
        #     sun_ang_name, view_ang_names, toa_refs, cloud_name = resample_s2_angles(metafile)
        sun_ang_name, view_ang_names, toa_refs, cloud_name = resample_s2_angles(
            metafile, temp_angle, s2_angle_dir)
        cloud_bands = np.array(toa_refs)[[0, 1, 3, 4, 7, 8, 9, 10, 11, 12]]
        logger.info('Getting cloud mask.')
        if not os.path.exists(cloud_name):
            cloud = do_cloud(cloud_bands, cloud_name)
        else:
            cloud = gdal.Open(cloud_name).ReadAsArray() / 100.
        cloud_mask = (cloud > 0.4) & (cloud != 2.56
                                      )  # 0.4 is the sentinel hub default
        clean_pixel = (
            (cloud != 2.56).sum() - cloud_mask.sum()) / cloud_mask.size * 100.
        valid_pixel = (cloud != 2.56).sum() / cloud_mask.size * 100.
        logger.info('Valid pixel percentage: %.02f' % (valid_pixel))
        logger.info('Clean pixel percentage: %.02f' % (clean_pixel))
        cloud_mask = binary_dilation(binary_erosion(cloud_mask, disk(2)),
                                     disk(3)) | (cloud < 0)
        s2_tiles.append([
            sun_ang_name, view_ang_names, toa_refs, cloud_name, cloud_mask,
            metafile
        ])
        handlers = logger.handlers[:]
        for handler in handlers:
            handler.close()
            logger.removeHandler(handler)
    return s2_tiles
Esempio n. 47
0
def anim_traj(
    df,
    tif,
    show_image=True,
    show_scalebar=True,
    pixel_size=None,
    scalebar_pos='upper right',
    scalebar_fontsize='large',
    scalebar_length=0.3,
    scalebar_height=0.02,
    scalebar_boxcolor=(1, 1, 1),
    scalebar_boxcolor_alpha=0,
    cb_fontsize='large',
    show_colorbar=True,
    cb_min=None,
    cb_max=None,
    cb_major_ticker=None,
    cb_minor_ticker=None,
    cb_pos='right',
    cb_tick_loc='right',
    plot_r=False,
    show_traj_num=False,
    fontname='Arial',
    show_tail=True,
    tail_length=50,
    show_boundary=False,
    boundary_masks=None,
    dpi=150,
):
    """
    Animate blob in the tif video.

    Pseudo code
    ----------
    1. If df is empty, return.
    2. Initialize fig, ax, and xlim, ylim based on df.
    3. Add scale bar.
    4. Animate blobs.

    Parameters
    ----------
    df : DataFrame
		DataFrame containing 'x', 'y', 'frame'.

    tif : Numpy array
        tif stack in format of 3d numpy array.

    pixel_size : None or float
        If None, no scalebar.
        If float, add scalebar with specified pixel size in um.

    scalebar_color : tuple
        RGB or RGBA tuple to define the scalebar color

    scalebar_pos : string
        position string. ('upper right'...)

    scalebar_length : float
        scalebar length relative to ax

    scalebar_height : float
        scalebar height relative to ax

    scalebar_boxcolor : tuple
        RGB or RGBA tuple to define the scalebar background box color

    scalebar_boxcolor_alpha : float
        Define the transparency of the background box color

    cb_fontsize : string or integer
        Define the colorbar label text size. eg. 'large', 'x-large', 10, 40...

    cb_min, cb_max: float
        [cb_min, cb_max] is the color bar range.

    cb_major_ticker, cb_minor_ticker: float
        Major and minor ticker setting for the color bar.

    cb_pos : string
        append_axes position string. ('right', 'top'...)

    cb_tick_loc : string
        colorbar tick position string. ('right', 'top'...)

    show_colorbar : bool
        If False, only return colormap and df, no colorbar added.

    show_image : bool
        if True, show animation of top of image.
        if False, only show blobs without image.

    tail_length : int
        how many frames will the traj last.

    dpi : int
        dpi setting for plt.subplots().


    Returns
    -------
    3d numpy array.

    Examples
	--------
    anim_tif = anim_traj(df, tif,
                pixel_size=0.163,
                show_image=True)
    imsave('anim-result.tif', anim_tif)
    """

    # """
    # ~~~~~~~~~~~Check if df is empty~~~~~~~~~~~~
    # """
    if df.empty:
        print('df is empty. No traj to animate!')
        return

    anim_tif = []

    for i in range(len(tif)):
        print("Animate frame %d" % i)
        curr_df = df[df['frame'] == i]

        # """
        # ~~~~~~~~Initialize fig, ax, and xlim, ylim based on df~~~~~~~~
        # """
        fig, ax = plt.subplots(figsize=(8, 6), dpi=dpi)
        ax.set_xticks([])
        ax.set_yticks([])

        if not show_image:
            x_range = (df['y'].max() - df['y'].min())
            y_range = (df['x'].max() - df['x'].min())
            ax.set_xlim(df['y'].min() - 0.1 * x_range,
                        df['y'].max() + 0.1 * x_range)
            ax.set_ylim(df['x'].max() + 0.1 * y_range,
                        df['x'].min() - 0.1 * y_range)
        else:
            ax.imshow(tif[i], cmap='gray', aspect='equal')
            ax.set_xlim(0, tif[0].shape[1])
            ax.set_ylim(0, tif[0].shape[0])
            for spine in ['top', 'bottom', 'left', 'right']:
                ax.spines[spine].set_visible(False)

        # """
        # ~~~~~~~~Add scale bar~~~~~~~~
        # """
        if show_scalebar and pixel_size:
            add_scalebar(
                ax,
                units='um',
                sb_color=(0.5, 0.5, 0.5),
                fontname='Arial',
                pixel_size=pixel_size,
                sb_pos=scalebar_pos,
                fontsize=scalebar_fontsize,
                length_fraction=scalebar_length,
                height_fraction=scalebar_height,
                box_color=scalebar_boxcolor,
                box_alpha=scalebar_boxcolor_alpha,
            )

        # """
        # ~~~~~~~~customized the colorbar, then add it~~~~~~~~
        # """
        if 'D' in df:
            df, colormap = add_outside_colorbar(
                ax,
                df,
                data_col='D',
                cb_colormap='coolwarm',
                label_font_size=cb_fontsize,
                cb_min=cb_min,
                cb_max=cb_max,
                cb_major_ticker=cb_major_ticker,
                cb_minor_ticker=cb_minor_ticker,
                show_colorbar=show_colorbar,
                label_str=r'D (nm$^2$/s)',
                cb_pos=cb_pos,
                cb_tick_loc=cb_tick_loc,
            )
        else:
            df, colormap = add_outside_colorbar(
                ax,
                df,
                data_col='particle',
                cb_colormap='jet',
                label_font_size=cb_fontsize,
                cb_min=cb_min,
                cb_max=cb_max,
                cb_major_ticker=cb_major_ticker,
                cb_minor_ticker=cb_minor_ticker,
                show_colorbar=show_colorbar,
                label_str='particle',
                cb_pos=cb_pos,
                cb_tick_loc=cb_tick_loc,
            )

        # """
        # ~~~~~~~~Add traj num~~~~~~~~
        # """
        if show_traj_num:
            particles = curr_df.particle.unique()
            ax.text(0.95,
                    0.00,
                    """
                    Total trajectory number: %d
                    """ % (len(particles)),
                    horizontalalignment='right',
                    verticalalignment='bottom',
                    fontsize=12,
                    color=(0.5, 0.5, 0.5, 0.5),
                    transform=ax.transAxes,
                    weight='bold',
                    fontname=fontname)

        # """
        # ~~~~~~~~Animate curr blob~~~~~~~~
        # Backup code for color coded blob animation:
        # for ind in curr_df.index:
        #     partcle_color = colormap(curr_df.loc[ind, 'D_norm'])
        #     y, x, r = curr_df.loc[ind, 'x'], curr_df.loc[ind, 'y'], curr_df.loc[ind, 'r']
        #     ax.scatter(x, y,
        #                 s=5,
        #                 marker='^',
        #                 c=[partcle_color])
        #     if False:
        #         c = plt.Circle((x,y), r, color=partcle_color,
        #                        linewidth=1, fill=False)
        #         ax.add_patch(c)
        # """
        anno_blob(ax,
                  curr_df,
                  marker='^',
                  markersize=3,
                  plot_r=plot_r,
                  color=(0, 0, 1))

        # """
        # ~~~~~~~~Animate particle tail~~~~~~~~
        # """
        if show_tail:
            particles = curr_df.particle.unique()
            for particle_num in particles:
                traj = df[df.particle == particle_num]
                traj = traj[traj['frame'].isin(range(i - tail_length, i + 1))]
                traj = traj.sort_values(by='frame')

                # """
                # ~~~~~~~~Animate cilia global trajectory if exists~~~~~~~~
                # """
                if 'x_global' in df.columns and 'y_global' in df.columns:
                    ax.plot(traj['y_global'],
                            traj['x_global'],
                            '-',
                            linewidth=0.5,
                            color=(0, 1, 0))

                if 'D_norm' in traj:
                    ax.plot(traj['y'],
                            traj['x'],
                            linewidth=0.5,
                            color=colormap(traj['D_norm'].mean()))
                else:
                    ax.plot(traj['y'],
                            traj['x'],
                            linewidth=0.5,
                            color=colormap(traj['particle_norm'].mean()))

        # """
        # ~~~~~~~~Animate boundary~~~~~~~~
        # """
        if show_boundary:
            curr_mask = boundary_masks[i]
            selem = disk(1)
            bdr_pixels = curr_mask - binary_erosion(curr_mask, selem)
            bdr_coords = np.nonzero(bdr_pixels)
            ax.plot(bdr_coords[1],
                    bdr_coords[0],
                    'o',
                    markersize=1,
                    linewidth=0.5,
                    color=(0, 1, 0, 1))

        # """
        # ~~~~~~~~save curr figure~~~~~~~~
        # """
        curr_plt_array = plot_end(fig, pltshow=False)
        anim_tif.append(curr_plt_array)

    anim_tif = np.array(anim_tif)
    return anim_tif
Esempio n. 48
0
            thresh_img = np.where(image < 0, 1.0, 0.)
            regions = regionprops(thresh_img.astype(int))

            for region in regions:

                if region.area > maxAllowedArea:
                    prediction = unet_predict([image], predict_fn)
                    prediction[prediction < THRESHOLD] = 0
                    prediction[prediction > 0] = 1
                    prediction = prediction.reshape(324, 324)

                    # localize the center of nodule
                    if np.amax(prediction) > 0:
                        centers = []
                        selem = morphology.disk(1)
                        image_eroded = morphology.binary_erosion(prediction,
                                                                 selem=selem)

                        label_im, nb_labels = ndimage.label(image_eroded)
                        for i in xrange(1, nb_labels + 1):
                            blob_i = np.where(label_im == i, 1, 0)
                            mass = center_of_mass(blob_i)
                            centers.append([mass[1], mass[0]])

                        for center in centers:
                            world_coords = voxel_2_world(
                                np.asarray([center[0], center[1],
                                            slice_index]), np.asarray(origin),
                                np.asarray([1, 1, 1]))
                            resnet_coords = world_2_voxel(
                                np.asarray(world_coords), np.asarray(origin),
                                np.asarray(OUTPUT_SPACING))
Esempio n. 49
0
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as mp
from skimage.filter.rank import entropy,otsu
from skimage.filter import threshold_otsu
from skimage.morphology import square,rectangle,label,closing,disk,binary_erosion,opening
from skimage.color import label2rgb,rgb2gray
from skimage.segmentation import clear_border
from skimage.measure import regionprops
from skimage import io
i=rgb2gray(io.imread('z.jpg'))
t=threshold_otsu(i)
i=i>t
z=binary_erosion(1-i,square(3))
i=1-z
i=entropy(i,rectangle(10,1))
t=threshold_otsu(i)
c=i>t
c=closing(c,rectangle(4,28))
b=c.copy()
clear_border(b)
l=label(b)
z=np.logical_xor(c,b)
l[z]=-1
iol=label2rgb(l,image=i)
fig,ax=plt.subplots(ncols=1,nrows=1,figsize=(6,6))
ax.imshow(iol)
for region in regionprops(l,['Area','BoundingBox']):
	if region['Area']<3500:
		continue
	minr,minc,maxr,maxc=region['BoundingBox']
Esempio n. 50
0
def erosao(img, est):
	out = skm.binary_erosion(img, est)
	return out
Esempio n. 51
0
def main():
    opt = TestOptions()
    args = opt.initialize()

    if not os.path.exists(args.save):
        os.makedirs(args.save)

    model = CreateSSLModel(args)
    cudnn.enabled = True
    cudnn.benchmark = True
    model.train()
    model.cuda()
    targetloader = CreateTrgDataSSLLoader(args)

    #predicted_label = np.zeros((len(targetloader), 1634, 1634))
    predicted_label = np.zeros((len(targetloader), 2056, 2124))
    #predicted_prob = np.zeros((len(targetloader), 1634, 1634))
    predicted_prob = np.zeros((len(targetloader), 2056, 2124))
    image_name = []

    for index, batch in enumerate(targetloader):
        if index % 10 == 0:
            print('%d processd' % index)
        image, _, name = batch
        image = Variable(image).cuda()
        _, output, _, _ = model(image, ssl=True)
        output = nn.functional.softmax(output / args.alpha, dim=1)
        #output = nn.functional.upsample(output, (1634, 1634), mode='bilinear', align_corners=True).cpu().data[0].numpy()
        output = nn.functional.upsample(
            output, (2056, 2124), mode='bilinear',
            align_corners=True).cpu().data[0].numpy()
        output = output.transpose(1, 2, 0)
        label, prob = np.argmax(output, axis=2), np.max(output, axis=2)
        cup_mask = get_bool(label, 0)
        disc_mask = get_bool(label, 0) + get_bool(label, 1)
        disc_mask = disc_mask.astype(np.uint8)
        cup_mask = cup_mask.astype(np.uint8)
        for i in range(5):
            disc_mask = scipy.signal.medfilt2d(disc_mask, 19)
            cup_mask = scipy.signal.medfilt2d(cup_mask, 19)
        disc_mask = morphology.binary_erosion(disc_mask,
                                              morphology.diamond(7)).astype(
                                                  np.uint8)  # return 0,1
        cup_mask = morphology.binary_erosion(cup_mask,
                                             morphology.diamond(7)).astype(
                                                 np.uint8)  # return 0,1
        disc_mask = get_largest_fillhole(disc_mask)
        cup_mask = get_largest_fillhole(cup_mask)

        disc_mask = morphology.binary_dilation(disc_mask,
                                               morphology.diamond(7)).astype(
                                                   np.uint8)  # return 0,1
        cup_mask = morphology.binary_dilation(cup_mask,
                                              morphology.diamond(7)).astype(
                                                  np.uint8)  # return 0,1

        disc_mask = get_largest_fillhole(disc_mask).astype(
            np.uint8)  # return 0,1
        cup_mask = get_largest_fillhole(cup_mask).astype(np.uint8)
        label = disc_mask + cup_mask
        predicted_label[index] = label.copy()
        predicted_prob[index] = prob.copy()
        image_name.append(name[0])

    thres = []
    for i in range(3):
        x = predicted_prob[predicted_label == i]
        if len(x) == 0:
            thres.append(0)
            continue
        x = np.sort(x)
        #print(len(x))
        print(i, x)
        print(np.sum(x < 0.5), '/', len(x), np.sum(x < 0.5) / len(x))
        #thres.append(x[np.int(np.round(len(x) *int(args.p[i])))])
        thres.append(0.5)
    thres = np.array(thres)
    print(thres)
    # thres[thres > 0.6] = 0.6

    color_labels = {0: 255, 1: 128, 2: 0}
    #import pdb;pdb.set_trace()
    for index in range(len(targetloader)):
        name = image_name[index]
        label = predicted_label[index]  # label_min:0 label_max=2
        #print(label)
        prob = predicted_prob[index]  # prob_min:0.5 prob_max=1.0
        #print(prob)
        for i, color in color_labels.items():
            label[label == i] = color
            #print(thres[i])
            label[(prob > thres[i]) * (label == i)] = color
        output = np.asarray(label, dtype=np.uint8)
        output = Image.fromarray(output.astype(np.uint8))
        #name = name.split('.')[0] + '.png'
        name = name.split('_')[0] + '.bmp'
        output.save('%s/%s' % (args.save, name))

    disc_dice, cup_dice = calculate_dice(args.gt_dir, args.save,
                                         args.devkit_dir)
    print('===> disc_dice:' + str(round(disc_dice, 3)) + '\t' + 'cup_dice:' +
          str(round(cup_dice, 3)))
Esempio n. 52
0
def _generate_binary_masks(annot_dict, shape, erose_size=5, obj_size_rem=500, save_indiv=False):
    # Get dimensions of image and created masks of same size
    # This we need to save somewhere (e.g. as part of the geojson file?)

    # Filled masks and edge mask for polygons
    mask_fill = np.zeros(shape, dtype=np.uint8)
    mask_edge = np.zeros(shape, dtype=np.uint8)
    mask_labels = np.zeros(shape, dtype=np.uint16)

    rr_all = []
    cc_all = []

    if save_indiv is True:
        mask_edge_indiv = np.zeros(
            (shape[0], shape[1], len(annot_dict)), dtype=np.bool
        )
        mask_fill_indiv = np.zeros(
            (shape[0], shape[1], len(annot_dict)), dtype=np.bool
        )

    # Image used to draw lines - for edge mask for freelines
    im_freeline = Image.new("1", (shape[1], shape[0]), color=0)
    draw = ImageDraw.Draw(im_freeline)

    # Loop over all roi
    i_roi = 0
    for roi_key, roi in annot_dict.items():
        roi_pos = roi["pos"]

        # Check region type

        # freeline - line
        if roi["type"] == "freeline" or roi["type"] == "LineString":

            # Loop over all pairs of points to draw the line

            for ind in range(roi_pos.shape[0] - 1):
                line_pos = (
                    roi_pos[ind, 1],
                    roi_pos[ind, 0],
                    roi_pos[ind + 1, 1],
                    roi_pos[ind + 1, 0],
                )
                draw.line(line_pos, fill=1, width=erose_size)

        # freehand - polygon
        elif (
            roi["type"] == "freehand"
            or roi["type"] == "polygon"
            or roi["type"] == "polyline"
            or roi["type"] == "Polygon"
        ):

            # Draw polygon
            rr, cc = skimage_draw.polygon(
                [shape[0] - r for r in roi_pos[:, 1]], roi_pos[:, 0]
            )

            # Make sure it's not outside
            rr[rr < 0] = 0
            rr[rr > shape[0] - 1] = shape[0] - 1

            cc[cc < 0] = 0
            cc[cc > shape[1] - 1] = shape[1] - 1

            # Test if this region has already been added
            if any(np.array_equal(rr, rr_test) for rr_test in rr_all) and any(
                np.array_equal(cc, cc_test) for cc_test in cc_all
            ):
                # print('Region #{} has already been used'.format(i +
                # 1))
                continue

            rr_all.append(rr)
            cc_all.append(cc)

            # Generate mask
            mask_fill_roi = np.zeros(shape, dtype=np.uint8)
            mask_fill_roi[rr, cc] = 1

            # Erode to get cell edge - both arrays are boolean to be used as
            # index arrays later
            mask_fill_roi_erode = morphology.binary_erosion(
                mask_fill_roi, np.ones((erose_size, erose_size))
            )
            mask_edge_roi = (
                mask_fill_roi.astype("int") - mask_fill_roi_erode.astype("int")
            ).astype("bool")

            # Save array for mask and edge
            mask_fill[mask_fill_roi > 0] = 1
            mask_edge[mask_edge_roi] = 1
            mask_labels[mask_fill_roi > 0] = i_roi + 1

            if save_indiv is True:
                mask_edge_indiv[:, :, i_roi] = mask_edge_roi.astype("bool")
                mask_fill_indiv[:, :, i_roi] = mask_fill_roi_erode.astype("bool")

            i_roi = i_roi + 1

        else:
            roi_type = roi["type"]
            raise NotImplementedError(
                f'Mask for roi type "{roi_type}" can not be created'
            )

    del draw

    # Convert mask from free-lines to numpy array
    mask_edge_freeline = np.asarray(im_freeline)
    mask_edge_freeline = mask_edge_freeline.astype("bool")

    # Post-processing of fill and edge mask - if defined
    mask_dict = {}
    if np.any(mask_fill):

        # (1) remove edges , (2) remove small  objects
        mask_fill = mask_fill & ~mask_edge
        mask_fill = morphology.remove_small_objects(
            mask_fill.astype("bool"), obj_size_rem
        )

        # For edge - consider also freeline edge mask

        mask_edge = mask_edge.astype("bool")
        mask_edge = np.logical_or(mask_edge, mask_edge_freeline)

        # Assign to dictionary for return
        mask_dict["edge"] = mask_edge
        mask_dict["fill"] = mask_fill.astype("bool")
        mask_dict["labels"] = mask_labels.astype("uint16")

        if save_indiv is True:
            mask_dict["edge_indiv"] = mask_edge_indiv
            mask_dict["fill_indiv"] = mask_fill_indiv
        else:
            mask_dict["edge_indiv"] = np.zeros(shape + (1,), dtype=np.uint8)
            mask_dict["fill_indiv"] = np.zeros(shape + (1,), dtype=np.uint8)

    # Only edge mask present
    elif np.any(mask_edge_freeline):
        mask_dict["edge"] = mask_edge_freeline
        mask_dict["fill"] = mask_fill.astype("bool")
        mask_dict["labels"] = mask_labels.astype("uint16")

        mask_dict["edge_indiv"] = np.zeros(shape + (1,), dtype=np.uint8)
        mask_dict["fill_indiv"] = np.zeros(shape + (1,), dtype=np.uint8)

    else:
        raise Exception("No mask has been created.")

    return mask_dict
Esempio n. 53
0
def getSquareCoords(imgArr, imgSize=(1024, 768), erosR=7, openR=10, bordW=80, boardDim=(8,8)):

    # calculate threshold using otsu and apply
    intensityTh = threshold_otsu(imgArr)
    imgThArr = (imgArr < intensityTh)
    #Image.fromarray(255*imgThArr.astype(np.uint8)).show()

    # morphologically erode then open binary images
    imgMorphArr = binary_opening(binary_erosion(imgThArr, selem=square(erosR)), selem=square(openR))
    #Image.fromarray(255*imgMorphArr.astype(np.uint8)).show()

    # remove border regions
    imgClearArr = clear_border(imgMorphArr, buffer_size=bordW)
    #Image.fromarray(255*imgClearArr.astype(np.uint8)).show()


    # apply connected-component labelling
    imgLabArr = label(imgClearArr)
    #Image.fromarray(55*(imgLabArr>0)+200*imgLabArr/np.max(imgLabArr).astype(np.uint8)).show()

    # remove regions of size x: median(regionSize)/2 < x < 2*median(regionSize) ---- (option: then reapply connected-component labelling?)
    regionStatsFull = regionprops(imgLabArr, coordinates="xy")
    regionStats = np.array([[region.label, region.area, region.centroid[0], region.centroid[1], region.extent] for region in regionStatsFull])
    for region in range(len(regionStats)):
        if regionStats[region, 1] < np.median(regionStats, axis=0)[1]/2 or regionStats[region, 1] > np.median(regionStats, axis=0)[1]*2:
            imgLabArr = imgLabArr * (imgLabArr != region+1)
    regionStats = regionStats[(regionStats[:, 1] >= np.median(regionStats, axis=0)[1]/2) & (regionStats[:, 1] < np.median(regionStats, axis=0)[1]*2)]
    #Image.fromarray(55*(imgLabArr>0)+imgLabArr*200/np.max(imgLabArr).astype(np.uint8)).show()

    # calculate how much to rotate image by
    angleList = []
    regionRowSort = regionStats[np.argsort(regionStats[:, 2])]
    regionRowSort = np.array([region for region in regionRowSort if region[4] >= 0.75])
    rowGapTh = np.max(regionRowSort[1:, 2]-regionRowSort[0:-1, 2])/2
    regionRowGroup = np.concatenate((np.zeros(1),np.cumsum((regionRowSort[1:, 2]-regionRowSort[0:-1, 2]) > rowGapTh)), axis=None)
    for rowGroup in range(int(np.max(regionRowGroup)+1)):
        if sum(regionRowGroup == rowGroup) > 1:
            A = np.array([[regionRowSort[region,3], 1] for region in np.arange(regionRowGroup.size)[regionRowGroup==rowGroup]])
            y = regionRowSort[np.arange(regionRowGroup.size)[regionRowGroup == rowGroup], 2]
            m, c = np.linalg.lstsq(A, y - np.mean(y), rcond=None)[0]
            angleList.append(np.arctan(m))
    regionColSort = regionStats[np.argsort(regionStats[:, 3])]
    regionColSort = np.array([region for region in regionColSort if region[4] >= 0.75])
    colGapTh = np.max(regionColSort[1:, 3]-regionColSort[0:-1, 3])/2
    regionColGroup = np.concatenate((np.zeros(1),np.cumsum((regionColSort[1:, 3]-regionColSort[0:-1, 3]) > colGapTh)), axis=None)
    for colGroup in range(int(np.max(regionColGroup)+1)):
        if sum(regionColGroup == colGroup) > 1:
            A = np.array([[regionColSort[region,3], 1] for region in np.arange(regionColGroup.size)[regionColGroup==colGroup]])
            y = regionColSort[np.arange(regionColGroup.size)[regionColGroup == colGroup], 2]
            m, c = np.linalg.lstsq(A, y - np.mean(y), rcond=None)[0]
            angleList.append(np.arctan(m)-np.pi/2)
    rotateAngle = np.median(angleList)*180/np.pi
    #Image.fromarray(55*(imgLabArr>0)+imgLabArr*200/np.max(imgLabArr).astype(np.uint8)).rotate(angle=rotateAngle, fillcolor=0).show()

    # find minimums of row sums and column sums
    imgLabArr = np.array(Image.fromarray(imgLabArr*255/np.max(imgLabArr).astype(np.uint8)).rotate(angle=rotateAngle, fillcolor=0))>0
    imgCS = np.reshape(np.sum(imgLabArr > 0, axis=0), (np.shape(imgLabArr)[1]))
    imgRS = np.reshape(np.sum(imgLabArr > 0, axis=1), (np.shape(imgLabArr)[0]))
    pECS = np.convolve(imgCS < threshold_otsu(imgCS), np.asarray([1/2, 1/2]))
    pERS = np.convolve(imgRS < threshold_otsu(imgRS), np.asarray([1/2, 1/2]))
    pEIndCS = np.asarray([i for i in range(imgSize[0]-1) if pECS[i + 1] == 1/2])
    pEIndRS = np.asarray([i for i in range(imgSize[1]-1) if pERS[i + 1] == 1/2])
    imgVL = np.asarray([pEIndCS[0]-erosR/2]+[(pEIndCS[2*i-1]+pEIndCS[2*i])/2 for i in range(1, int(len(pEIndCS)/2))]+[pEIndCS[-1]+erosR/2])
    imgHL = np.asarray([pEIndRS[0]-erosR/2]+[(pEIndRS[2*i-1]+pEIndRS[2*i])/2 for i in range(1, int(len(pEIndRS)/2))]+[pEIndRS[-1]+erosR/2])

    imgVL_Diff = imgVL[1:]-imgVL[0:-1]
    imgHL_Diff = imgHL[1:]-imgHL[0:-1]

    if imgHL_Diff.shape[0] != boardDim[0]:
        imgHL = imgHL[0] + np.median(imgHL_Diff)*np.arange(boardDim[0]+1)
    elif np.sum(np.abs(imgHL_Diff - np.median(imgHL_Diff)) > 0.2*np.median(imgHL_Diff)) > 0:
        imgHL = ((boardDim[0]*np.median(imgHL_Diff) + 3*imgHL[0] - imgHL[-1])/2) + np.median(imgHL_Diff)*np.arange(boardDim[0]+1)
    if imgVL_Diff.shape[0] != boardDim[1]:
        imgVL = imgVL[0] + np.median(imgVL_Diff)*np.arange(boardDim[1]+1)
        #imgVL[5:] += 0.01*np.median(imgVL_Diff) # to account for centre hinge
    elif np.sum(np.abs(imgVL_Diff - np.median(imgVL_Diff)) > 0.2*np.median(imgVL_Diff)) > 0:
        imgVL = (((boardDim[1]*np.median(imgVL_Diff) + 3*imgVL[0] - imgVL[-1])/2) + np.median(imgVL_Diff)*np.arange(boardDim[1]+1))

    # return imgHL and imgVL
    return rotateAngle, imgVL.astype(int), imgHL.astype(int)
Esempio n. 54
0
def get_segmented_lungs(img_dir, plot=False, min_lung_area=3000, padding_num=0):
    """
    :param img_dir: Input image path
    :param plot: Whether to show pictures or not
    :param min_lung_area: The minimum possible area of a lung (as a threshold)
    :param padding_num: Interception needs padding size
    :return: True or False (img is useful or not)
    """

    src_img = cv2.imread(img_dir)
    img = Image.open(img_dir)
    img = np.array(img)[:, :, 0]
    img = img.astype(np.int16)
    img = img * 3
    img -= 1000
    im = img.copy()
    '''
    This funtion segments the lungs from the given 2D slice.
    '''
    if plot == True:
        f, plots = plt.subplots(8, 1, figsize=(5, 40))
    '''
    Step 1: Convert into a binary image. 
    '''
    binary = im < -600
    if plot == True:
        plots[0].axis('off')
        plots[0].imshow(binary, cmap=plt.cm.bone)
    '''
    Step 2: Remove the blobs connected to the border of the image.
    '''
    cleared = clear_border(binary)
    if plot == True:
        plots[1].axis('off')
        plots[1].imshow(cleared, cmap=plt.cm.bone)
    '''
    Step 3: Label the image.
    '''
    label_image = label(cleared)
    if plot == True:
        plots[2].axis('off')
        plots[2].imshow(label_image, cmap=plt.cm.bone)
    '''
    Step 4: Keep the labels with 2 largest areas.
    '''
    areas = [r.area for r in regionprops(label_image)]
    areas.sort()
    if len(areas) > 2:
        for region in regionprops(label_image):
            if region.area < areas[-2] or region.area < min_lung_area:
                for coordinates in region.coords:
                    label_image[coordinates[0], coordinates[1]] = 0
    binary = label_image > 0
    if plot == True:
        plots[3].axis('off')
        plots[3].imshow(binary, cmap=plt.cm.bone)
    '''
    Step 5: Erosion operation with a disk of radius 2. This operation is 
    seperate the lung nodules attached to the blood vessels.
    '''
    selem = disk(2)
    binary = binary_erosion(binary, selem)
    if plot == True:
        plots[4].axis('off')
        plots[4].imshow(binary, cmap=plt.cm.bone)
    '''
    Step 6: Closure operation with a disk of radius 10. This operation is 
    to keep nodules attached to the lung wall.
    '''
    selem = disk(10)
    binary = binary_closing(binary, selem)
    if plot == True:
        plots[5].axis('off')
        plots[5].imshow(binary, cmap=plt.cm.bone)
    '''
    Step 7: Fill in the small holes inside the binary mask of lungs.
    '''
    edges = roberts(binary)
    binary = ndi.binary_fill_holes(edges)
    if plot == True:
        plots[6].axis('off')
        plots[6].imshow(binary, cmap=plt.cm.bone)
    '''
    Step 8: Superimpose the binary mask on the input image.
    '''
    get_high_vals = binary == 0
    im[get_high_vals] = 0
    if plot == True:
        plots[7].axis('off')
        plots[7].imshow(im, cmap=plt.cm.bone)
    mask = binary.astype(int)

    mask_img = np.zeros(src_img.shape, dtype=src_img.dtype)
    mask_img[mask == 1] = [255, 255, 0]

    if plot == True:
        plt.figure(figsize=(12, 12))
        plt.imshow(mask_img)
        plt.show()

    if mask_img.mean() < 7:
        return (False, [], [], [])
    else:

        # Find the smallest effective rectangle surrounding the lungs
        gray = cv2.cvtColor(mask_img, cv2.COLOR_BGR2GRAY)
        ret, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
        contours, hierarchy = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

        label_img = np.zeros(src_img.shape)
        cv2.drawContours(label_img, contours, -1, (255, 255, 0), thickness=cv2.FILLED)

        minx, miny, maxx, maxy = src_img.shape[1], src_img.shape[0], 0, 0
        for c in contours:
            if cv2.contourArea(c) > min_lung_area:
                temp_minx = np.min(c[:, 0, 0])
                temp_miny = np.min(c[:, 0, 1])
                temp_maxx = np.max(c[:, 0, 0])
                temp_maxy = np.max(c[:, 0, 1])
                if temp_minx < minx:
                    minx = temp_minx
                if temp_miny < miny:
                    miny = temp_miny
                if temp_maxx > maxx:
                    maxx = temp_maxx
                if temp_maxy > maxy:
                    maxy = temp_maxy
        crop_img = src_img[miny - padding_num:maxy + padding_num, minx - padding_num:maxx + padding_num]
        crop_mask = mask[miny - padding_num:maxy + padding_num, minx - padding_num:maxx + padding_num]
        crop_copy = crop_img.copy()
        crop_img[crop_mask == 0] = [0, 0 , 0]

        if plot == True:
            plt.figure(figsize=(9, 9))
            plt.imshow(crop_img, cmap='gray')
            plt.show()

        # fill crop area
        crop_mask = np.stack([crop_mask] * 3, 2)
        background = entity_filling(crop_img, crop_mask)

        filled_crop_img = np.where(crop_mask == 1, crop_img, background)
        filled_crop_img = np.array(filled_crop_img, dtype=np.int16)

        return (True, filled_crop_img, crop_img, crop_copy)
Esempio n. 55
0
        rr, cc = line(x - 10, y - 8, x + 10, y + 8)
        Iout[rr, cc, :] = [1, 0, 0]
        rr, cc = line(x + 10, y - 8, x - 10, y + 8)
        Iout[rr, cc, :] = [1, 0, 0]

    return (Iout)


A = io.imread(imageLoadingFolder + "\digits_binary_inv.png")
A2 = np.where(A < A.max() / 8, 1, 0)

#direct cut out of letter x from A2
F1 = A2[0:40, 60:90]
F1_miss = np.where(F2 == True, 0, 1)

F2 = binary_erosion(A2[0:40, 60:90])
F2_miss = np.where(
    binary_dilation(binary_dilation(binary_dilation(F2))) == True, 0, 1)
#closing on cutout
# F2 = medial_axis(closing(F1/np.max(F1)))

# H, _ = np.histogram(A/A.max()*256, bins = 256, range = (-0.5,255.5))

fdim = [25, 8]

fig = plt.figure(figsize=(fdim[0], fdim[1]), constrained_layout=True)  #
gs = fig.add_gridspec(fdim[0], fdim[1])

# plt.subplot(gs[0:8,0:4]) #fig_d[0], fig_d[1], 1)
# plotImage(gca(), A2, 'Binary Image', gray=True)
Esempio n. 56
0
def read_and_process_directory(base_directory, norm_window, min_hole_size,
                               min_cell_size, extrema_blur, peak_sep,
                               formatted_titles, channel_list):
    # process all .tif files in a passed directory and returns results dataframe (.csv)

    # set up paths
    time_stamp = dt.now().strftime('%Y_%m_%d_%H_%M_%S')
    save_path = '_extracted_data_%s' % time_stamp
    save_path = os.path.join(base_directory, save_path)
    print('base: ' + base_directory)
    print('save: ' + save_path)
    print('channel_list: ', channel_list)
    os.mkdir(save_path)

    # get paths for images in base directory
    image_list = glob.glob(os.path.join(base_directory,
                                        '*.TIF'))  # '.TIF' or '.tif'
    image_list = image_list + glob.glob(os.path.join(base_directory, '*.tif'))

    # initialize results dataframe
    results_df = pd.DataFrame()

    # iteratively read in images by filenames
    for i, img_path in enumerate(image_list):
        img = plt.imread(img_path)
        name = os.path.basename(img_path)

        print('\n')
        print(name)
        print('img ' + str(i + 1) + ' of ' + str(len(image_list)))

        img, labeled_cells, cell_props, n_chan = process_image(
            img, norm_window, min_hole_size, min_cell_size, extrema_blur,
            peak_sep, name, save_path)

        # save all cell quant in results dataframe
        img_df = pd.DataFrame()

        for count, key in enumerate(cell_props.keys()):
            channel_data = cell_props[key]

            if np.logical_and(
                    len(np.shape(img)) > 2,
                    str(count) in channel_list):
                if count < n_chan:
                    bg = filters.threshold_local(img[:, :, count], norm_window)

            for c, cell in enumerate(channel_data):

                if c % 10 == 0:
                    pct_done = ((c + (len(channel_data) * count)) /
                                len(channel_data))
                    pct_done = np.round(
                        (pct_done / len(cell_props.keys())) * 100, decimals=3)
                    print('img ' + str(pct_done) + '% complete ' +
                          '(channel ' + str(count + 1) + ' of ' +
                          str(len(cell_props.keys())) + ', cell ' +
                          str(c + 1) + ' of ' + str(len(channel_data)) + ')')

                if count == 0:
                    if formatted_titles:
                        img_df = img_df.append(
                            {
                                '_image_name':
                                name,
                                '_img_cell_#':
                                c,
                                '_clone':
                                name[14:17],
                                '_moi':
                                float(name[18:20]),
                                '_days_post_inf':
                                float(name[22:24]),
                                'area_ch' + str(count):
                                channel_data[c]['area'],
                                'log_area_ch' + str(count):
                                np.log10(channel_data[c]['area']),
                                'max_ch' + str(count):
                                channel_data[c]['max_intensity'],
                                'min_ch' + str(count):
                                channel_data[c]['min_intensity'],
                                'mean_ch' + str(count):
                                channel_data[c]['mean_intensity'],
                                'extent_ch' + str(count):
                                channel_data[c]['extent'],
                                'eccentricity_ch' + str(count):
                                channel_data[c]['eccentricity'],
                                'perimeter_ch' + str(count):
                                channel_data[c]['perimeter'],
                                'major_axis_ch' + str(count):
                                channel_data[c]['major_axis_length'],
                                'minor_axis_ch' + str(count):
                                channel_data[c]['minor_axis_length']
                            },
                            ignore_index=True)

                    else:
                        img_df = img_df.append(
                            {
                                '_image_name':
                                name,
                                '_img_cell_#':
                                c,
                                'area_ch' + str(count):
                                channel_data[c]['area'],
                                'log_area_ch' + str(count):
                                np.log10(channel_data[c]['area']),
                                'max_ch' + str(count):
                                channel_data[c]['max_intensity'],
                                'min_ch' + str(count):
                                channel_data[c]['min_intensity'],
                                'mean_ch' + str(count):
                                channel_data[c]['mean_intensity'],
                                'extent_ch' + str(count):
                                channel_data[c]['extent'],
                                'eccentricity_ch' + str(count):
                                channel_data[c]['eccentricity'],
                                'perimeter_ch' + str(count):
                                channel_data[c]['perimeter'],
                                'major_axis_ch' + str(count):
                                channel_data[c]['major_axis_length'],
                                'minor_axis_ch' + str(count):
                                channel_data[c]['minor_axis_length']
                            },
                            ignore_index=True)

                    img_df['log_area_ch' +
                           str(count)] = img_df['log_area_ch' +
                                                str(count)].replace(0, 0.01)

                else:
                    img_df.loc[img_df.index[c], 'area_ch' +
                               str(count)] = channel_data[c]['area']
                    img_df.loc[img_df.index[c], 'log_area_ch' +
                               str(count)] = np.log10(channel_data[c]['area'])
                    img_df.loc[img_df.index[c], 'max_ch' +
                               str(count)] = channel_data[c]['max_intensity']
                    img_df.loc[img_df.index[c], 'min_ch' +
                               str(count)] = channel_data[c]['min_intensity']
                    img_df.loc[img_df.index[c], 'mean_ch' +
                               str(count)] = channel_data[c]['mean_intensity']
                    img_df.loc[img_df.index[c], 'extent_ch' +
                               str(count)] = channel_data[c]['extent']
                    img_df.loc[img_df.index[c], 'eccentricity_ch' +
                               str(count)] = channel_data[c]['eccentricity']
                    img_df.loc[img_df.index[c], 'perimeter_ch' +
                               str(count)] = channel_data[c]['perimeter']
                    img_df.loc[
                        img_df.index[c], 'major_axis_ch' +
                        str(count)] = channel_data[c]['major_axis_length']
                    img_df.loc[
                        img_df.index[c], 'minor_axis_ch' +
                        str(count)] = channel_data[c]['minor_axis_length']
                    img_df['log_area_ch' +
                           str(count)] = img_df['log_area_ch' +
                                                str(count)].replace(0, 0.01)

                ### new -- for channel-specific detailed regionprop data to add to img_df
                if str(count) in channel_list:
                    if np.logical_and(count < n_chan, len(np.shape(img)) > 2):
                        cleaned_channel = img[:, :, count] / bg
                        cleaned_channel = filters.gaussian(cleaned_channel,
                                                           sigma=2)
                        ch_otsu = filters.threshold_otsu(cleaned_channel)
                        ch_feat_mask = morphology.binary_erosion(
                            cleaned_channel > ch_otsu)
                        ch_feat_mask = morphology.remove_small_objects(
                            ch_feat_mask, 2)

                        cell_ch_labels = measure.label(
                            (labeled_cells == c) * ch_feat_mask)
                        cell_ch_props = measure.regionprops(
                            cell_ch_labels, img[:, :, count])
                        ch_feat_areas = np.array(
                            [r.area for r in cell_ch_props])
                        ch_feat_means = np.array(
                            [r.mean_intensity for r in cell_ch_props])
                        ch_feat_maxes = np.array(
                            [r.max_intensity for r in cell_ch_props])
                        ch_feat_mins = np.array(
                            [r.min_intensity for r in cell_ch_props])
                        img_df.loc[img_df.index[c], 'num_features_ch' +
                                   str(count)] = len(cell_ch_props)

                        if len(cell_ch_props) > 0:
                            img_df.loc[img_df.index[c], 'log_num_features_ch' +
                                       str(count)] = np.log10(
                                           len(cell_ch_props))
                        else:
                            img_df.loc[img_df.index[c], 'log_num_features_ch' +
                                       str(count)] = 0.01

                        img_df.loc[img_df.index[c], 'avg_feature_area_ch' +
                                   str(count)] = np.mean(ch_feat_areas)
                        img_df.loc[img_df.index[c], 'log_avg_feature_area_ch' +
                                   str(count)] = np.log10(
                                       np.mean(ch_feat_areas))
                        img_df.loc[img_df.index[c], 'median_feature_area_ch' +
                                   str(count)] = np.median(ch_feat_areas)
                        img_df.loc[img_df.index[c], 'avg_feature_int_ch' +
                                   str(count)] = np.mean(ch_feat_means)
                        img_df.loc[img_df.index[c], 'avg_feature_max_ch' +
                                   str(count)] = np.mean(ch_feat_maxes)
                        img_df.loc[img_df.index[c], 'avg_feature_min_ch' +
                                   str(count)] = np.mean(ch_feat_mins)
                        img_df.loc[img_df.index[c], 'feature_coverage_%_ch' +
                                   str(count)] = np.sum(
                                       ch_feat_mask *
                                       (labeled_cells == c)) / np.sum(
                                           labeled_cells == c)
                        img_df.fillna(0, inplace=True)

            try:
                c
            except:
                print('no cells detected')
            else:
                if count == len(cell_props.keys()) - 1:
                    pct_done = 100.00
                    print('img ' + str(pct_done) + '% complete ' +
                          '(channel ' + str(count + 1) + ' of ' +
                          str(len(cell_props.keys())) + ', cell ' +
                          str(c + 1) + ' of ' + str(len(channel_data)) + ')')

                if np.logical_and(count < n_chan, len(np.shape(img)) > 2):
                    if str(count) in channel_list:
                        img_df['log_avg_feature_area_ch' +
                               str(count)] = img_df['log_avg_feature_area_ch' +
                                                    str(count)].replace(
                                                        0, 0.01)
                        img_df['log_num_features_ch' +
                               str(count)] = img_df['log_num_features_ch' +
                                                    str(count)].replace(
                                                        0, 0.01)

        results_df = pd.concat([results_df, img_df])
        results_df.fillna(0, inplace=True)

    results_df.to_csv(save_path + '/' + '_cell_datasheet.csv')
    return results_df, save_path, n_chan
def pixelwise_transform(mask, dilation_radius=None, data_format=None,
                        separate_edge_classes=False):
    """Transforms a label mask for a z stack edge, interior, and background

    Args:
        mask (tensor): tensor of labels
        dilation_radius (int):  width to enlarge the edge feature of
            each instance
        data_format (str): 'channels_first' or 'channels_last'
        separate_edge_classes (bool): Whether to separate the cell edge class
            into 2 distinct cell-cell edge and cell-background edge classes.

    Returns:
        numpy.array: one-hot encoded tensor of masks:
            if not separate_edge_classes: [cell_edge, cell_interior, background]
            otherwise: [bg_cell_edge, cell_cell_edge, cell_interior, background]
    """
    if data_format is None:
        data_format = K.image_data_format()

    if data_format == 'channels_first':
        channel_axis = 0
    else:
        channel_axis = -1

    # Detect the edges and interiors
    new_mask = np.zeros(mask.shape)
    strel = ball(1) if mask.ndim > 2 else disk(1)
    for cell_label in np.unique(mask):
        if cell_label != 0:
            # get the cell interior
            img = mask == cell_label
            img = binary_erosion(img, strel)
            new_mask += img

    interior = np.multiply(new_mask, mask)
    edge = (mask - interior > 0).astype('int')
    interior = (interior > 0).astype('int')

    if not separate_edge_classes:
        if dilation_radius:
            dil_strel = ball(dilation_radius) if mask.ndim > 2 else disk(dilation_radius)
            # Thicken cell edges to be more pronounced
            edge = binary_dilation(edge, selem=dil_strel)

            # Thin the augmented edges by subtracting the interior features.
            edge = (edge - interior > 0).astype('int')

        background = (1 - edge - interior > 0)
        background = background.astype('int')

        all_stacks = [
            edge,
            interior,
            background
        ]

        return np.stack(all_stacks, axis=channel_axis)

    # dilate the background masks and subtract from all edges for background-edges
    background = (mask == 0).astype('int')
    dilated_background = binary_dilation(background, strel)

    background_edge = (edge - dilated_background > 0).astype('int')

    # edges that are not background-edges are interior-edges
    interior_edge = (edge - background_edge > 0).astype('int')

    if dilation_radius:
        dil_strel = ball(dilation_radius) if mask.ndim > 2 else disk(dilation_radius)
        # Thicken cell edges to be more pronounced
        interior_edge = binary_dilation(interior_edge, selem=dil_strel)
        background_edge = binary_dilation(background_edge, selem=dil_strel)

        # Thin the augmented edges by subtracting the interior features.
        interior_edge = (interior_edge - interior > 0).astype('int')
        background_edge = (background_edge - interior > 0).astype('int')

    background = (1 - background_edge - interior_edge - interior > 0)
    background = background.astype('int')

    all_stacks = [
        background_edge,
        interior_edge,
        interior,
        background
    ]

    return np.stack(all_stacks, axis=channel_axis)
Esempio n. 58
0
import numpy as np
import matplotlib.pyplot as plt
import imageio
import libreria as lib

from skimage.color import rgb2lab
from skimage.morphology import binary_closing, binary_erosion
from os import scandir, getcwd
from os.path import abspath


def ls(ruta=getcwd()):
    return [arch.name for arch in scandir(ruta) if arch.is_file()]


cad = 'C:/Users/nineil/Desktop/Jeffri/USP/Procesamiento de Imagenes/Proyecto_PI/DataSegmentada/Opcional/plagaT/'
A = ls(cad)

for i in A:
    print(i)
    C = cad + i
    I = imageio.imread(C)
    imglab = rgb2lab(I)  # Conversão de RGB a lab
    imglab = (imglab + [0, 128, 128]) / [100, 255, 255]  # Normalizaçã0
    imglab = imglab[:, :, 1]  # Canal a*

    mask = binary_erosion(binary_closing(imglab > 0.49, np.ones(
        (3, 3))))  # operaçiões morfologicas
    R = lib.segmenta(I, mask)
    D = 'C:/Users/nineil/Desktop/Jeffri/USP/Procesamiento de Imagenes/Proyecto_PI/DataSegmentada/Experimento/T/' + i
    imageio.imwrite(D, R)
Esempio n. 59
0
#####background normalization
mode = stats.mode(norobot, axis=None)[0][0]
for l in range(data_train.shape[1]):
    for j in range(data_train.shape[2]):
        norobot[l, j] = min(1., norobot[l, j] / mode)

##invert the image, we will need this image for the classification
norobot_inv = util.invert(norobot)

#####Remove dark bg and line in the middle and find regions

#Threshold
norobot_line = norobot[:] > 0.8
#Dilate the dark regions (i.e. erode the image)
norobot_line = morphology.binary_erosion(norobot_line, morphology.square(10))

norobot_bin = norobot[:] > 0.8

#Find regions
labels_line = measure.label(util.invert(norobot_line))
regions_line = measure.regionprops(labels_line)
#Remove the biggest areas, i.e. line, borders
labels_toremove = []
for i, region in enumerate(regions_line):
    if (region.area > 2000):
        labels_toremove.append(i + 1)
for lab in labels_toremove:
    for lin in range(len(labels_line)):
        for col in range(len(labels_line[lin])):
            if (labels_line[lin, col] == lab):
Esempio n. 60
0
def save_img(org_img, mask_path, data_save_path, img_name, prob_map, err_coord, crop_coord, DiscROI_size, org_img_size, threshold=0.5, pt=False):
    path = os.path.join(data_save_path, img_name)
    path0 = os.path.join(data_save_path+'/visulization/', img_name.split('.')[0]+'.png')
    if not os.path.exists(os.path.dirname(path0)):
        os.makedirs(os.path.dirname(path0))
   
    disc_map = resize(prob_map[:, :, 0], (DiscROI_size, DiscROI_size))
    cup_map = resize(prob_map[:, :, 1], (DiscROI_size, DiscROI_size))

    if pt:
        disc_map = cv2.linearPolar(rotate(disc_map, 90), (DiscROI_size/2, DiscROI_size/2),
                                          DiscROI_size/2, cv2.WARP_FILL_OUTLIERS + cv2.WARP_INVERSE_MAP)
        cup_map = cv2.linearPolar(rotate(cup_map, 90), (DiscROI_size/2, DiscROI_size/2),
                                         DiscROI_size/2, cv2.WARP_FILL_OUTLIERS + cv2.WARP_INVERSE_MAP)

    mask_path = os.path.join(mask_path, img_name.split('.')[0]+'.bmp')
    if os.path.exists(mask_path):
        fig, (ax1,ax2,ax3, ax4) = plt.subplots(nrows=1, ncols=4)  # create figure & 1 axis
    else:
        fig, (ax1, ax2, ax3) = plt.subplots(nrows=1, ncols=3)
    # ax0, ax1, ax2 = axes.ravel()
    ax1.imshow(org_img)
    ax2.imshow(org_img)
    ax3.imshow(org_img)

    ax1.set_xticks([])
    ax1.set_yticks([])
    ax1.set_title('initial image', fontsize=4, color='b')
    # plt.figure(dpi=600)
    #import pdb;pdb.set_trace()
    disc_mask = (disc_map > threshold) # return binary mask
    cup_mask = (cup_map > threshold)
    disc_mask = disc_mask.astype(np.uint8)
    cup_mask = cup_mask.astype(np.uint8)

    contours_disc = measure.find_contours(disc_mask, 0.5)
    contours_cup = measure.find_contours(cup_mask, 0.5)
    for n, contour in enumerate(contours_disc):
        ax2.plot(contour[:, 1] + crop_coord[2] - err_coord[2], contour[:, 0] + crop_coord[0] - err_coord[0], 'b', linewidth=0.2)
    for n, contour in enumerate(contours_cup):
        ax2.plot(contour[:, 1] + crop_coord[2] - err_coord[2], contour[:, 0] + crop_coord[0] - err_coord[0], 'g', linewidth=0.2)

    for i in range(5):
        disc_mask = scipy.signal.medfilt2d(disc_mask, 7)
        cup_mask = scipy.signal.medfilt2d(cup_mask, 7)
    disc_mask = morphology.binary_erosion(disc_mask, morphology.diamond(7)).astype(np.uint8) # return 0,1
    cup_mask = morphology.binary_erosion(cup_mask, morphology.diamond(7)).astype(np.uint8) # return 0,1
    disc_mask = get_largest_fillhole(disc_mask)
    cup_mask = get_largest_fillhole(cup_mask)

    disc_mask = morphology.binary_dilation(disc_mask, morphology.diamond(7)).astype(np.uint8)  # return 0,1
    cup_mask = morphology.binary_dilation(cup_mask, morphology.diamond(7)).astype(np.uint8)  # return 0,1

    disc_mask = get_largest_fillhole(disc_mask).astype(np.uint8) # return 0,1
    cup_mask = get_largest_fillhole(cup_mask).astype(np.uint8)
    ROI_result = disc_mask + cup_mask
    ROI_result[ROI_result < 1] = 255
    ROI_result[ROI_result < 2] = 128
    ROI_result[ROI_result < 3] = 0

    Img_result = np.zeros((org_img_size[0], org_img_size[1], 3), dtype=int) + 255
    Img_result[crop_coord[0]:crop_coord[1], crop_coord[2]:crop_coord[3], 0] = ROI_result[err_coord[0]:err_coord[1],
                                                                              err_coord[2]:err_coord[3]]
    # for submit
    cv2.imwrite(path, Img_result[:, :, 0])

    contours_disc = measure.find_contours(disc_mask, 0.5)
    contours_cup = measure.find_contours(cup_mask, 0.5)
    for n, contour in enumerate(contours_disc):
        ax3.plot(contour[:, 1] + crop_coord[2] - err_coord[2], contour[:, 0] + crop_coord[0] - err_coord[0], 'b',
                 linewidth=0.2)
    for n, contour in enumerate(contours_cup):
        ax3.plot(contour[:, 1] + crop_coord[2] - err_coord[2], contour[:, 0] + crop_coord[0] - err_coord[0], 'g',
                 linewidth=0.2)

    ax2.set_xticks([])
    ax2.set_yticks([])
    ax2.set_title('raw image', fontsize=4, color='b')
    ax3.set_xticks([])
    ax3.set_yticks([])
    ax3.set_title('smooth image', fontsize=4, color='b')

    if os.path.exists(mask_path):
        ax4.imshow(org_img)
        mask = np.asarray(image.load_img(mask_path))
        disc_mask, cup_mask = transfer_mask2maps(mask)
        print('onon3')
        contours_disc = measure.find_contours(disc_mask, 0.5)
        contours_cup = measure.find_contours(cup_mask, 0.5)
        for n, contour in enumerate(contours_disc):
            ax4.plot(contour[:, 1], contour[:, 0], 'b',
                     linewidth=0.2)
        for n, contour in enumerate(contours_cup):
            ax4.plot(contour[:, 1], contour[:, 0], 'g',
                     linewidth=0.2)
        ax4.set_xticks([])
        ax4.set_yticks([])
        ax4.set_title('ground truth', fontsize=4, color='b')
        fig.savefig(path0, dpi=600, bbox_inches='tight')  # save the figure to file
        plt.close(fig)
    else:
        fig.savefig(path0, dpi=600, bbox_inches='tight')  # save the figure to file
        plt.close(fig)