Esempio n. 1
0
 def make_mask(self):
     mask = copy.copy(self.img)
     mask = spacetransformer.im2c(mask, 8)
     nrows, ncols = mask.shape
     row, col = np.ogrid[:nrows, :ncols]
     cnt_row, cnt_col = nrows / 2, ncols / 2
     outer_disk_mask = ((row - cnt_row)**2 + (col - cnt_col)**2 < (nrows / 2)**2)
     mask[mask<0.3] = -1
     mask[outer_disk_mask==0] = -1
     self.mask = mask
def cell_watershed(img):
    """
    Performs watershed on an RGB-image. Returns the image with the new boarders and the markers
    """
    img = img[:,:,0:3]
    kernel = np.ones((3,3),np.uint8)

    # Mask the background to get the whole cells
    color = 10
    bg_transform = spacetransformer.im2c(img, color)
    bg_transform = np.array(bg_transform * 255, dtype=np.uint8)
    bg_img = bg_transform.copy()
    unknown_mask = bg_transform.copy()
    unknown_mask[bg_img<=0.45*np.amax(bg_img)] = 0
    unknown_mask[bg_img>0.45*np.amax(bg_img)] = 1

    # Erode and close to remove trash
    #unknown_mask = cv2.erode(unknown_mask, kernel, iterations =1)
    unknown_mask = cv2.morphologyEx(unknown_mask,cv2.MORPH_CLOSE,kernel, iterations = 2)


    # Mask to get the nuclei
    color = 4
    nuclei = spacetransformer.im2c(img, color)
    nuclei = np.array(nuclei * 255, dtype=np.uint8)
    nuclei_mask = nuclei.copy()
    nuclei_mask[nuclei< 0.07*np.amax(nuclei)] = 1 #0.05
    nuclei_mask[nuclei>=0.07*np.amax(nuclei)] = 0

    # Dilate and close to fill the nuclei
    nuclei_mask = cv2.dilate(nuclei_mask, kernel, iterations = 1)
    nuclei_mask = cv2.erode(nuclei_mask, kernel, iterations = 2)
    #nuclei_mask = cv2.morphologyEx(nuclei_mask,cv2.MORPH_CLOSE,kernel, iterations = 2)

    nuclei_mask[nuclei_mask > 0] = 1

    unknown_mask[unknown_mask > 0] = 1

    # Create image with unknown region (between membrane and nucleus)
    unknown_region = nuclei_mask - unknown_mask
    unknown_region[unknown_region > 0] = 1

    #plt.figure("unknown_region")
    #plt.imshow(unknown_region)
    #plt.figure("unknown_mask")
    #plt.imshow(unknown_mask)
    plt.figure("nuclei_mask")
    plt.imshow(nuclei_mask)
    #print(np.amax(unknown_region))
    #print(np.amax(unknown_mask))
    #print(np.amax(nuclei_mask))
    # Create the markers for the nuclei
    ret, markers_nuc = cv2.connectedComponents(nuclei_mask)

    # Add the markers for the nuclei with the mask for the whole cells
    markers = markers_nuc.copy()
    markers += 1
    ret += 1
    markers[unknown_region == 0] = 0

    # Create a background image to use in the watershed
    background = img.copy()
    background[:,:,0] = unknown_mask*255
    background[:,:,1] = unknown_mask*255
    background[:,:,2] = unknown_mask*255


    # Perform watershed and mark the boarders on the image
    markers = cv2.watershed(background, markers)
    img[markers == -1] = [255,0,0]

    return img, ret, markers, nuclei_mask
Esempio n. 3
0
import numpy as np
import cv2
import pylab
import copy
from ColourNM import spacetransformer


WBCarray = []
WBCarray_hsv = []
WBCarray_bw = []

