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
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)
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
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