예제 #1
0
def load_center_evaluate(idx_row,
                         df_annot,
                         path_annot,
                         path_visu=None,
                         col_prefix=''):
    """ complete pipeline fon input image and seg_pipe, such that load them,
    generate points, compute features and using given classifier predict labels

    :param (int, DF:row) idx_row:
    :param df_annot:
    :param str path_annot:
    :param str path_visu:
    :param str col_prefix:
    :return {str: float}:
    """
    idx, row = idx_row
    dict_row = dict(row)
    dict_row['image'] = os.path.splitext(
        os.path.basename(dict_row['path_image']))[0]

    if idx not in df_annot.index:
        logging.debug(
            'particular image/slice "%s" does not contain eggs '
            'of selected stage %s', idx, col_prefix)
        return dict_row

    name, img, segm, centres = run_train.load_image_segm_center((None, row))
    if centres is None:
        logging.debug('center missing "%s"', idx)
        return dict_row

    assert all(c in df_annot.columns for c in tl_visu.COLUMNS_POSITION_EGG_ANNOT), \
        'some required columns %s are missing for %s' % \
        (tl_visu.COLUMNS_POSITION_EGG_ANNOT, df_annot.columns)
    mask_eggs = estimate_eggs_from_info(df_annot.loc[idx], img.shape[:2])

    try:
        if EXPORT_ANNOT_EGGS:
            path_img = os.path.join(path_annot, idx + '.png')
            tl_data.io_imsave(path_img, mask_eggs.astype(np.uint8))

        if VISUAL_ANNOT_EGGS:
            fig = tl_visu.figure_image_segm_results(img, mask_eggs)
            fig.savefig(os.path.join(path_visu, idx + '_eggs.png'))
            plt.close(fig)

        if VISUAL_SEGM_CENTRES:
            run_clust.export_draw_image_centers_clusters(path_visu,
                                                         name,
                                                         img,
                                                         centres,
                                                         segm=segm)
        labels = np.array([1] * len(centres))
        dict_stat = compute_statistic_eggs_centres(dict_row, centres, labels,
                                                   mask_eggs, img, segm,
                                                   path_visu, col_prefix)
    except Exception:
        logging.exception('load_center_evaluate')
        dict_stat = dict_row
    return dict_stat
예제 #2
0
def perform_img_convert(path_img, path_out, dict_colors):
    """ perform the quantization together with loading and exporting

    :param str path_img:
    :param str path_out:
    :param {} dict_colors:
    """
    img = tl_data.io.imread(path_img)

    if img.ndim == 2:
        if len(dict_colors) == 0:
            dict_colors = seg_annot.DICT_COLOURS
        img_new = convert_labels_2_colors(img, dict_colors, path_out)
    elif img.ndim == 3:
        if img.shape[2] > 3:
            # for some 4 chanel images remove the last one (alpha)
            img = img[:, :, :3]
        img_new = convert_colors_2_labels(img, dict_colors, path_out)
    else:
        logging.warning('not supported image format %s', repr(img.shape))
        img_new = None

    if img_new is not None:
        img_new = img_new.astype(np.uint8)
        path_img_out = os.path.join(path_out, os.path.basename(path_img))
        logging.debug('export "%s"', path_img_out)
        tl_data.io_imsave(path_img_out, img_new)
예제 #3
0
def export_cut_objects(df_row,
                       path_out,
                       padding,
                       use_mask=True,
                       bg_color=None):
    """ cut and expert objects in image according given segmentation

    :param df_row:
    :param str path_out: path for exporting image
    :param int padding: set padding around segmented object
    """
    annot, _ = tl_data.load_image_2d(df_row['path_1'])
    img, name = tl_data.load_image_2d(df_row['path_2'])
    if annot.shape[:2] != img.shape[:2]:
        raise ImageDimensionError('image sizes not match %r vs %r' %
                                  (annot.shape, img.shape))

    uq_objects = np.unique(annot)
    if len(uq_objects) == 1:
        return

    for idx in uq_objects[1:]:
        img_new = tl_data.cut_object(img, annot == idx, padding, use_mask,
                                     bg_color)
        path_img = os.path.join(path_out, '%s_%i.png' % (name, idx))
        logging.debug('saving image "%s"', path_img)
        tl_data.io_imsave(path_img, img_new)