for i in range(1, 21):
    # WBCarray.append(np.load("white_" + str(i) + ".npy"));
    WBCarray_hsv.append(cv2.cvtColor(np.load("white_" + str(i) + ".npy"), cv2.COLOR_BGR2HSV))
    # WBCarray_bw.append(cv2.cvtColor(np.load("white_" + str(i) + ".npy"), cv2.COLOR_BGR2GRAY))
    WBCarray_bw.append(spacetransformer.im2c(np.load("white_" + str(i) + ".npy"), 8))

WBC_masked = []
for i in range(0, 20):
    # plt.figure(1)
    test_img = copy.copy(WBCarray_bw[i])
    nrows, ncols = test_img.shape
    row, col = np.ogrid[:nrows, :ncols]
    cnt_row, cnt_col = nrows / 2, ncols / 2
    outer_disk_mask = (row - cnt_row) ** 2 + (col - cnt_col) ** 2 < (nrows / 2) ** 2
    # test_img[outer_disk_mask==0] = -1
    test_img[test_img < 0.3] = -1
    test_img[outer_disk_mask == 0] = -1
    WBC_masked.append(test_img)
    # plt.subplot(5,4,i+1)
    # plt.imshow(test_img)
Esempio n. 4
0
 def hist_features(self, color, bins, interval = [0,1]):
     col = spacetransformer.im2c(self.img, color)
     col[self.mask == -1] = -1
     hist,_ = np.histogram(col,bins,interval)
     hist = hist/float(np.size(col[col>=0]))
     return hist
Esempio n. 5
0
 def get_mean_var_energy(self, color):
     col = spacetransformer.im2c(self.img, color)
     energy = np.sum(np.power(col, 2))/self.size
     return [np.mean(col), np.var(col), energy]
