This repository has been archived by the owner on Feb 11, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 26
/
bm_template.py
180 lines (147 loc) · 6.54 KB
/
bm_template.py
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
"""
All other benchmarks should be deviated this way so the core functionality
of the benchmarks such as loading or evaluation is not overwritten
INSTALLATION:
1. ...
Sample run::
mkdir ./results
touch sample-config.yaml
python birl/bm_template.py \
-t ./data-images/pairs-imgs-lnds_histol.csv \
-d ./data-images \
-o ./results \
--visual --unique \
-cfg ./sample-config.yaml
Copyright (C) 2017-2019 Jiri Borovec <[email protected]>
"""
import logging
import os
import sys
# this is used while calling this file as a script
sys.path += [os.path.abspath('.'), os.path.abspath('..')] # Add path to root
from birl.benchmark import ImRegBenchmark
from birl.utilities.experiments import create_basic_parser
class BmTemplate(ImRegBenchmark):
""" Basic template showing utilization by inheriting general workflow.
This case serves as an example of using the general image regist. benchmark.
:param dict params: dictionary with experiment configuration,
the required options are names in `REQUIRED_PARAMS`,
note that the basic parameters are inherited
General methods that should be overwritten:
* `_check_required_params`
* `_prepare_img_registration`
* `_execute_img_registration`/`_generate_regist_command`
* `_extract_warped_image_landmarks`
* `_extract_execution_time`
* `_clear_after_registration`
.. note:: The actual implementation simulates the "WORSE" registration while
it blindly copies the moving landmarks as results of the registration.
It also copies the moving images so there is correct "warping" between
image and landmarks. It means that there was no registration performed.
Examples
--------
>>> # Running in single thread:
>>> from birl.utilities.data_io import create_folder, update_path
>>> path_out = create_folder('temp_results')
>>> path_csv = os.path.join(update_path('data-images'), 'pairs-imgs-lnds_mix.csv')
>>> open('sample_config.yaml', 'w').close()
>>> BmTemplate.main({
... 'path_table': path_csv,
... 'path_out': path_out,
... 'nb_workers': 1,
... 'unique': False,
... 'visual': True,
... 'path_config': 'sample_config.yaml'
... }) # doctest: +ELLIPSIS
({...}, '...BmTemplate')
>>> import shutil
>>> shutil.rmtree(path_out, ignore_errors=True)
>>> os.remove('sample_config.yaml')
>>> # Running in multiple parallel threads:
>>> from birl.utilities.data_io import create_folder, update_path
>>> path_out = create_folder('temp_results')
>>> path_csv = os.path.join(update_path('data-images'), 'pairs-imgs-lnds_mix.csv')
>>> params = {'path_table': path_csv,
... 'path_out': path_out,
... 'nb_workers': 2,
... 'unique': False,
... 'visual': True,
... 'path_config': ''}
>>> benchmark = BmTemplate(params)
>>> benchmark.run()
True
>>> del benchmark
>>> import shutil
>>> shutil.rmtree(path_out, ignore_errors=True)
"""
REQUIRED_PARAMS = ImRegBenchmark.REQUIRED_PARAMS + ['path_config']
def _prepare(self):
logging.info('-> copy configuration...')
self._copy_config_to_expt('path_config')
def _prepare_img_registration(self, item):
""" prepare the experiment folder if it is required,
eq. copy some extra files
:param dict item: dictionary with regist. params
:return dict: the same or updated registration info
"""
logging.debug('.. no preparing before registration experiment')
return item
def _generate_regist_command(self, item):
""" generate the registration command(s)
:param dict item: dictionary with registration params
:return str|list(str): the execution commands
"""
logging.debug('.. simulate registration: copy the source image and landmarks, like regist. failed')
_, path_im_move, _, path_lnds_move = self._get_paths(item)
path_reg_dir = self._get_path_reg_dir(item)
name_img = os.path.basename(item[self.COL_IMAGE_MOVE])
cmd_img = 'cp %s %s' % (path_im_move, os.path.join(path_reg_dir, name_img))
name_lnds = os.path.basename(item[self.COL_POINTS_MOVE])
cmd_lnds = 'cp %s %s' % (path_lnds_move, os.path.join(path_reg_dir, name_lnds))
commands = [cmd_img, cmd_lnds]
return commands
def _extract_warped_image_landmarks(self, item):
""" get registration results - warped registered images and landmarks
:param dict item: dictionary with registration params
:return dict: paths to warped images/landmarks
"""
path_reg_dir = self._get_path_reg_dir(item)
# detect image
path_img = os.path.join(path_reg_dir, os.path.basename(item[self.COL_IMAGE_MOVE]))
# detect landmarks
path_lnd = os.path.join(path_reg_dir, os.path.basename(item[self.COL_POINTS_MOVE]))
# return formatted results
return {self.COL_IMAGE_MOVE_WARP: path_img, self.COL_POINTS_MOVE_WARP: path_lnd}
def _extract_execution_time(self, item):
""" if needed update the execution time
:param dict item: dictionary with registration params
:return float|None: time in minutes
"""
return 1. / 60 # running constant time 1 sec.
def _clear_after_registration(self, item):
""" clean unnecessarily files after the registration
:param dict item: dictionary with regist. information
:return dict: the same or updated regist. info
"""
logging.debug('.. no cleaning after registration experiment')
return item
@staticmethod
def extend_parse(arg_parser):
""" extent the basic arg parses by some extra required parameters
:return object:
>>> parser = BmTemplate.extend_parse(create_basic_parser())
>>> type(parser)
<class 'argparse.ArgumentParser'>
"""
# SEE: https://docs.python.org/3/library/argparse.html
arg_parser.add_argument('-cfg', '--path_config', type=str, required=True, help='some extra parameters')
return arg_parser
# RUN by given parameters
if __name__ == '__main__':
logging.basicConfig(level=logging.INFO)
logging.info(__doc__)
arg_params, path_expt = BmTemplate.main()
if arg_params.get('run_comp_benchmark', False):
# from bm_experiments import bm_comp_perform
# bm_comp_perform.main(path_expt)
logging.info('Here you can call the separate benchmark to measure your computer performances.')