def segm_set_center_levels(name, seg_labels, path_out, levels=DISTANCE_LEVELS):
    """ set segmentation levels according distance inside object imsegm

    :param str name: image name
    :param ndarray seg_labels:
    :param str path_out: path for output
    :param [float] levels: distance levels fro segmentation levels
    """
    seg = np.zeros_like(seg_labels)

    # set bourders to 0
    # seg_labels = set_boundary_values(seg_labels)

    for obj_id in range(1, seg_labels.max() + 1):
        im_bin = (seg_labels == obj_id)
        if np.sum(im_bin) == 0:
            continue
        distance = ndimage.distance_transform_edt(im_bin)
        probab = distance / np.max(distance)
        pos_center = ndimage.measurements.center_of_mass(im_bin)
        # logging.debug('object %i with levels: %s', obj_id, repr(levels))
        for i, level in enumerate(levels):
            mask = probab > level
            if i > 0:
                radius = int(np.sqrt(np.sum(mask) / np.pi))
                im_level = draw_circle(pos_center, radius, mask.shape)
                mask = np.logical_and(mask, im_level)
                sel = morphology.disk(int(radius * 0.15))
                mask = morphology.binary_opening(mask, sel)
            seg[mask] = i + 1

    path_seg = os.path.join(path_out, name)
    tl_data.io_imsave(path_seg, seg.astype(np.uint8))
def segment_image_model(imgs_idx_path,
                        params,
                        model,
                        path_out=None,
                        path_visu=None,
                        show_debug_imgs=SHOW_DEBUG_IMAGES):
    """ segment image with already estimated model

    :param (int, str) imgs_idx_path:
    :param dict params: segmentation parameters
    :param obj scaler:
    :param obj pca:
    :param obj model:
    :param str path_out: path to dir with segmentation
    :param str path_visu: path to dir with debug images
    :param bool show_debug_imgs: whether show debug images
    :return (str, ndarray):
    """
    idx, path_img = parse_imgs_idx_path(imgs_idx_path)
    logging.debug('segmenting image: "%s"', path_img)
    idx_name = get_idx_name(idx, path_img)
    img = load_image(path_img, params['img_type'])

    path_img = os.path.join(params['path_exp'], FOLDER_IMAGE,
                            idx_name + '.png')
    tl_data.io_imsave(path_img, img.astype(np.uint8))

    debug_visual = dict() if show_debug_imgs else None

    try:
        segm, segm_soft = seg_pipe.segment_color2d_slic_features_model_graphcut(
            img,
            model,
            sp_size=params['slic_size'],
            sp_regul=params['slic_regul'],
            dict_features=params['features'],
            gc_regul=params['gc_regul'],
            gc_edge_type=params['gc_edge_type'],
            debug_visual=debug_visual)
        path_npz = os.path.join(path_out, idx_name + '.npz')
        np.savez_compressed(path_npz, segm_soft)
    except Exception:
        logging.exception('segment_color2d_slic_features_model_graphcut(...)')
        segm = np.zeros(img.shape[:2])

    boundary_size = int(np.sqrt(np.prod(segm.shape)) * 0.01)
    segm = seg_lbs.assume_bg_on_boundary(segm,
                                         bg_label=0,
                                         boundary_size=boundary_size)

    export_visual(idx_name, img, segm, debug_visual, path_out, path_visu)

    # gc.collect(), time.sleep(1)
    return idx_name, segm