def cell_watershed(img):
    """
    Performs watershed on an RGB-image. Returns the image with the new boarders and the markers
    """

    img = img[:,:,0:3]
    kernel = np.ones((3,3),np.uint8)

    # Mask the background to get the whole cells
    color = 10
    bg_transform = spacetransformer.im2c(img, color)
    bg_transform = np.array(bg_transform * 255, dtype=np.uint8)
    blur = cv2.GaussianBlur(bg_transform,(5,5),0)
    thres,unknown_mask = cv2.threshold(bg_transform,0,1,cv2.THRESH_BINARY+cv2.THRESH_OTSU)

    # Erode and close to remove trash
    unknown_mask = cv2.morphologyEx(unknown_mask,cv2.MORPH_OPEN,kernel, iterations = 2)

    # Get colorspace 4 and set the background of whole cells to -1
    color = 4
    nuclei = spacetransformer.im2c(img, color)
    nuclei = np.array(nuclei * 255, dtype=np.uint8)
    nuclei[unknown_mask == 1] = -1

    # Equalize histogram and blur image
    nuclei = cv2.equalizeHist(nuclei)
    blur = cv2.GaussianBlur(nuclei,(5,5),0)
    blur = cv2.medianBlur(blur,11)

    # Get threshold and mask the image to get nuclei set background of the whole cells to 0
    hist,_ = np.histogram(blur,255,[0,254])
    thres = get_threshold(hist)
    _,nuclei_mask = cv2.threshold(blur,thres,1,cv2.THRESH_BINARY_INV)
    nuclei_mask[unknown_mask == 1] = 0

    # Get contours and find joined nuclei, look at hull if possible
    _, all_nuclei_cont, _ = cv2.findContours(nuclei_mask.copy(), 1, 2)
    joined_nuclei_cont = []
    max_radius = 0
    for c in all_nuclei_cont:
        (x,y), radius = cv2.minEnclosingCircle(c)
        if radius > 0:
            center = (int(x),int(y))
            radius = int(radius)
            if radius > max_radius:
                max_radius = radius
            circle_area = 3.14*radius*radius
            nuclei_area = cv2.contourArea(c)
            if nuclei_area/circle_area < .6 and nuclei_area > 150:
                joined_nuclei_cont.append(c)

    # Draw contours of joined nuclei
    empty = np.zeros(np.shape(nuclei))
    empty = np.array(empty*255, dtype=np.uint8)
    joined_nuclei = empty.copy()
    cv2.drawContours(joined_nuclei, joined_nuclei_cont, -1, (255,255,255), -1)

    # Erode joined nuclei and get new contours
    kernelll = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (20,20))
    eroded_joined_nuclei = cv2.erode(joined_nuclei,kernelll,iterations=1)
    _, eroded_nuclei_cont,_ = cv2.findContours(eroded_joined_nuclei.copy(), 1, 2)


    # Find contours to be removed, assumed to be joined red blood cells
    cells_to_remove = []
    for i,c in enumerate(joined_nuclei_cont):
        x,y,w,h = cv2.boundingRect(c)
        erode = eroded_joined_nuclei[y:y+h,x:x+w]
        temp = np.zeros(np.shape(erode))
        cv2.drawContours(temp, [c], -1, (1,1,1), -1, offset=(-x,-y))
        if np.sum(temp*erode) == 0:
            cells_to_remove.append(c)

    cells_to_remove_im = empty.copy()
    cv2.drawContours(cells_to_remove_im, cells_to_remove, -1, (255,255,255), -1)

    # Get new mask for large nuclei
    joined_mask, large_nuclei_cont = mask_joined_WBC(eroded_nuclei_cont, nuclei_mask, max_radius)

    # Create the markers for the nuclei
    ret, markers_nuc = cv2.connectedComponents(nuclei_mask)
    markers_nuc[markers_nuc == 0] = -1
    markers_nuc = markers_nuc + 1

    # Add the markers for the nuclei and the mask for the whole cells
    markers = markers_nuc | unknown_mask

    # Create a background image to use in watershed
    background =img.copy()
    background[:,:,0] = unknown_mask*255
    background[:,:,1] = unknown_mask*255
    background[:,:,2] = unknown_mask*255

    ###save images!!###
    im = Image.fromarray(bg_transform)
    im.save('../results/bg_transform.png')

    im = Image.fromarray(nuclei)
    im.save('../results/nuclei.png')

    im = Image.fromarray(markers)
    im.save('../results/watershed_result.png')

    # Perform watershed and mark the borders on the image
    markers = cv2.watershed(background, markers)

    # Get an image of the markers and find contours
    cytoplasm_markers_im = empty.copy()
    cytoplasm_markers_im[markers > 1] = 1
    cytoplasm_markers_im[markers == -1] = 0
    cytoplasm_markers_im = cv2.erode(cytoplasm_markers_im, np.ones(2)) #ska det inte vara en (2,2)
    _,cytoplasm_cont,_ = cv2.findContours(cytoplasm_markers_im, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)

    to_be_removed = []
    to_be_inserted = []
    removed_cells = []
    exchanged_cells = []

    for i,c in enumerate(cytoplasm_cont):
        x,y,w,h = cv2.boundingRect(c)
        cell_img = cells_to_remove_im[y:y+h,x:x+w]
        join = joined_mask[y:y+h,x:x+w]
        emp = np.zeros(np.shape(cell_img))
        temp = emp.copy()
        cv2.drawContours(temp, [c], -1, (1,1,1), -1, offset=(-x,-y))
        if np.sum(temp*cell_img) > 0:
            to_be_removed.append(i)
            removed_cells.append(c)
        if np.sum(temp*join)> 0:
            to_be_removed.append(i)
            exchanged_cells.append(c)
            for con in large_nuclei_cont:
                joined = emp.copy()
                cv2.drawContours(joined, [con], -1, (1,1,1), -1,offset=(-x,-y))
                if np.sum(temp*joined) > 0:
                    to_be_inserted.append(con)

    for i in sorted(to_be_removed, reverse=True):
        del cytoplasm_cont[i]

    for con in to_be_inserted:
        cytoplasm_cont.append(con)

    return cytoplasm_cont, nuclei_mask, removed_cells, exchanged_cells