def separate_channels(image_original, matrix_dh): """ Separate the stains using the custom matrix """ image_separated = color.separate_stains(image_original, matrix_dh) stain_dab = image_separated[..., 1] # Hematox channel separation is disabled, it could be switched on if image with both stains is needed. # one of plot_figure() subplots should be replaced with stainHematox # stainHematox = image_separated[..., 0] # 1-D array for histogram conversion, 1 was added to move the original range from # [-1,0] to [0,1] as black and white respectively. Warning! Magic numbers. # Anyway it's not a trouble for correct thresholding. Only for histogram aspect. stain_dab = (stain_dab + 1) * 200 # Histogram shift. This correcion makes the background really blank. After the correction # numpy clipping is performed to fit the 0-100 range stain_dab -= 18 stain_dab = np.clip(stain_dab, 0, 100) stain_dab_1d = np.ravel(stain_dab) # Extracting Lightness channel from HSL of original image # L-channel is multiplied to 100 to get the range 0-100 % from 0-1. It's easier to use with # empty area threshold image_hsl = hasel.rgb2hsl(image_original) channel_lightness = (image_hsl[..., 2] * 100) return stain_dab, stain_dab_1d, channel_lightness
def test_hdx_rgb_roundtrip(self): from skimage.color.colorconv import hdx_from_rgb, rgb_from_hdx img_rgb = self.img_rgb conv = combine_stains(separate_stains(img_rgb, hdx_from_rgb), rgb_from_hdx) with expected_warnings('precision loss'): assert_equal(img_as_ubyte(conv), img_rgb)
def test_hdx_rgb_roundtrip(self): from skimage.color.colorconv import hdx_from_rgb, rgb_from_hdx img_rgb = self.img_rgb conv = combine_stains(separate_stains(img_rgb, hdx_from_rgb), rgb_from_hdx) with expected_warnings(['precision loss']): assert_equal(img_as_ubyte(conv), img_rgb)
def patch_operations(patch, mydoc): # Convert to grayscale img = patch.convert('L') # img to array img_array = np.array(img) # Intensity for all pixels, divided by num pixels mydoc['grayscale_patch_mean'] = np.mean(img_array) mydoc['grayscale_patch_std'] = np.std(img_array) # Intensity for all pixels inside segmented objects... # mydoc.grayscale_segment_mean = "n/a" # mydoc.grayscale_segment_std = "n/a" # Convert to RGB img = patch.convert('RGB') img_array = np.array(img) hed_title_img = separate_stains(img_array, hed_from_rgb) max1 = np.max(hed_title_img) min1 = np.min(hed_title_img) new_img_array = hed_title_img[:, :, 0] new_img_array = ((new_img_array - min1) * 255 / (max1 - min1)).astype( np.uint8) mydoc['hematoxylin_patch_mean'] = np.mean(new_img_array) mydoc['hematoxylin_patch_std'] = np.std(new_img_array) # mydoc.Hematoxylin_segment_mean = "n/a" # mydoc.Hematoxylin_segment_std = "n/a" return mydoc
def rgb2stain(img, diameter=3): mask = im2bw(rgb2gray(img)) mask = binary_erosion(mask, disk(diameter)).astype(np.uint8) img_t = separate_stains(img, bex_from_rgb) img_t = img_as_ubyte(img_normalization(img_t)) return img_t * np.expand_dims(mask, axis=2)
def color_deconvolution(img, sep_matrix, comb_matrix, component_idx): separated = separate_stains(img, sep_matrix) stains = np.zeros_like(separated) stains[:, :, component_idx] = separated[:, :, component_idx] combined = combine_stains(stains, comb_matrix) return _convert(combined, img.dtype)
def rgb2he(img, normalize=False): """ RGB2HE: Extracts the haematoxylin and eosin components from an RGB color. h,e = rgb2he(img, normalize=False) Args: img (numpy.ndarray): and RGB image; no check for actual color space is performed normalize (bool): should the values be linearly transformed, to ensure they are all between -1.0 and 1.0 Returns: tuple. Contains two intensity images as numpy.ndarray, coding for the haematoxylin and eosin components, respectively. The values are in the "H&E" space or in -1..1 (if normalize==True) """ # my color separation matrices # (from http://www.mecourse.com/landinig/software/colour_deconvolution.zip) # The code commented out below was used to generate the "he1_from_rgb" matrix. # After the matrix was obtained, it has been hard coded, for computation # efficiency: # rgb_from_he1 = np.array([[0.644211, 0.716556, 0.266844], # [0.092789, 0.954111, 0.283111], # [0.0, 0.0, 0.0]]) # rgb_from_he1[2, :] = np.cross(rgb_from_he1[0, :], rgb_from_he1[1, :]) # he1_from_rgb = linalg.inv(rgb_from_he1) he1_from_rgb = np.array([[1.73057512, -1.3257525, -0.1577248], [-0.19972397, 1.1187028, -0.48055639], [0.10589662, 0.19656106, 1.67121469]]) img_tmp = separate_stains(img_as_ubyte(img), he1_from_rgb) # The RGB -> H&E transformation maps: # black (0,0,0) |-> (-1.13450710, 0.00727017021) # white (255,255,255) |-> (-9.08243792, 0.05.82022531) # red (255,0,0) |-> (-9.53805685, 6.44503007) # green (0,255,0) |-> (-0.164661728, -5.42507111) # blue (0,0,255) |-> (-1.64873355, -0.947216369) if normalize: img_tmp[:, :, 0] = 2 * (img_tmp[:, :, 0] + 9.53805685) / (-0.164661728 + 9.53805685) - 1 img_tmp[img_tmp[:, :, 0] < -1.0, 0] = -1.0 img_tmp[img_tmp[:, :, 0] > 1.0, 0] = 1.0 img_tmp[:, :, 1] = 2 * (img_tmp[:, :, 1] + 5.42507111) / (6.44503007 + 5.42507111) - 1 img_tmp[img_tmp[:, :, 1] < -1.0, 0] = -1.0 img_tmp[img_tmp[:, :, 1] > 1.0, 0] = 1.0 return img_tmp[:, :, 0], img_tmp[:, :, 1]
def test_bro_rgb_roundtrip_float(self, channel_axis): from skimage.color.colorconv import bro_from_rgb, rgb_from_bro img_in = self.img_stains img_in = np.moveaxis(img_in, source=-1, destination=channel_axis) img_out = combine_stains(img_in, rgb_from_bro, channel_axis=channel_axis) img_out = separate_stains(img_out, bro_from_rgb, channel_axis=channel_axis) assert_array_almost_equal(img_out, img_in)
def rgb2he(img, normalize=False): """ RGB2HE: Extracts the haematoxylin and eosin components from an RGB color. h,e = rgb2he(img, normalize=False) Args: img (numpy.ndarray): and RGB image; no check for actual color space is performed normalize (bool): should the values be linearly transformed, to ensure they are all between -1.0 and 1.0 Returns: tuple. Contains two intensity images as numpy.ndarray, coding for the haematoxylin and eosin components, respectively. The values are in the "H&E" space or in -1..1 (if normalize==True) """ # my color separation matrices # (from http://www.mecourse.com/landinig/software/colour_deconvolution.zip) # The code commented out below was used to generate the "he1_from_rgb" matrix. # After the matrix was obtained, it has been hard coded, for computation # efficiency: # rgb_from_he1 = np.array([[0.644211, 0.716556, 0.266844], # [0.092789, 0.954111, 0.283111], # [0.0, 0.0, 0.0]]) # rgb_from_he1[2, :] = np.cross(rgb_from_he1[0, :], rgb_from_he1[1, :]) # he1_from_rgb = linalg.inv(rgb_from_he1) he1_from_rgb = np.array([[ 1.73057512, -1.3257525 , -0.1577248 ], [-0.19972397, 1.1187028 , -0.48055639], [ 0.10589662, 0.19656106, 1.67121469]]) img_tmp = separate_stains(img_as_ubyte(img), he1_from_rgb) # The RGB -> H&E transformation maps: # black (0,0,0) |-> (-1.13450710, 0.00727017021) # white (255,255,255) |-> (-9.08243792, 0.05.82022531) # red (255,0,0) |-> (-9.53805685, 6.44503007) # green (0,255,0) |-> (-0.164661728, -5.42507111) # blue (0,0,255) |-> (-1.64873355, -0.947216369) if normalize: img_tmp[:,:,0] = 2*(img_tmp[:,:,0] + 9.53805685) / (-0.164661728 + 9.53805685) - 1 img_tmp[img_tmp[:,:,0] < -1.0, 0] = -1.0 img_tmp[img_tmp[:,:,0] > 1.0, 0] = 1.0 img_tmp[:,:,1] = 2*(img_tmp[:,:,1] + 5.42507111) / (6.44503007 + 5.42507111) - 1 img_tmp[img_tmp[:,:,1] < -1.0, 0] = -1.0 img_tmp[img_tmp[:,:,1] > 1.0, 0] = 1.0 return img_tmp[:, :, 0], img_tmp[:, :, 1]
def round_image(image): out = image.copy() out *= 255 out = np.array(out, dtype=np.uint8) return out ihc_hed = col.separate_stains(self.image[:, :, ::-1], col.hed_from_rgb) t1 = normalize_shift(ihc_hed[:, :, 2]).copy() THRESHOLD = 0.73 t1[np.where(t1 < THRESHOLD)] = 0 #image_show(t1) t1 = round_image(opening(t1, kernel)) image_show(t1) hstrong = np.count_nonzero(t1) return hstrong, t1, ihc_hed
def rgb_to_stain(rgb_img_matrix, sizex, sizey): """ RGB to stain color space conversion :param rgb_img_matrix: :param sizex: :param sizey: :return: """ hed_title_img = separate_stains(rgb_img_matrix, hed_from_rgb) hematoxylin_img_array = [[0 for x in range(sizex)] for y in range(sizey)] for index1, row in enumerate(hed_title_img): for index2, pixel in enumerate(row): hematoxylin_img_array[index1][index2] = pixel[0] return hematoxylin_img_array
def getPASnuclei(im_PAS, Glommask, int_thre, size_thre, gauss_filt_size, watershed_dist_thre, disc_size): PASnuc = separate_stains(im_PAS, hpx_from_rgb) PASnuc_extract = rescale_intensity(PASnuc[:, :, 0], out_range=(0, 1)) kernel = np.ones((gauss_filt_size, gauss_filt_size), np.float32) / 25 PASnuc_extract = cv2.filter2D(PASnuc_extract, -1, kernel) PAS_nuclei = ((PASnuc_extract > int_thre) * 1) PAS_nuc_label = label(PAS_nuclei) PAS_nuclei = morphology.opening(PAS_nuc_label, morphology.disk(disc_size)) PAS_nuclei = remove_small_objects(label(PAS_nuclei), min_size=size_thre / 3) label_nuc = label(PAS_nuclei) PAS_nuclei2 = remove_small_objects(label_nuc, min_size=size_thre) try: distance = ndi.distance_transform_edt(PAS_nuclei2) coords = peak_local_max(distance, min_distance=watershed_dist_thre, exclude_border=False, footprint=np.ones((2, 2)), labels=PAS_nuclei2) mask = np.zeros(distance.shape, dtype=bool) mask[tuple(coords.T)] = True markers, _ = ndi.label(mask) labels = watershed(-distance, markers, mask=PAS_nuclei, watershed_line=True) labels = remove_small_objects(labels, min_size=size_thre / 5) #REst = 3, NTN = 5 singlenuc = ((PAS_nuclei > 0) * 1 - (PAS_nuclei2 > 0) * 1) doublesepnuc = (labels > 0) * 1 separatednucPAS = ((singlenuc + doublesepnuc) * Glommask) > 0 * 1 except: print('watershed fix') separatednucPAS = (PAS_nuclei * Glommask) > 0 * 1 err_nuclei = remove_small_objects(label(separatednucPAS), min_size=size_thre * 6) final_out = (separatednucPAS > 0) * 1 - (err_nuclei > 0) * 1 return final_out
def seperateStains(s, params): logging.info(f"{s['filename']} - \tseperateStains") stain = params.get("stain", "") use_mask = strtobool(params.get("use_mask", "True")) if stain == "": logging.error( f"{s['filename']} - stain not set in DeconvolutionModule.seperateStains" ) sys.exit(1) return stain_matrix = getattr(sys.modules[__name__], stain, "") if stain_matrix == "": logging.error( f"{s['filename']} - Unknown stain matrix specified in DeconolutionModule.seperateStains" ) sys.exit(1) return img = s.getImgThumb(s["image_work_size"]) dimg = separate_stains(img, stain_matrix) for c in range(0, 3): dc = dimg[:, :, c] if use_mask: mask = s["img_mask_use"] dc_sub = dc[mask] dc_min = dc_sub.min() dc_max = dc_sub.max() s.addToPrintList(f"deconv_c{c}_mean", str(dc_sub.mean())) s.addToPrintList(f"deconv_c{c}_std", str(dc_sub.std())) else: mask = 1.0 dc_min = dc.min() dc_max = dc.max() s.addToPrintList(f"deconv_c{c}_mean", str(dc.mean())) s.addToPrintList(f"deconv_c{c}_std", str(dc.std())) dc = (dc - dc_min) / float(dc_max - dc_min) * mask io.imsave(s["outdir"] + os.sep + s["filename"] + f"_deconv_c{c}.png", dc) return
def weak_area(self, debug=False): def opening(image, kernel=None): if kernel==None: kernel = np.ones((3, 3)) out = cv2.erode(image.copy(), kernel) out = cv2.dilate(out.copy(), kernel) return out # def closing(image, kernel=None): # if kernel==None: # kernel = np.ones((2, 2)) # out = cv2.dilate(image.copy(), kernel) # out = cv2.erode(out.copy(), kernel) # return out def normalize_shift(image_orig): image = image_orig.copy() image = (image - np.min(image_orig))/(np.max(image_orig) - np.min(image_orig)) return image def round_image(image): out = image.copy() out *= 255 out = np.array(out, dtype=np.uint8) return out ihc_ahx = col.separate_stains(self.image[:, :, ::-1], col.ahx_from_rgb) if debug: image_show(ihc_ahx[:, :, 0]) t1 = normalize_shift(ihc_ahx[:, :, 0]) #image_show(t1) #print_stats(t1) # THRESHOLD_EOSIN = 0.68 # t[np.where(t < THRESHOLD_EOSIN)] = 0 # t[np.where(t >0)] = 255 t1 = round_image(t1) THRESHOLD = 175 #175 doesn't work for 3pr.svs t1[np.where(t1 < THRESHOLD)] = 0 t1[np.where(t1 > 0)] = 255 #image_show(t1) t1 = opening(t1) if debug: image_show(t1) hweak = np.count_nonzero(t1) print(ihc_ahx.shape) return hweak, t1, ihc_ahx
def separate_colors(self, colors, colorize=True): colors_new = np.vstack([colors, colors[0, :]]) stain_images = [] for id_col in range(colors.shape[0]): color_1 = colors_new[id_col, :] color_2 = colors_new[id_col + 1, :] colors_base = self.find_color_base(color_1, color_2) color_matrix = linalg.inv(colors_base) separated = color.separate_stains(self._image, color_matrix) separated_main = separated[:, :, 0] separated_main = self.maxmin_norm(separated_main) if colorize: separated_main = self._colorize_image(separated_main, color_1) stain_images.append(separated_main) return stain_images
def enhance_contrast(image, clip=True, pct=1, channel=None, conv_matrix=None): """Enhance contrast of input image Parameters ---------- image : ndarray Input image clip : bool Whether to clip the intensity levels pct : scalar Percentage by which to clip intensity channel : int (or None) Which channel (R, B, G) to return (post-deconvolution if `conv_matrix` is given) Should be the case that `channel < image.ndim` conv_matrix : ndarray Stain separation matrix as described by G. Landini [1] Returns ------- out : ndarray Enhanced contrast image References ---------- [1] http://www.mecourse.com/landinig/software/software.html """ out = img_as_float(image) multichannel = image.ndim > 2 # Deconvolve colors if given a convolution matrix if multichannel and conv_matrix is not None: multichannel = True out = separate_stains(out, conv_matrix) # Convert to greyscale if given a channel if channel is not None: out = out[:, :, channel] # Clip intensity levels if clip: out = clip_intensity(out, pct) return rescale_intensity(out, out_range=(0.0, 1.0))
def col_deconv(Img, bias, ki67bias, DiscSize): ihc_hrd_DAB = rgb2hed(Img) ihc_hrd_syn = separate_stains(Img, rbd_from_rgb) print("Color deconvolution...") synaptophysin_1 = rescale_intensity(ihc_hrd_syn[:, :, 1], out_range=(0, 1)) DAB_1 = rescale_intensity(ihc_hrd_DAB[:, :, 2], out_range=(0, 1)) print("Thresholding ki67...") _, thre_ki67 = cv2.threshold(DAB_1, ki67bias, 255, cv2.THRESH_BINARY) print("Otsu thresholding of synaptophysin...") ret, blur_red = cv2.threshold((synaptophysin_1), bias, 255, cv2.THRESH_BINARY) blur_red = dilation(blur_red, disk(DiscSize)) blur_red_mr = erosion(blur_red, disk(DiscSize)) ki_mask_mr2 = cv2.bitwise_and((thre_ki67), (blur_red_mr)) return blur_red_mr, ki_mask_mr2
if not f.endswith(".jpg") : l.remove(f) qstain = np.array([[.26451728, .5205347, .81183386], [.9199094, .29797825, .25489032], [.28947765, .80015373, .5253158]]) for im in l : print im A = transform.rescale(io.imread("../data/" + im), 0.25) deconv = ski.img_as_float(color.separate_stains(A, np.linalg.inv(qstain))) subveins1 = \ morphology.remove_small_objects( filter.threshold_adaptive( filter.gaussian_filter( deconv[:, :, 2] / deconv[:, :, 0], 11), 250, offset = -0.13), 60)
def random_walk_segmentation(input_image, output_folder): input_image = imread(input_image) ihc_hrd = separate_stains(input_image, hrd_from_rgb) DAB_Grey_Array = stainspace_to_2d_array(ihc_hrd, 2) Hema_Gray_Array = stainspace_to_2d_array(ihc_hrd, 0) GBIred_Gray_Array = stainspace_to_2d_array(ihc_hrd, 1) #Perform Random Walker, fills in positive regions DAB_segmentation = random_walker(DAB_Grey_Array, get_markers(DAB_Grey_Array, .3, .5), beta=130, mode='cg_mg') Hema_segmentation = random_walker(Hema_Gray_Array, get_markers(Hema_Gray_Array, .2, .4), beta=130, mode='cg_mg') GBIred_segmentation = random_walker(GBIred_Gray_Array, get_markers(GBIred_Gray_Array, .4, .5), beta=130, mode='cg_mg') '''Compute and Output''' #Compute and output percentages of pixels stained by each chromagen pic_dimensions = np.shape(DAB_segmentation) # both arrays same shape total_pixels = pic_dimensions[0] * pic_dimensions[1] #Change negative pixel values from 1 -> 0, positives 2 -> 1 subtrahend_array = np.ones_like(DAB_segmentation) DAB_segmentation = np.subtract(DAB_segmentation, subtrahend_array) Hema_segmentation = np.subtract(Hema_segmentation, subtrahend_array) GBIred_segmentation = np.subtract(GBIred_segmentation, subtrahend_array) #Count positive pixels DAB_pixels = np.count_nonzero(DAB_segmentation) Hema_pixels = np.count_nonzero(Hema_segmentation) red_pixels = np.count_nonzero(GBIred_segmentation) #Percent of image covered by positive staining DAB_coverage_percent = (round((DAB_pixels / total_pixels * 100), 1)) Hema_coverage_percent = (round((Hema_pixels / total_pixels * 100), 1)) #An overlay of the DAB and Hematoxylin segmented images, for total cellular area total_cell_array = np.add(DAB_segmentation, Hema_segmentation) #Number of pixels covered by cellular area total_cell_pixels = np.count_nonzero(total_cell_array) #Percent of image covered by cellular area (DAB OR Hematoxylin) total_cell_percent = (round((total_cell_pixels / total_pixels * 100), 1)) #The percentage of DAB/CD3+ cells out of the total number of cells percent_pos_cells = (round((DAB_pixels / total_cell_pixels * 100), 1)) #The percentage of the image covered by cytokines Red_coverage_percent = (round((red_pixels / total_pixels * 100), 1)) red_plus_total_array = np.add(total_cell_array, GBIred_segmentation) red_plus_total_pixels = np.count_nonzero(red_plus_total_array) #The percentage of the area covered by cytokines, with non-cellular regions subtracted adjusted_red_coverage_percent = (round( (red_pixels / red_plus_total_pixels * 100), 1)) # Plot images fig, axes = plt.subplots(2, 2, figsize=(12, 11)) ax0, ax1, ax2, ax3 = axes.ravel() ax0.imshow(input_image, cmap=plt.cm.gray, interpolation='nearest') ax0.set_title("Original") ax1.imshow(DAB_segmentation, cmap=plt.cm.gray, interpolation='nearest') ax1.set_title("DAB") ax2.imshow(GBIred_segmentation, cmap=plt.cm.gray) ax2.set_title("GBI red") ax3.imshow(Hema_segmentation, cmap=plt.cm.gray) ax3.set_title("Hematoxylin") for ax in axes.ravel(): ax.axis('off') fig.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=None) output_filename = 'output' + time.strftime("%Y-%m-%d %H:%M:%S") plt.savefig(output_folder + output_filename) #do a save csv here, maybe delete return statement after this comment return output_filename #, DAB_coverage_percent, Hema_coverage_percent, total_cell_percent, percent_pos_cells, Red_coverage_percent, adjusted_red_coverage_percent
#plt.imshow(stain_array) gray_array = rgb2grey(stain_array) #plt.imshow(gray_array) return gray_array def normalize_mapping(source_array, source_mean, target_mean): for x in source_array: x[...] = x/source_mean x[...] = x * target_mean return source_array #Import and decovolute target target_ihc_rgb = imread(target_file_path) target_ihc_hrd = separate_stains(target_ihc_rgb, hrd_from_rgb) target_Hema_Gray_Array = stainspace_to_2d_array(target_ihc_hrd, 0) target_red_Gray_Array = stainspace_to_2d_array(target_ihc_hrd, 1) target_DAB_Gray_Array = stainspace_to_2d_array(target_ihc_hrd, 2) for image_path in full_file_paths: if image_path.endswith(".jpg"): try: pic_file_name = os.path.basename(image_path) file_path = image_path #Import picture source_ihc_rgb = imread(file_path)
def process_one_patch(case_id, user, i, j, patch_polygon_area, image_width, image_height, patch_polygon_original, patchHumanMarkupRelation, tumorFlag, patch_humanmarkup_intersect_polygon, nuclues_polygon_list): patch_min_x_pixel = int(patch_polygon_original[0][0] * image_width) patch_min_y_pixel = int(patch_polygon_original[0][1] * image_height) x10 = patch_polygon_original[0][0] y10 = patch_polygon_original[0][1] x20 = patch_polygon_original[2][0] y20 = patch_polygon_original[2][1] patch_width_unit = float(patch_size) / float(image_width) patch_height_unit = float(patch_size) / float(image_height) try: patch_img = img.read_region((patch_min_x_pixel, patch_min_y_pixel), 0, (patch_size, patch_size)) except openslide.OpenSlideError as detail: print 'Handling run-time error:', detail exit() except Exception as e: print(e) exit() tmp_poly = [tuple(i1) for i1 in patch_polygon_original] tmp_polygon = Polygon(tmp_poly) patch_polygon = tmp_polygon.buffer(0) #patch_polygon_bound= patch_polygon.bounds; grayscale_img = patch_img.convert('L') rgb_img = patch_img.convert('RGB') grayscale_img_matrix = np.array(grayscale_img) rgb_img_matrix = np.array(rgb_img) grayscale_patch_mean = np.mean(grayscale_img_matrix) grayscale_patch_std = np.std(grayscale_img_matrix) grayscale_patch_10th_percentile = np.percentile( grayscale_img_matrix, 10) grayscale_patch_25th_percentile = np.percentile( grayscale_img_matrix, 25) grayscale_patch_50th_percentile = np.percentile( grayscale_img_matrix, 50) grayscale_patch_75th_percentile = np.percentile( grayscale_img_matrix, 75) grayscale_patch_90th_percentile = np.percentile( grayscale_img_matrix, 90) hed_title_img = separate_stains(rgb_img_matrix, hed_from_rgb) Hematoxylin_img_matrix = [[0 for x in range(patch_size)] for y in range(patch_size)] for index1, row in enumerate(hed_title_img): for index2, pixel in enumerate(row): Hematoxylin_img_matrix[index1][index2] = pixel[0] Hematoxylin_patch_mean = np.mean(Hematoxylin_img_matrix) Hematoxylin_patch_std = np.std(Hematoxylin_img_matrix) Hematoxylin_patch_10th_percentile = np.percentile( Hematoxylin_img_matrix, 10) Hematoxylin_patch_25th_percentile = np.percentile( Hematoxylin_img_matrix, 25) Hematoxylin_patch_50th_percentile = np.percentile( Hematoxylin_img_matrix, 50) Hematoxylin_patch_75th_percentile = np.percentile( Hematoxylin_img_matrix, 75) Hematoxylin_patch_90th_percentile = np.percentile( Hematoxylin_img_matrix, 90) nucleus_area = 0.0 segment_img = [] segment_img_hematoxylin = [] initial_grid = np.full((patch_size * patch_size), False) findPixelWithinPolygon = False record_count = len(nuclues_polygon_list) if (record_count > 0): for nuclues_polygon in nuclues_polygon_list: polygon = nuclues_polygon["geometry"]["coordinates"][0] tmp_poly2 = [tuple(i2) for i2 in polygon] computer_polygon2 = Polygon(tmp_poly2) computer_polygon = computer_polygon2.buffer(0) #computer_polygon_bound= computer_polygon.bounds; polygon_area = computer_polygon.area special_case2 = "" #only calculate features within tumor or non tumor region if (patchHumanMarkupRelation == "within"): special_case2 = "within" elif (patchHumanMarkupRelation == "intersect"): if (computer_polygon.within( patch_humanmarkup_intersect_polygon)): special_case2 = "within" elif (computer_polygon.intersects( patch_humanmarkup_intersect_polygon)): special_case2 = "intersects" else: special_case2 = "disjoin" if (special_case2 == "disjoin"): continue #skip this one and move to another computer polygon if (special_case2 == "within" and computer_polygon.within(patch_polygon) ): #within/within nucleus_area = nucleus_area + polygon_area has_value, one_polygon_mask = getMatrixValue( polygon, patch_min_x_pixel, patch_min_y_pixel) if (has_value): initial_grid = initial_grid | one_polygon_mask findPixelWithinPolygon = True elif (special_case2 == "within" and computer_polygon.intersects(patch_polygon) ): #within/intersects polygon_intersect = computer_polygon.intersection( patch_polygon) if polygon_intersect.is_empty: continue tmp_area = polygon_intersect.area nucleus_area = nucleus_area + tmp_area if polygon_intersect.geom_type == 'MultiPolygon': for p in polygon_intersect: polygon_intersect_points = list( zip(*p.exterior.coords.xy)) has_value, one_polygon_mask = getMatrixValue( polygon_intersect_points, patch_min_x_pixel, patch_min_y_pixel) if (has_value): initial_grid = initial_grid | one_polygon_mask findPixelWithinPolygon = True elif polygon_intersect.geom_type == 'Polygon': polygon_intersect_points = list( zip(*polygon_intersect.exterior.coords.xy)) has_value, one_polygon_mask = getMatrixValue( polygon_intersect_points, patch_min_x_pixel, patch_min_y_pixel) if (has_value): initial_grid = initial_grid | one_polygon_mask findPixelWithinPolygon = True else: print "patch indexes %d , %d Shape is not a polygon!!!" % ( i, j) print polygon_intersect elif (special_case2 == "intersects" and computer_polygon.within(patch_polygon) ): #intersects/within starttime = time.time() polygon_intersect = computer_polygon.intersection( patch_humanmarkup_intersect_polygon) if polygon_intersect.is_empty: continue tmp_area = polygon_intersect.area nucleus_area = nucleus_area + tmp_area if polygon_intersect.geom_type == 'MultiPolygon': for p in polygon_intersect: polygon_intersect_points = list( zip(*p.exterior.coords.xy)) has_value, one_polygon_mask = getMatrixValue( polygon_intersect_points, patch_min_x_pixel, patch_min_y_pixel) if (has_value): initial_grid = initial_grid | one_polygon_mask findPixelWithinPolygon = True elif polygon_intersect.geom_type == 'Polygon': polygon_intersect_points = list( zip(*polygon_intersect.exterior.coords.xy)) has_value, one_polygon_mask = getMatrixValue( polygon_intersect_points, patch_min_x_pixel, patch_min_y_pixel) if (has_value): initial_grid = initial_grid | one_polygon_mask findPixelWithinPolygon = True else: print "patch indexes %d , %d Shape is not a polygon!!!" % ( i, j) print polygon_intersect elif (special_case2 == "intersects" and computer_polygon.intersects(patch_polygon) ): #intersects/intersects starttime = time.time() polygon_intersect = computer_polygon.intersection( patch_polygon) if polygon_intersect.is_empty: continue polygon_intersect = polygon_intersect.intersection( patch_humanmarkup_intersect_polygon) if polygon_intersect.is_empty: continue tmp_area = polygon_intersect.area nucleus_area = nucleus_area + tmp_area if polygon_intersect.geom_type == 'MultiPolygon': for p in polygon_intersect: polygon_intersect_points = list( zip(*p.exterior.coords.xy)) has_value, one_polygon_mask = getMatrixValue( polygon_intersect_points, patch_min_x_pixel, patch_min_y_pixel) if (has_value): initial_grid = initial_grid | one_polygon_mask findPixelWithinPolygon = True elif polygon_intersect.geom_type == 'Polygon': polygon_intersect_points = list( zip(*polygon_intersect.exterior.coords.xy)) has_value, one_polygon_mask = getMatrixValue( polygon_intersect_points, patch_min_x_pixel, patch_min_y_pixel) if (has_value): initial_grid = initial_grid | one_polygon_mask findPixelWithinPolygon = True else: print "patch indexes %d , %d Shape is not a polygon!!!" % ( i, j) print polygon_intersect if (findPixelWithinPolygon): mask = initial_grid.reshape(patch_size, patch_size) for index1, row in enumerate(mask): for index2, pixel in enumerate(row): if (pixel ): #this pixel is inside of segmented unclei polygon segment_img.append( grayscale_img_matrix[index1][index2]) segment_img_hematoxylin.append( Hematoxylin_img_matrix[index1][index2]) percent_nuclear_material = float( (nucleus_area / patch_polygon_area) * 100) if (len(segment_img) > 0): segment_mean_grayscale_intensity = np.mean(segment_img) segment_std_grayscale_intensity = np.std(segment_img) segment_10th_percentile_grayscale_intensity = np.percentile( segment_img, 10) segment_25th_percentile_grayscale_intensity = np.percentile( segment_img, 25) segment_50th_percentile_grayscale_intensity = np.percentile( segment_img, 50) segment_75th_percentile_grayscale_intensity = np.percentile( segment_img, 75) segment_90th_percentile_grayscale_intensity = np.percentile( segment_img, 90) segment_mean_hematoxylin_intensity = np.mean( segment_img_hematoxylin) segment_std_hematoxylin_intensity = np.std(segment_img_hematoxylin) segment_10th_percentile_hematoxylin_intensity = np.percentile( segment_img_hematoxylin, 10) segment_25th_percentile_hematoxylin_intensity = np.percentile( segment_img_hematoxylin, 25) segment_50th_percentile_hematoxylin_intensity = np.percentile( segment_img_hematoxylin, 50) segment_75th_percentile_hematoxylin_intensity = np.percentile( segment_img_hematoxylin, 75) segment_90th_percentile_hematoxylin_intensity = np.percentile( segment_img_hematoxylin, 90) else: segment_mean_grayscale_intensity = "n/a" segment_std_grayscale_intensity = "n/a" segment_mean_hematoxylin_intensity = "n/a" segment_std_hematoxylin_intensity = "n/a" segment_10th_percentile_grayscale_intensity = "n/a" segment_25th_percentile_grayscale_intensity = "n/a" segment_50th_percentile_grayscale_intensity = "n/a" segment_75th_percentile_grayscale_intensity = "n/a" segment_90th_percentile_grayscale_intensity = "n/a" segment_10th_percentile_hematoxylin_intensity = "n/a" segment_25th_percentile_hematoxylin_intensity = "n/a" segment_50th_percentile_hematoxylin_intensity = "n/a" segment_75th_percentile_hematoxylin_intensity = "n/a" segment_90th_percentile_hematoxylin_intensity = "n/a" print case_id, image_width, image_height, user, i, j, patch_min_x_pixel, patch_min_y_pixel, patch_size, patch_polygon_area, tumorFlag, nucleus_area, percent_nuclear_material, grayscale_patch_mean, grayscale_patch_std, Hematoxylin_patch_mean, Hematoxylin_patch_std, segment_mean_grayscale_intensity, segment_std_grayscale_intensity, segment_mean_hematoxylin_intensity, segment_std_hematoxylin_intensity
def seperateStains(s, params): logging.info(f"{s['filename']} - \tseperateStains") stain = params.get("stain", "") use_mask = strtobool(params.get("use_mask", "True")) if stain == "": logging.error( f"{s['filename']} - stain not set in DeconvolutionModule.seperateStains" ) sys.exit(1) return stain_matrix = getattr(sys.modules[__name__], stain, "") if stain_matrix == "": logging.error( f"{s['filename']} - Unknown stain matrix specified in DeconolutionModule.seperateStains" ) sys.exit(1) return mask = s["img_mask_use"] if use_mask and len( mask.nonzero()[0] ) == 0: #-- lets just error check at the top if mask is empty and abort early for c in range(3): s.addToPrintList(f"deconv_c{c}_std", str(-100)) s.addToPrintList(f"deconv_c{c}_mean", str(-100)) io.imsave( s["outdir"] + os.sep + s["filename"] + f"_deconv_c{c}.png", img_as_ubyte(np.zeros(mask.shape))) logging.warning( f"{s['filename']} - DeconvolutionModule.seperateStains: NO tissue " f"remains detectable! Saving Black images") s["warnings"].append(f"DeconvolutionModule.seperateStains: NO tissue " f"remains detectable! Saving Black images") return img = s.getImgThumb(s["image_work_size"]) dimg = separate_stains(img, stain_matrix) for c in range(0, 3): dc = dimg[:, :, c] if use_mask: dc_sub = dc[mask] dc_min = dc_sub.min() dc_max = dc_sub.max() s.addToPrintList(f"deconv_c{c}_mean", str(dc_sub.mean())) s.addToPrintList(f"deconv_c{c}_std", str(dc_sub.std())) else: mask = 1.0 dc_min = dc.min() dc_max = dc.max() s.addToPrintList(f"deconv_c{c}_mean", str(dc.mean())) s.addToPrintList(f"deconv_c{c}_std", str(dc.std())) dc = (dc - dc_min) / float(dc_max - dc_min) * mask io.imsave(s["outdir"] + os.sep + s["filename"] + f"_deconv_c{c}.png", img_as_ubyte(dc)) return
def test_bro_rgb_roundtrip_float(self): from skimage.color.colorconv import bro_from_rgb, rgb_from_bro img_in = self.img_stains img_out = combine_stains(img_in, rgb_from_bro) img_out = separate_stains(img_out, bro_from_rgb) assert_array_almost_equal(img_out, img_in)
# Import picture ihc_rgb = data.imread(file_path) # Normalized optical density matrix # Hematoxylin(0), Red(1), DAB(2) rgb_from_hrd = np.array([[0.644, 0.710, 0.285], [0.0326, 0.873, 0.487], [0.270, 0.562, 0.781]]) # conv_matrix hrd_from_rgb = linalg.inv(rgb_from_hrd) print(hrd_from_rgb) hrd_from_rgb = linalg.inv(rgb_from_hrd) # Stain space conversion ihc_hrd = separate_stains(ihc_rgb, hrd_from_rgb) '''DAB''' # Rescale signals # [:, :, 012 color] dab_rescale = rescale_intensity(ihc_hrd[:, :, 2], out_range=(0, 1)) dab_array = np.dstack( (np.zeros_like(dab_rescale), dab_rescale, dab_rescale)) # Blob detection image2d = rgb2grey(dab_array) blobs_DoG_DAB = blob_dog(image2d, min_sigma=1, max_sigma=25, threshold=.3, overlap=0.9)
def test_hdx_rgb_roundtrip(self): from skimage.color.colorconv import hdx_from_rgb, rgb_from_hdx img_rgb = self.img_rgb conv = combine_stains(separate_stains(img_rgb, hdx_from_rgb), rgb_from_hdx) assert_equal(img_as_ubyte(conv), img_rgb)
def deconv_ihc(image): ihc_hdx = separate_stains(image, hdx_from_rgb) return ihc_hdx[:, :, 0], ihc_hdx[:, :, 1], ihc_hdx[:, :, 2]
def test_bro_rgb_roundtrip(self): from skimage.color.colorconv import bro_from_rgb, rgb_from_bro img_in = img_as_ubyte(self.img_stains) img_out = combine_stains(img_in, rgb_from_bro) img_out = separate_stains(img_out, bro_from_rgb) assert_equal(img_as_ubyte(img_out), img_in)
def RunScript(): # Color deconvolution # Normalized optical density matrix # see Ruifrok AC, Johnston DA. Quantification of histological staining by color deconvolution. # R G B # X X X Hematoxylin(0) # X X X Red(1) # X X X DAB(2) # Hematoxylin(0), Red(1), DAB(2) rgb_from_hrd = np.array([[0.644, 0.710, 0.285], [0.0326, 0.873, 0.487], [0.270, 0.562, 0.781]]) # conv_matrix hrd_from_rgb = linalg.inv(rgb_from_hrd) # Import picture #ihc_rgb = imread(r'TestImage.jpg') ihc_rgb = imread(r'TimedRunImage.jpg') # Rescale signals so that intensity ranges from 0 to 1 # ihc_hrd[:, :, (0,1, or 2 -- is the color channel)] def stainspace_to_2d_array(ihc_xyz, channel): rescale = rescale_intensity(ihc_xyz[:, :, channel], out_range=(0, 1)) stain_array = np.dstack((np.zeros_like(rescale), rescale, rescale)) grey_array = rgb2grey(stain_array) return grey_array # Stain space conversion ihc_hrd = separate_stains(ihc_rgb, hrd_from_rgb) DAB_Grey_Array = stainspace_to_2d_array(ihc_hrd, 2) Hema_Gray_Array = stainspace_to_2d_array(ihc_hrd, 0) permRed_Gray_Array = stainspace_to_2d_array(ihc_hrd, 1) # Get markers for random walk def get_markers(grey_array, bottom_thresh, top_thresh): markers = np.zeros_like(grey_array) markers[grey_array < bottom_thresh] = 1 markers[grey_array > top_thresh] = 2 return markers # perform Random Walker, fills in positive regions DAB_segmentation = random_walker(DAB_Grey_Array, get_markers(DAB_Grey_Array, .3, .5), beta=130, mode='cg') Hema_segmentation = random_walker(Hema_Gray_Array, get_markers(Hema_Gray_Array, .2, .4), beta=130, mode='cg') permRed_segmentation = random_walker(permRed_Gray_Array, get_markers(permRed_Gray_Array, .4, .5), beta=130, mode='cg') """PRINTING OUTPUT""" print(20 *'-') print(' ') '''Compute and Output''' # Compute and output percentages of pixels stained by each chromagen pic_dimensions = np.shape(DAB_segmentation) # both arrays same shape total_pixels = pic_dimensions[0] * pic_dimensions[1] # change negative pixel values from 1 -> 0, positives 2 -> 1 subtrahend_array = np.ones_like(DAB_segmentation) DAB_segmentation = np.subtract(DAB_segmentation, subtrahend_array) Hema_segmentation = np.subtract(Hema_segmentation, subtrahend_array) permRed_segmentation = np.subtract(permRed_segmentation, subtrahend_array) # count positive pixels DAB_pixels = np.count_nonzero(DAB_segmentation) Hema_pixels = np.count_nonzero(Hema_segmentation) red_pixels = np.count_nonzero(permRed_segmentation) DAB_coverage_percent = (round((DAB_pixels / total_pixels * 100), 1)) print("The percentage of the image covered by DAB is: " + str(DAB_coverage_percent) + "%") Hema_coverage_percent = (round((Hema_pixels / total_pixels * 100), 1)) print("The percentage of the image covered by Hematoxylin is: " + str(Hema_coverage_percent) + "%") total_cell_array = np.add(DAB_segmentation, Hema_segmentation) total_cell_pixels = np.count_nonzero(total_cell_array) total_cell_percent = (round((total_cell_pixels / total_pixels * 100), 1)) print("The percentage of the image covered by DAB & Hematoxylin is: " + str(total_cell_percent) + "%") percent_pos_cells = (round((DAB_pixels / total_cell_pixels * 100), 1)) print("The percentage of CD3+ cells out of the total number of cells is: " + str(percent_pos_cells) + "%") PercentPos = percent_pos_cells """ if PercentPos >= 81: print('Proportion Score: 5') proportion_score = 5 elif PercentPos >= 61: print('Proportion Score: 4') proportion_score = 4 elif PercentPos >= 41: print('Proportion Score: 3') proportion_score = 3 elif PercentPos >= 21: print('Proportion Score: 2') proportion_score = 2 elif PercentPos >= 5: print('Proportion Score: 1') proportion_score = 1 elif PercentPos >= 0: print('Proportion Score: 0') proportion_score = 0 else: print('error, proportion score below zero?') proportion_score = -1 """ # Cytokines print(" ") Red_coverage_percent = (round((red_pixels / total_pixels * 100), 1)) print("The percentage of the image covered by cytokines is: " + str(Red_coverage_percent) + "%") red_plus_total_array = np.add(total_cell_array, permRed_segmentation) red_plus_total_pixels = np.count_nonzero(red_plus_total_array) adjusted_red_coverage_percent = (round((red_pixels / red_plus_total_pixels * 100), 1)) print("The percentage of the area covered by cytokines, with non-cellular regions subtracted is: " + str( adjusted_red_coverage_percent) + "%") """PLOTTING IMAGES""" # Plot images fig, axes = plt.subplots(2, 2, figsize=(12, 11)) # ax0 = axes.ravel() ax0, ax1, ax2, ax3 = axes.ravel() ax0.imshow(ihc_rgb, cmap=plt.cm.gray, interpolation='nearest') ax0.set_title("Original") ax1.imshow(DAB_segmentation, cmap=plt.cm.gray, interpolation='nearest') ax1.set_title("DAB") ax2.imshow(permRed_segmentation, cmap=plt.cm.gray) ax2.set_title("Permanent Red") ax3.imshow(Hema_segmentation, cmap=plt.cm.gray) ax3.set_title("Hematoxylin") for ax in axes.ravel(): ax.axis('on') fig.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=None)
def process_4x(image_filename): """ Process widefield images, returning a coloured image containing segmentations of inflammatory areas and veins. """ # Read in the image image = transform.rescale(io.imread(image_filename), 0.25) # Deconvolve the image heu = color.separate_stains( image, np.linalg.inv(colour_deconv_matrix)).astype(float) # INFLAMMATION # Apply CLAHE equalised_hist = exposure.equalize_adapthist(exposure.rescale_intensity( heu[:, :, 1], out_range=(0, 1)), ntiles_y=1) # Blur blurred = filters.gaussian(equalised_hist, 5) # Sigmoid transform for contrast contrast = exposure.adjust_sigmoid(blurred, cutoff=0.6) # Take an adaptive threshold thresholded = filters.threshold_adaptive(contrast, 75, offset=-0.12) # Remove small connected components cleaned = morphology.remove_small_objects(thresholded, 250) # Enlarge areas enlarged = maximum_filter(cleaned, 11) # Binary closing inflammation = morphology.closing(enlarged, morphology.disk(15)) # VEINS # How stained by eosin is each individual pixel ? unstained = heu[:, :, 2] / heu[:, :, 0] # Blur blurred = filters.gaussian(unstained, 11) # Thresholded thresholded = filters.threshold_adaptive(blurred, 251, offset=-0.13) # Morphlogical closing closed = morphology.binary_closing(thresholded, morphology.disk(25)) # Remove small connected components veins = morphology.remove_small_objects(closed, 200) # Inflammation in blue, veins in green coloured = np.zeros_like(heu) coloured[:, :, 1] = veins coloured[:, :, 2] = inflammation return coloured
# Rescale signals so that intensity ranges from 0 to 1 # ihc_hrd[:, :, (0,1, or 2 -- is the color channel)] def stainspace_to_2d_array(ihc_xyz, channel): #rescale = rescale_intensity(ihc_xyz[:, :, channel], out_range=(0,1)) #stain_array = np.dstack((np.zeros_like(rescale), rescale, rescale)) #try to not reverse engineer rescale right now stain_array = ihc_xyz[:, :, channel] #plt.imshow(stain_array) gray_array = rgb2grey(stain_array) #plt.imshow(gray_array) return gray_array #Stain space conversion source_ihc_hrd = separate_stains(source_ihc_rgb, hrd_from_rgb) target_ihc_hrd = separate_stains(target_ihc_rgb, hrd_from_rgb) source_Hema_Gray_Array = stainspace_to_2d_array(source_ihc_hrd, 0) source_red_Gray_Array = stainspace_to_2d_array(source_ihc_hrd, 1) source_DAB_Gray_Array = stainspace_to_2d_array(source_ihc_hrd, 2) target_Hema_Gray_Array = stainspace_to_2d_array(target_ihc_hrd, 0) target_red_Gray_Array = stainspace_to_2d_array(target_ihc_hrd, 1) target_DAB_Gray_Array = stainspace_to_2d_array(target_ihc_hrd, 2) ''' def get_stats(input_1D_array): mean = np.mean(input_1D_array)
#print grayscale_img_matrix,grayscale_img_matrix.shape; #print rgb_img_matrix,rgb_img_matrix.shape; #exit(); grayscale_patch_mean = np.mean(grayscale_img_matrix) grayscale_patch_std = np.std(grayscale_img_matrix) grayscale_patch_10th_percentile = np.percentile( grayscale_img_matrix, 10) grayscale_patch_25th_percentile = np.percentile( grayscale_img_matrix, 25) grayscale_patch_50th_percentile = np.percentile( grayscale_img_matrix, 50) grayscale_patch_75th_percentile = np.percentile( grayscale_img_matrix, 75) grayscale_patch_90th_percentile = np.percentile( grayscale_img_matrix, 90) hed_title_img = separate_stains(rgb_img_matrix, hed_from_rgb) Hematoxylin_img_matrix = [[0 for x in range(patch_size)] for y in range(patch_size)] for index1, row in enumerate(hed_title_img): for index2, pixel in enumerate(row): Hematoxylin_img_matrix[index1][index2] = pixel[0] Hematoxylin_patch_mean = np.mean(Hematoxylin_img_matrix) Hematoxylin_patch_std = np.std(Hematoxylin_img_matrix) Hematoxylin_patch_10th_percentile = np.percentile( Hematoxylin_img_matrix, 10) Hematoxylin_patch_25th_percentile = np.percentile( Hematoxylin_img_matrix, 25) Hematoxylin_patch_50th_percentile = np.percentile( Hematoxylin_img_matrix, 50) Hematoxylin_patch_75th_percentile = np.percentile( Hematoxylin_img_matrix, 75)
def test_hdx_rgb_roundtrip(self): from skimage.color.colorconv import hdx_from_rgb, rgb_from_hdx img_rgb = img_as_float(self.img_rgb) conv = combine_stains(separate_stains(img_rgb, hdx_from_rgb), rgb_from_hdx) assert_array_almost_equal(conv, img_rgb)
#Color deconvolution #DAB and perm red(1) rgb_from_drx = np.array([[0.270, 0.562, 0.781], [0.0326, 0.873, 0.487], [0.0, 0.0, 0.0]]) rgb_from_drx[2, :] = np.cross(rgb_from_drx[0, :], rgb_from_drx[1, :]) drx_from_rgb = linalg.inv(rgb_from_drx) #Import picture ihc_rgb = data.imread(r'TestImage.jpg') #Stain space conversion #ihc_hax = separate_stains(ihc_rgb, hax_from_rgb) ihc_drx = separate_stains(ihc_rgb, drx_from_rgb) #Rescale signals? - might help, might not #[:, :, 012 color] permred_rescale = rescale_intensity(ihc_drx[:, :, 1], out_range=(0, 1)) permred_array = np.dstack((np.zeros_like(permred_rescale), permred_rescale, permred_rescale)) #Blob detection image2d = rgb2grey(permred_array) blobs_dog = blob_dog(image2d, min_sigma=1, max_sigma=40, threshold=.5, overlap=0.1) blobs_dog[:, 2] = blobs_dog[:, 2] * sqrt(2)
def random_walk_segmentation(input_image, output_folder): input_image = imread(input_image) ihc_hrd = separate_stains(input_image, hrd_from_rgb) DAB_Grey_Array = stainspace_to_2d_array(ihc_hrd, 2) Hema_Gray_Array = stainspace_to_2d_array(ihc_hrd, 0) GBIred_Gray_Array = stainspace_to_2d_array(ihc_hrd, 1) #Perform Random Walker, fills in positive regions DAB_segmentation = random_walker(DAB_Grey_Array, get_markers(DAB_Grey_Array, .3, .5), beta=130, mode='cg_mg') Hema_segmentation = random_walker(Hema_Gray_Array, get_markers(Hema_Gray_Array, .2, .4), beta=130, mode='cg_mg') GBIred_segmentation = random_walker(GBIred_Gray_Array, get_markers(GBIred_Gray_Array, .4, .5), beta=130, mode='cg_mg') '''Compute and Output''' #Compute and output percentages of pixels stained by each chromagen pic_dimensions = np.shape(DAB_segmentation) # both arrays same shape total_pixels = pic_dimensions[0] * pic_dimensions[1] #Change negative pixel values from 1 -> 0, positives 2 -> 1 subtrahend_array = np.ones_like(DAB_segmentation) DAB_segmentation = np.subtract(DAB_segmentation, subtrahend_array) Hema_segmentation = np.subtract(Hema_segmentation, subtrahend_array) GBIred_segmentation = np.subtract(GBIred_segmentation, subtrahend_array) #Count positive pixels DAB_pixels = np.count_nonzero(DAB_segmentation) Hema_pixels = np.count_nonzero(Hema_segmentation) red_pixels = np.count_nonzero(GBIred_segmentation) #Percent of image covered by positive staining DAB_coverage_percent = (round((DAB_pixels / total_pixels * 100), 1)) Hema_coverage_percent = (round((Hema_pixels / total_pixels * 100), 1)) #An overlay of the DAB and Hematoxylin segmented images, for total cellular area total_cell_array = np.add(DAB_segmentation, Hema_segmentation) #Number of pixels covered by cellular area total_cell_pixels = np.count_nonzero(total_cell_array) #Percent of image covered by cellular area (DAB OR Hematoxylin) total_cell_percent = (round((total_cell_pixels / total_pixels * 100), 1)) #The percentage of DAB/CD3+ cells out of the total number of cells percent_pos_cells = (round((DAB_pixels / total_cell_pixels * 100), 1)) #The percentage of the image covered by cytokines Red_coverage_percent = (round((red_pixels / total_pixels * 100), 1)) red_plus_total_array = np.add(total_cell_array, GBIred_segmentation) red_plus_total_pixels = np.count_nonzero(red_plus_total_array) #The percentage of the area covered by cytokines, with non-cellular regions subtracted adjusted_red_coverage_percent = (round((red_pixels / red_plus_total_pixels * 100), 1)) # Plot images fig, axes = plt.subplots(2, 2, figsize=(12, 11)) ax0, ax1, ax2, ax3 = axes.ravel() ax0.imshow(input_image, cmap=plt.cm.gray, interpolation='nearest') ax0.set_title("Original") ax1.imshow(DAB_segmentation, cmap=plt.cm.gray, interpolation='nearest') ax1.set_title("DAB") ax2.imshow(GBIred_segmentation, cmap=plt.cm.gray) ax2.set_title("GBI red") ax3.imshow(Hema_segmentation, cmap=plt.cm.gray) ax3.set_title("Hematoxylin") for ax in axes.ravel(): ax.axis('off') fig.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=None) output_filename = 'output' + time.strftime("%Y-%m-%d %H:%M:%S") plt.savefig(output_folder + output_filename) #do a save csv here, maybe delete return statement after this comment return output_filename#, DAB_coverage_percent, Hema_coverage_percent, total_cell_percent, percent_pos_cells, Red_coverage_percent, adjusted_red_coverage_percent
def RunScript(): # Color deconvolution # Normalized optical density matrix # see Ruifrok AC, Johnston DA. Quantification of histological staining by color deconvolution. # R G B # X X X Hematoxylin(0) # X X X Red(1) # X X X DAB(2) # Hematoxylin(0), Red(1), DAB(2) rgb_from_hrd = np.array([[0.644, 0.710, 0.285], [0.0326, 0.873, 0.487], [0.270, 0.562, 0.781]]) # conv_matrix hrd_from_rgb = linalg.inv(rgb_from_hrd) # Import picture #ihc_rgb = imread(r'TestImage.jpg') ihc_rgb = imread(r'TimedRunImage.jpg') # Rescale signals so that intensity ranges from 0 to 1 # ihc_hrd[:, :, (0,1, or 2 -- is the color channel)] def stainspace_to_2d_array(ihc_xyz, channel): rescale = rescale_intensity(ihc_xyz[:, :, channel], out_range=(0, 1)) stain_array = np.dstack((np.zeros_like(rescale), rescale, rescale)) grey_array = rgb2grey(stain_array) return grey_array # Stain space conversion ihc_hrd = separate_stains(ihc_rgb, hrd_from_rgb) DAB_Grey_Array = stainspace_to_2d_array(ihc_hrd, 2) Hema_Gray_Array = stainspace_to_2d_array(ihc_hrd, 0) permRed_Gray_Array = stainspace_to_2d_array(ihc_hrd, 1) # Get markers for random walk def get_markers(grey_array, bottom_thresh, top_thresh): markers = np.zeros_like(grey_array) markers[grey_array < bottom_thresh] = 1 markers[grey_array > top_thresh] = 2 return markers # perform Random Walker, fills in positive regions DAB_segmentation = random_walker(DAB_Grey_Array, get_markers(DAB_Grey_Array, .3, .5), beta=130, mode='cg') Hema_segmentation = random_walker(Hema_Gray_Array, get_markers(Hema_Gray_Array, .2, .4), beta=130, mode='cg') permRed_segmentation = random_walker(permRed_Gray_Array, get_markers(permRed_Gray_Array, .4, .5), beta=130, mode='cg') """PRINTING OUTPUT""" print(20 * '-') print(' ') '''Compute and Output''' # Compute and output percentages of pixels stained by each chromagen pic_dimensions = np.shape(DAB_segmentation) # both arrays same shape total_pixels = pic_dimensions[0] * pic_dimensions[1] # change negative pixel values from 1 -> 0, positives 2 -> 1 subtrahend_array = np.ones_like(DAB_segmentation) DAB_segmentation = np.subtract(DAB_segmentation, subtrahend_array) Hema_segmentation = np.subtract(Hema_segmentation, subtrahend_array) permRed_segmentation = np.subtract(permRed_segmentation, subtrahend_array) # count positive pixels DAB_pixels = np.count_nonzero(DAB_segmentation) Hema_pixels = np.count_nonzero(Hema_segmentation) red_pixels = np.count_nonzero(permRed_segmentation) DAB_coverage_percent = (round((DAB_pixels / total_pixels * 100), 1)) print("The percentage of the image covered by DAB is: " + str(DAB_coverage_percent) + "%") Hema_coverage_percent = (round((Hema_pixels / total_pixels * 100), 1)) print("The percentage of the image covered by Hematoxylin is: " + str(Hema_coverage_percent) + "%") total_cell_array = np.add(DAB_segmentation, Hema_segmentation) total_cell_pixels = np.count_nonzero(total_cell_array) total_cell_percent = (round((total_cell_pixels / total_pixels * 100), 1)) print("The percentage of the image covered by DAB & Hematoxylin is: " + str(total_cell_percent) + "%") percent_pos_cells = (round((DAB_pixels / total_cell_pixels * 100), 1)) print( "The percentage of CD3+ cells out of the total number of cells is: " + str(percent_pos_cells) + "%") PercentPos = percent_pos_cells """ if PercentPos >= 81: print('Proportion Score: 5') proportion_score = 5 elif PercentPos >= 61: print('Proportion Score: 4') proportion_score = 4 elif PercentPos >= 41: print('Proportion Score: 3') proportion_score = 3 elif PercentPos >= 21: print('Proportion Score: 2') proportion_score = 2 elif PercentPos >= 5: print('Proportion Score: 1') proportion_score = 1 elif PercentPos >= 0: print('Proportion Score: 0') proportion_score = 0 else: print('error, proportion score below zero?') proportion_score = -1 """ # Cytokines print(" ") Red_coverage_percent = (round((red_pixels / total_pixels * 100), 1)) print("The percentage of the image covered by cytokines is: " + str(Red_coverage_percent) + "%") red_plus_total_array = np.add(total_cell_array, permRed_segmentation) red_plus_total_pixels = np.count_nonzero(red_plus_total_array) adjusted_red_coverage_percent = (round( (red_pixels / red_plus_total_pixels * 100), 1)) print( "The percentage of the area covered by cytokines, with non-cellular regions subtracted is: " + str(adjusted_red_coverage_percent) + "%") """PLOTTING IMAGES""" # Plot images fig, axes = plt.subplots(2, 2, figsize=(12, 11)) # ax0 = axes.ravel() ax0, ax1, ax2, ax3 = axes.ravel() ax0.imshow(ihc_rgb, cmap=plt.cm.gray, interpolation='nearest') ax0.set_title("Original") ax1.imshow(DAB_segmentation, cmap=plt.cm.gray, interpolation='nearest') ax1.set_title("DAB") ax2.imshow(permRed_segmentation, cmap=plt.cm.gray) ax2.set_title("Permanent Red") ax3.imshow(Hema_segmentation, cmap=plt.cm.gray) ax3.set_title("Hematoxylin") for ax in axes.ravel(): ax.axis('on') fig.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=None)
def test_hdx_rgb_roundtrip_float(self): from skimage.color.colorconv import hdx_from_rgb, rgb_from_hdx img_rgb = img_as_float(self.img_rgb) conv = combine_stains(separate_stains(img_rgb, hdx_from_rgb), rgb_from_hdx) assert_array_almost_equal(conv, img_rgb)
# <codecell> A = io.imread("../data/" + l[5]) io.imshow(A) # <codecell> #B = exposure.adjust_sigmoid(filter.gaussian_filter(A[:, :, 0], 19), cutoff=.45, gain=15) B = exposure.adjust_sigmoid( filter.gaussian_filter( exposure.rescale_intensity( color.separate_stains( A, np.linalg.inv(qstain)), out_range=(0, 1))[:, :, 1], 29), cutoff=.35, gain=20) io.imshow(B) # <codecell> #b = morphology.remove_small_objects(filter.threshold_adaptive(filter.gaussian_filter(exposure.adjust_sigmoid(A[:,:,1]), 31), 501, offset=-0.05), 2000) C = morphology.remove_small_objects( filter.threshold_adaptive(B, 301, offset=-0.025), 4000) #io.imshow(morphology.binary_closing(np.logical_or(morphology.binary_dilation(C, morphology.disk(11)), b), morphology.disk(31))) io.imshow(C)
graies = [(rgb2gray(np.average(image[labels == i], axis=0)), i) for i in xrange(cluster_num)] graies.sort() nuclei__ = np.zeros((w, h)) nuclei__[labels == graies[0][1]] = 1 image___ = np.copy(image) image___[labels == graies[1][1]] = 255 image___[labels == graies[2][1]] = 255 hematoxylin_ = separate_stains(image_, conv_matrix)[:, :, 0] hematoxylin__ = separate_stains(image__, conv_matrix)[:, :, 0] hematoxylin___ = separate_stains(image___, conv_matrix)[:, :, 0] # opened_ = opening(hematoxylin_, disk(int(sys.argv[2]))) # # opened__ = opening(hematoxylin__, disk(int(sys.argv[2]))) cleared = clear_border(nuclei) cleared_ = clear_border(nuclei_) cleared__ = clear_border(nuclei__)
# Inflammatory focus count qstain = np.array([[.26451728, .5205347, .81183386], [.9199094, .29797825, .25489032], [.28947765, .80015373, .5253158]]) deconv = ski.img_as_float(color.separate_stains(transform.rescale(A, 0.25), np.linalg.inv(qstain))) subveins1 = \ morphology.remove_small_objects( filter.threshold_adaptive( filter.gaussian_filter( deconv[:, :, 2] / deconv[:, :, 0], 11), 250, offset = -0.13), 60) subveins2 = \ morphology.remove_small_objects( filter.threshold_adaptive(
from skimage.segmentation import random_walker from skimage import morphology from skimage.filters import sobel #ihc_rgb = imread(r'C:\Users\griffin\Desktop\MicroDeconvolution\TestingScripts\SamplePics\SK108 3554 28_1_CD3_IL10_Set 1_20X_Take 1.jpg') ihc_rgb = imread(r'TestImage.jpg') # Color deconvolution # Hematoxylin(0) & DAB(2) rgb_from_hrd = np.array([[0.65, 0.70, 0.29], [0.1, 0.95, 0.95], [0.27, 0.57, 0.78]]) hrd_from_rgb = linalg.inv(rgb_from_hrd) # Stain space conversion ihc_hrd = separate_stains(ihc_rgb, hrd_from_rgb) # Rescale signals so that intensity ranges from 0 to 1 # ihc_hrd[:, :, (0,1, or 2 -- is the color channel)] def stainspace2array(ihc_xyz, channel): rescale = rescale_intensity(ihc_xyz[:, :, channel], out_range=(0,1)) stain_array = np.dstack((np.zeros_like(rescale), rescale, rescale)) grey_array = rgb2grey(stain_array) return grey_array DAB_Grey_Array = stainspace2array(ihc_hrd, 2) Hema_Grey_Array = stainspace2array(ihc_hrd, 0) red_Grey_Array = stainspace2array(ihc_hrd, 1)
def setUp(self): self.rgb = misc.imread( os.path.join(curdir, "../immunopy/image/hdab256.tif")) self.hdx = color.separate_stains(self.rgb, color.hdx_from_rgb) self.hem = self.hdx[:,:,0] self.dab = self.hdx[:,:,1]