def segment_image_independent(img_idx_path,
                              params,
                              path_out,
                              path_visu=None,
                              show_debug_imgs=SHOW_DEBUG_IMAGES):
    """ segment image indecently (estimate model just for this model)

    :param (int, str) img_idx_path:
    :param dict params: segmentation parameters
    :param str path_out: path to dir with segmentation
    :param str path_visu: path to dir with debug images
    :return (str, ndarray):
    """
    idx, path_img = parse_imgs_idx_path(img_idx_path)
    logging.debug('segmenting image: "%s"', path_img)
    idx_name = get_idx_name(idx, path_img)
    img = load_image(path_img, params['img_type'])

    path_img = os.path.join(params['path_exp'], FOLDER_IMAGE,
                            idx_name + '.png')
    tl_data.io_imsave(path_img, img.astype(np.uint8))

    debug_visual = dict() if show_debug_imgs else None
    try:
        segm, segm_soft = seg_pipe.pipe_color2d_slic_features_model_graphcut(
            img,
            nb_classes=params['nb_classes'],
            sp_size=params['slic_size'],
            sp_regul=params['slic_regul'],
            dict_features=params['features'],
            estim_model=params['estim_model'],
            pca_coef=params['pca_coef'],
            gc_regul=params['gc_regul'],
            gc_edge_type=params['gc_edge_type'],
            debug_visual=debug_visual)
        path_npz = os.path.join(path_out, idx_name + '.npz')
        np.savez_compressed(path_npz, segm_soft)
    except Exception:
        logging.exception('pipe_color2d_slic_features_model_graphcut(...)')
        segm = np.zeros(img.shape[:2])

    boundary_size = int(params['slic_size'] * 3)
    segm = seg_lbs.assume_bg_on_boundary(segm,
                                         bg_label=0,
                                         boundary_size=boundary_size)

    export_visual(idx_name, img, segm, debug_visual, path_out, path_visu)

    # gc.collect(), time.sleep(1)
    return idx_name, segm
def perform_img_inpaint(path_img, labels):
    """ perform the quantization together with loading and exporting

    :param str path_img: image path
    """
    logging.debug('repaint labels %r for image: "%s"', labels, path_img)
    img = np.array(tl_data.io.imread(path_img), dtype=np.float)

    for label in labels:
        img[img == label] = np.nan

    # interpolate nearest fo label
    valid_mask = ~np.isnan(img)
    im_paint = seg_annot.image_inpaint_pixels(img, valid_mask)

    tl_data.io_imsave(path_img, im_paint.astype(np.uint8))
예제 #8
0
def perform_quantize_image(path_image, list_colors, method='color'):
    """ perform the quantization together with loading and exporting

    :param str path_image:
    :param [(int, int, int)] list_colors: list of possible colours
    """
    logging.debug('quantize img: "%s"', path_image)
    im = tl_data.io_imread(path_image)
    if not im.ndim == 3:
        logging.warning('not valid color image of dims %r', im.shape)
        return
    im = im[:, :, :3]
    # im = io.imread(path_image)[:, :, :3]
    if method == 'color':
        im_q = seg_annot.quantize_image_nearest_color(im, list_colors)
    elif method == 'position':
        im_q = seg_annot.quantize_image_nearest_pixel(im, list_colors)
    else:
        logging.error('not implemented method "%s"', method)
        im_q = np.zeros(im.shape)
    path_image = os.path.splitext(path_image)[0] + '.png'
    tl_data.io_imsave(path_image, im_q.astype(np.uint8))
예제 #9
0
def perform_image_relabel(path_img, path_out, labels_old, labels_new):
    """ perform the quantization together with loading and exporting

    :param str path_img:
    :param str path_out:
    :param str labels_new:
    :param str labels_old:
    """
    logging.debug('repaint labels %r -> %r for image: "%s"',
                  labels_old, labels_new, path_img)
    img = np.array(tl_data.io.imread(path_img), dtype=int)

    max_label = int(max(img.max(), max(labels_old)))
    lut = np.array(range(max_label + 1))
    for label_old, label_new in zip(labels_old, labels_new):
        lut[label_old] = label_new
    img = lut[img]

    # for label_old, label_new in zip(labels_old, labels_new):
    #     img[img == label_old] = label_new

    logging.debug('resulting image labels: %r', np.unique(img).tolist())
    path_img_out = os.path.join(path_out, os.path.basename(path_img))
    tl_data.io_imsave(path_img_out, img)
