def exudates_get_features_3(folder, elements_folder, fundus_mask, num_imgs=10, stride_width=6): thr_high = 189.0 / 255.0 y = [] pxl_df = pd.DataFrame(columns=['hue', 'intensity', 'mean intensity', 'std intensity', 'dist to optic disk']) for img_fn in image_names_in_folder(folder)[:num_imgs]: print 'Image filename:', img_fn img = load_image(img_fn) short_fn = os.path.split(img_fn)[-1] hard_exud = load_image(os.path.join(elements_folder, short_fn)) hsi = rgb_to_hsi(img) intensity = hsi[:, :, 2].copy() #i_sp = add_salt_and_pepper(intensity, 0.005) i_med = mh.median_filter(intensity) # use Wiener filter instead? i_clahe = skimage.exposure.equalize_adapthist(i_med) optic_disk_map = optic_disk_detect_3(img) mask, optic_disk_center = optic_disk_mask(optic_disk_map, return_center=True) print 'Disk center: ', optic_disk_center fundus_wo_disk_mask = fundus_mask & (~mask) pxl_mask = np.zeros_like(i_clahe, dtype=np.bool) pxl_mask[::stride_width, ::stride_width] = True pxl_mask[~fundus_wo_disk_mask] = False bbox = bounding_box(hard_exud >= thr_high, bbox_radius_ratio=2) pxl_mask &= bbox cur_pxl_df = pd.DataFrame(columns=['hue', 'intensity', 'mean intensity', 'std intensity', 'dist to optic disk']) cur_pxl_df['hue'] = hsi[:, :, 0][pxl_mask].ravel() cur_pxl_df['intensity'] = i_clahe[pxl_mask].ravel() cur_pxl_df['mean intensity'] = pf.pxls_mean_intensity(i_clahe, stride_width, neighbd_rad=7, mask=pxl_mask).ravel() cur_pxl_df['std intensity'] = pf.pxls_std_intensity(i_clahe, stride_width, neighbd_rad=3, mask=pxl_mask).ravel() cur_pxl_df['dist to optic disk'] = pf.pxls_dist_to_pnt(i_clahe.shape, optic_disk_center, stride_width, mask=pxl_mask).ravel() print 'Accounted pixels: ', len(cur_pxl_df) y.append(hard_exud[pxl_mask]) # we can use fraction of white points in a neighborhood instead, # but it becomes regression task then pxl_df = pd.concat((pxl_df, cur_pxl_df), axis=0, ignore_index=True) y = np.hstack(y) y = y >= thr_high return pxl_df, y
def get_clusters_from_img_set(folder, box_shape=30): boxes = [] for img_fn in sorted(glob.glob(os.path.join(folder, '*.jpeg'))): img = load_image(img_fn) gb = prepare_img(img) t = np.percentile(gb.ravel(), 99) bright = gb > t bright = (bright * 255).astype(int) cl1 = bfs_clustered(bright, radius=2, tol=1) cl2 = erase_clusters(cl1, small_tol=0.0004 * cl1.shape[0] * cl1.shape[1], large_tol=2 * cl1.size, small_replace=0) cl_boxes, _ = get_clusters(cl2, box_shape=box_shape) cl_boxes = cl_boxes[1:] # ignoring background cl_boxes = cl_boxes[cl_boxes.mean(axis=1) != 0.0] boxes.append(cl_boxes) boxes = np.array(boxes) boxes = np.vstack(boxes) return boxes
def extract_RIM_ONE_v2(db_folder): """ Cropped (to optic disc region) images with polygonal optic disc segmentation. 380 x 394 original, 394 x 394 after post-processing. Required schema: db_folder/ Normal/ im{:03}.jpg (number from 0 to 255) im{:03}_gs.txt Glaucoma and glaucoma suspicious/ im{:03}.jpg (number from 256 to 455) im{:03}_gs.txt """ orig_resolution = (380, 394) result_resolution = (394, 394) X_all, Y_all, filecodes_all, is_ill = [], [], [], [] for pic_type in ('Normal', 'Glaucoma and glaucoma suspicious'): X, filenames = imh.load_set(os.path.join(db_folder, pic_type)) file_codes = [fn[-7:-4] for fn in filenames] Y = [] for i, code in enumerate(file_codes): anot_filename = os.path.join(db_folder, pic_type, 'Im{}-gs.txt'.format(code)) with open(anot_filename) as anot_fin: lines = anot_fin.readlines() ''' # polygonal segmentation coords = lines[1:lines.index('Ellipse parameters\r\n')] coords = np.array(map(int, coords)) if coords.size % 2 != 0: raise imh.ImLibException('n_coords % 2 != 0') coords = coords.reshape((coords.size / 2, 2)) coords = coords[1:] # optic disc center point is included in annotation for some reason segm_img = np.zeros(orig_resolution, dtype=np.uint8) cv2.fillPoly(segm_img, coords.reshape((1,) + coords.shape), color=1) ''' ''' # ellipse segmentation coords = lines[lines.index('Ellipse parameters\r\n') + 1:] coords = map(int, coords) i0, j0, a, b, angle = coords a /= 2 b /= 2 segm_img = np.zeros(orig_resolution, dtype=np.uint8) cv2.ellipse(segm_img, (i0, j0), (a, b), angle, 0, 360, color=1, thickness=-1) ''' # acquiring segmentation from pre-computed image segm_img = imh.load_image( os.path.join(db_folder, pic_type + ' segmentation', 'Im{}-gs_mask.jpg'.format(code))) Y.append(segm_img) is_ill.append(HEALTHY if pic_type == 'Normal' else GLAUCOMA_OR_SUSPECT) for i in xrange(len(X)): side = result_resolution[0] X[i] = imh.resize_image_to_square(X[i], side, pad_cval=0) Y[i] = imh.resize_image_to_square(Y[i], side, pad_cval=0) Y[i] = Y[i].reshape(Y[i].shape + (1, )) X_all.extend(X) Y_all.extend(Y) filecodes_all.extend(file_codes) return X_all, Y_all, filecodes_all, is_ill
def extract_DRISHTI_GS_train(db_folder, return_disc=True, return_cup=True): """ Full images with optic disc and optic cup segmentation. Average segmentation and "softmap" segmentation image are given. 50 images of various resolution close to 2040 x 1740. Data set is split into training and test sets. Groundtruth is available for training set only. This function returns Training set only. Required schema: db_folder/ Drishti-GS1_files/ Training/ Images/ drishtiGS_{:03}.png # some numbers are omitted, like 001, 003, 004, ... GT/ drishtiGS_{:03}/ drishtiGS_{:03}_cdrValues.txt AvgBoundary/ drishtiGS_{:03}_ODAvgBoundary.txt drishtiGS_{:03}_CupAvgBoundary.txt drishtiGS_{:03}_diskCenter.txt SoftMap/ drishtiGS_{:03}_ODsegSoftmap.png drishtiGS_{:03}_cupsegSoftmap.png """ result_resolution = (2040, 2040) disc_all, cup_all, file_codes_all = [], [], [] set_path = os.path.join(db_folder, 'Drishti-GS1_files', 'Training') images_path = os.path.join(set_path, 'Images') X_all, file_names = imh.load_set(images_path) rel_file_names = [os.path.split(fn)[-1] for fn in file_names] rel_file_names_wo_ext = [fn[:fn.rfind('.')] for fn in rel_file_names] file_codes = [ 'Training' + fn[fn.find('_'):] for fn in rel_file_names_wo_ext ] file_codes_all.extend(file_codes) for fn in rel_file_names_wo_ext: if return_disc: disc_segmn = imh.load_image( os.path.join(set_path, 'GT', fn, 'SoftMap', fn + '_ODsegSoftmap.png')) disc_all.append(disc_segmn) if return_cup: cup_segmn = imh.load_image( os.path.join(set_path, 'GT', fn, 'SoftMap', fn + '_cupsegSoftmap.png')) cup_all.append(cup_segmn) for i in xrange(len(X_all)): side = result_resolution[0] X_all[i] = imh.resize_image_to_square(X_all[i], side, pad_cval=0) if return_disc: disc_all[i] = imh.resize_image_to_square(disc_all[i], side, pad_cval=0) disc_all[i] = disc_all[i].reshape(disc_all[i].shape + (1, )) if return_cup: cup_all[i] = imh.resize_image_to_square(cup_all[i], side, pad_cval=0) cup_all[i] = cup_all[i].reshape(cup_all[i].shape + (1, )) if return_disc: if return_cup: return X_all, disc_all, cup_all, file_codes_all return X_all, disc_all, file_codes_all if return_cup: return X_all, cup_all, file_codes_all return X_all, file_codes_all
def extract_RIM_ONE_v3(db_folder, expert='avg', return_disc=True, return_cup=True): """ Cropped (to optic disc region, and a little more by vertical axis) images with polygonal optic disc segmentation. 1424 x 2144 original, 1424 x 1424 after post-processing. Images are two-channel (stereo) --- caught from 2 angles. But segmentation is given for only one view (see L/R letter in file name for clarification). So only one view of two is chosen. Accepted values for `expert`: 1, 2, 'avg'. Required schema: db_folder/ Healthy/ Stereo Images/ N-{}-[L,R].jpg (number is without leading zeros, from 1 to 92) (image cannot be used as is. it is two-part image, divided by vertical border) Expert1_masks/ N-{}-[L,R]-Cup-exp1.png (4 files for one image number and L/R characteristic) N-{}-[L,R]-Cup-exp1.txt N-{}-[L,R]-Disc-exp1.png N-{}-[L,R]-Disc-exp1.txt Expert2_masks/ N-{}-[L,R]-Cup-exp2.png (4 files for one image number and L/R characteristic) N-{}-[L,R]-Cup-exp2.txt N-{}-[L,R]-Disc-exp2.png N-{}-[L,R]-Disc-exp2.txt Average_masks/ N-{}-[L,R]-Cup-Avg.png (4 files for one image number and L/R characteristic) N-{}-[L,R]-Cup-Avg.txt N-{}-[L,R]-Disc-Avg.png N-{}-[L,R]-Disc-Avg.txt Glaucoma and suspects/ (...) (the same as for Healthy, but images start with G not N) """ orig_resolution = (1424, 2144) result_resolution = (1424, 1424) if expert == 1: expert_folder = 'Expert1_masks' suffix = 'exp1' elif expert == 2: expert_folder = 'Expert2_masks' suffix = 'exp2' elif expert == 'avg': expert_folder = 'Average_masks' suffix = 'Avg' else: raise imh.ImLibException('value for "expert" argument not understood') X_all, disc_all, cup_all, file_codes_all, is_ill = [], [], [], [], [] for pic_type in ('Healthy', 'Glaucoma and suspects'): X, file_names = imh.load_set( os.path.join(db_folder, pic_type, 'Stereo Images')) X_all.extend(X) rel_file_names = [os.path.split(fn)[-1] for fn in file_names] file_codes = [fn[:fn.rfind('.')] for fn in rel_file_names] file_codes_all.extend(file_codes) for fc in file_codes: if return_disc: disc_segmn = imh.load_image( os.path.join(db_folder, pic_type, expert_folder, '{}-Disc-{}.png'.format(fc, suffix))) disc_all.append(disc_segmn) if return_cup: cup_segmn = imh.load_image( os.path.join(db_folder, pic_type, expert_folder, '{}-Cup-{}.png'.format(fc, suffix))) cup_all.append(cup_segmn) is_ill.append(HEALTHY if pic_type == 'Healthy' else GLAUCOMA_OR_SUSPECT) for i in xrange(len(X_all)): side = result_resolution[0] if file_codes_all[i][-1] == 'L': X_all[i] = X_all[i][:, :orig_resolution[1] / 2] elif file_codes_all[i][-1] == 'R': X_all[i] = X_all[i][:, orig_resolution[1] / 2:] if return_disc: disc_all[i] = disc_all[i][:, :orig_resolution[1] / 2] if return_cup: cup_all[i] = cup_all[i][:, :orig_resolution[1] / 2] else: raise imh.ImLibException( 'image {} has no L/R characteristic'.format(file_codes_all[i])) X_all[i] = imh.resize_image_to_square(X_all[i], side, pad_cval=0) if return_disc: disc_all[i] = imh.resize_image_to_square(disc_all[i], side, pad_cval=0) disc_all[i] = disc_all[i].reshape(disc_all[i].shape + (1, )) if return_cup: cup_all[i] = imh.resize_image_to_square(cup_all[i], side, pad_cval=0) cup_all[i] = cup_all[i].reshape(cup_all[i].shape + (1, )) if return_disc: if return_cup: return X_all, disc_all, cup_all, file_codes_all, is_ill return X_all, disc_all, file_codes_all, is_ill if return_cup: return X_all, cup_all, file_codes_all, is_ill return X_all, file_codes_all, is_ill