Beispiel #1
0
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
Beispiel #2
0
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
Beispiel #3
0
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
Beispiel #4
0
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
Beispiel #5
0
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