[853718]: / bm_dataset / rescale_tissue_images.py

Download this file

131 lines (102 with data), 4.4 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
"""
Converting images to particular scales
With given path pattern to images crete particular scales within the same set
.. note:: Using these scripts for 1+GB images take several tens of GB RAM
Sample usage::
python rescale_tissue_images.py \
-i "/datagrid/Medical/dataset_ANHIR/images_private/COAD_*/scale-100pc/*.png" \
--scales 5 10 25 50 -ext .jpg --nb_workers 4
Copyright (C) 2016-2019 Jiri Borovec <jiri.borovec@fel.cvut.cz>
"""
import argparse
import gc
import glob
import logging
import os
import sys
import time
from functools import partial
import cv2 as cv
sys.path += [os.path.abspath('.'), os.path.abspath('..')] # Add path to root
from birl.utilities.data_io import create_folder
from birl.utilities.dataset import args_expand_parse_images, load_large_image, parse_path_scale, save_large_image
from birl.utilities.experiments import get_nb_workers, is_iterable, iterate_mproc_map
NB_WORKERS = get_nb_workers(0.5)
DEFAULT_SCALES = (5, 10, 15, 20, 25, 50)
IMAGE_EXTENSION = '.jpg'
# IMWRITE_PARAMS = (cv.IMWRITE_JPEG_QUALITY, 100)
FOLDER_TEMPLATE = 'scale-%ipc'
def arg_parse_params():
""" parse the input parameters
:return dict: parameters
"""
# SEE: https://docs.python.org/3/library/argparse.html
parser = argparse.ArgumentParser()
parser.add_argument(
'--scales', type=int, required=False, nargs='+', help='list of output scales', default=DEFAULT_SCALES
)
parser.add_argument(
'-ext', '--image_extension', type=str, required=False, help='output image extension', default=IMAGE_EXTENSION
)
args = args_expand_parse_images(parser, NB_WORKERS)
if not is_iterable(args['scales']):
args['scales'] = [args['scales']]
logging.info('ARGUMENTS: \n%r' % args)
return args
def scale_image(img_path, scale, image_ext=IMAGE_EXTENSION, overwrite=False):
""" scaling images by given scale factor
:param img_path: input image path
:param int scale: selected scaling in percents
:param str image_ext: image extension used on output
:param bool overwrite: whether overwrite existing image on output
"""
base = os.path.dirname(os.path.dirname(img_path))
name, _ = os.path.splitext(os.path.basename(img_path))
base_scale = parse_path_scale(os.path.dirname(img_path))
path_dir = os.path.join(base, FOLDER_TEMPLATE % scale)
create_folder(path_dir)
path_img_scale = os.path.join(path_dir, name + image_ext)
if os.path.isfile(path_img_scale) and not overwrite:
logging.debug('existing "%s"', path_img_scale)
return
img = load_large_image(img_path)
sc = scale / float(base_scale)
# for down-scaling use just linear
if sc == 1.:
img_sc = img
else:
interp = cv.INTER_CUBIC if sc > 1 else cv.INTER_LINEAR
img_sc = cv.resize(img, None, fx=sc, fy=sc, interpolation=interp)
del img
gc.collect()
time.sleep(1)
logging.debug('creating >> %s', path_img_scale)
save_large_image(path_img_scale, img_sc)
def wrap_scale_image(img_path_scale, image_ext=IMAGE_EXTENSION, overwrite=False):
img_path, scale = img_path_scale
try:
return scale_image(img_path, scale, image_ext, overwrite)
except Exception:
logging.exception('scaling %i of image: %s', scale, img_path)
def main(path_images, scales, image_extension, overwrite, nb_workers):
""" main entry point
:param str path_images: path to input images
:param list(float) scales: define scales in percentage, range (0, 100)
:param str image_extension: image extension used on output
:param bool overwrite: whether overwrite existing image on output
:param int nb_workers: nb jobs running in parallel
:return:
"""
image_paths = sorted(glob.glob(path_images))
image_path_scales = [(im_path, sc) for im_path in image_paths for sc in scales]
if not image_paths:
logging.info('No images found on "%s"', path_images)
return
_wrap_scale = partial(wrap_scale_image, image_ext=image_extension, overwrite=overwrite)
list(iterate_mproc_map(_wrap_scale, image_path_scales, desc='Scaling images', nb_workers=nb_workers))
if __name__ == '__main__':
logging.basicConfig(level=logging.INFO)
arg_params = arg_parse_params()
logging.info('running...')
main(**arg_params)
logging.info('DONE')