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