예제 #10
0
def image_segmentation(idx_row, params, debug_export=DEBUG_EXPORT):
    """ image segmentation which prepare inputs (imsegm, centres)
    and perform segmentation of various imsegm methods

    :param (int, str) idx_row: input image and centres
    :param dict params: segmentation parameters
    :return str: image name
    """
    _, row_path = idx_row
    for k in dict(row_path):
        if isinstance(k, str) and k.startswith('path_'):
            row_path[k] = tl_data.update_path(row_path[k], absolute=True)
    logging.debug('segmenting image: "%s"', row_path['path_image'])
    name = os.path.splitext(os.path.basename(row_path['path_image']))[0]

    img = load_image(row_path['path_image'])
    # make the image like RGB
    img_rgb = np.rollaxis(np.tile(img, (3, 1, 1)), 0, 3)
    seg = load_image(row_path['path_segm'], 'segm')
    assert img_rgb.shape[:2] == seg.shape, \
        'image %r and segm %r do not match' % (img_rgb.shape[:2], seg.shape)
    if not os.path.isfile(row_path['path_centers']):
        logging.warning('no center was detected for "%s"', name)
        return name
    centers = tl_data.load_landmarks_csv(row_path['path_centers'])
    centers = tl_data.swap_coord_x_y(centers)
    if not list(centers):
        logging.warning('no center was detected for "%s"', name)
        return name
    # img = seg / float(seg.max())
    slic = seg_spx.segment_slic_img2d(img_rgb,
                                      sp_size=params['slic_size'],
                                      relative_compact=params['slic_regul'])

    path_segm = os.path.join(params['path_exp'], 'input', name + '.png')
    export_draw_image_segm(path_segm, img_rgb, segm_obj=seg, centers=centers)

    seg_simple = simplify_segm_3cls(seg)
    path_segm = os.path.join(params['path_exp'], 'simple', name + '.png')
    export_draw_image_segm(path_segm, seg_simple - 1.)

    dict_segment = create_dict_segmentation(params, slic, seg, img, centers)

    image_name = name + '.png'
    centre_name = name + '.csv'

    # iterate over segmentation methods and perform segmentation on this image
    for method in dict_segment:
        (fn, args) = dict_segment[method]
        logging.debug(' -> %s on "%s"', method, name)
        path_dir = os.path.join(params['path_exp'], method)  # n.split('_')[0]
        path_segm = os.path.join(path_dir, image_name)
        path_centre = os.path.join(path_dir + DIR_CENTRE_POSIX, centre_name)
        path_fig = os.path.join(path_dir + DIR_VISUAL_POSIX, image_name)
        path_debug = os.path.join(path_dir + DIR_DEBUG_POSIX, name)
        # assuming that segmentation may fail
        try:
            t = time.time()
            if debug_export and 'rg2sp' in method:
                os.mkdir(path_debug)
                segm_obj, centers, dict_export = fn(*args,
                                                    debug_export=path_debug)
            else:
                segm_obj, centers, dict_export = fn(*args)

            # also export ellipse params here or inside the segm fn
            if dict_export is not None:
                for k in dict_export:
                    export_partial(k, dict_export[k], path_dir, name)

            logging.info('running time of %r on image "%s" is %d s',
                         fn.__name__, image_name,
                         time.time() - t)
            tl_data.io_imsave(path_segm, segm_obj.astype(np.uint8))
            export_draw_image_segm(path_fig, img_rgb, seg, segm_obj, centers)
            # export also centers
            centers = tl_data.swap_coord_x_y(centers)
            tl_data.save_landmarks_csv(path_centre, centers)
        except Exception:
            logging.exception('segment fail for "%s" via %s', name, method)

    return name