def split_image(img_path, overwrite=False, cut_dim=CUT_DIMENSION):
    """ split two images in single dimension

    the input images assume to contain two names in the image name separated by "_"

    :param str img_path: path to the input / output image
    :param bool overwrite: allow overwrite exiting output images
    :param int cut_dim: define splitting dimension
    """
    name = os.path.splitext(os.path.basename(img_path))[0]
    ext = os.path.splitext(os.path.basename(img_path))[-1]
    folder = os.path.dirname(img_path)
    obj_names = name.split('_')
    paths_img = [
        os.path.join(folder, obj_name + ext) for obj_name in obj_names
    ]

    if all(os.path.isfile(p) for p in paths_img) and not overwrite:
        logging.debug('existing all splits of %r', paths_img)
        return

    img = load_large_image(img_path)
    # work with just a scaled version
    scale_factor = max(1, img.shape[cut_dim] / float(SCALE_SIZE))
    sc = 1. / scale_factor
    order = cv.INTER_AREA if scale_factor > 1 else cv.INTER_LINEAR
    img_small = 255 - cv.resize(img, None, fx=sc, fy=sc, interpolation=order)
    img_edge = project_object_edge(img_small, cut_dim)
    del img_small

    # prepare all cut edges and scale them to original image size
    splits = find_split_objects(img_edge, nb_objects=len(obj_names))
    if not splits:
        logging.error('no splits found for %s', img_path)
        return

    edges = [
        int(round(i * scale_factor)) for i in [0] + splits + [len(img_edge)]
    ]

    # cutting images
    for i, path_img_cut in enumerate(paths_img):
        if os.path.isfile(path_img_cut) and not overwrite:
            logging.debug('existing "%s"', path_img_cut)
            continue
        if cut_dim == 0:
            img_cut = img[edges[i]:edges[i + 1], ...]
        elif cut_dim == 1:
            img_cut = img[:, edges[i]:edges[i + 1], ...]
        else:
            raise Exception('unsupported dimension: %i' % cut_dim)
        save_large_image(path_img_cut, img_cut)
        gc.collect()
        time.sleep(1)
Esempio n. 2
0
def crop_image(img_path, crop_dims=(0, 1), padding=0.15):
    """ crop umages to by tight around tissue

    :param str img_path: path to image
    :param tuple(int) crop_dims: crop in selected dimensions
    :param float padding: padding around tissue
    """
    img = load_large_image(img_path)
    scale_factor = max(1, np.mean(img.shape[:2]) / float(SCALE_SIZE))
    # work with just a scaled version
    sc = 1. / scale_factor
    order = cv.INTER_AREA if scale_factor > 1 else cv.INTER_LINEAR
    img_small = 255 - cv.resize(img, None, fx=sc, fy=sc, interpolation=order)

    crops = {}
    for crop_dim in crop_dims:
        if crop_dim not in (0, 1):
            raise ValueError('not supported dimension: %i' % crop_dim)
        img_edge = project_object_edge(img_small, crop_dim)

        begin, end = find_largest_object(img_edge, threshold=TISSUE_CONTENT)
        # img_diag = int(np.sqrt(img.shape[0] ** 2 + img.shape[1] ** 2))
        pad_px = padding * (end - begin) * scale_factor
        begin_px = max(0, int((begin * scale_factor) - pad_px))
        end_px = min(img.shape[crop_dim], int((end * scale_factor) + pad_px))
        crops[crop_dim] = (begin_px, end_px)
    del img_small

    for _ in range(2):
        if 0 not in crops:
            crops[0] = (0, img.shape[0])

    img = img[crops[0][0]:crops[0][1], crops[1][0]:crops[1][1], ...]

    save_large_image(img_path, img)
    gc.collect()
    time.sleep(1)