Publishing 2019 R1 content
[platform/upstream/dldt.git] / tools / accuracy_checker / accuracy_checker / annotation_converters / convert.py
1 """
2 Copyright (c) 2019 Intel Corporation
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8       http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 """
16 import warnings
17 import json
18 from pathlib import Path
19 from argparse import ArgumentParser
20 from functools import partial
21
22 import numpy as np
23
24 from ..utils import get_path
25
26 from .format_converter import BaseFormatConverter
27
28
29 def build_argparser():
30     parser = ArgumentParser(
31         description="Converts annotation form a arbitrary format to accuracy-checker specific format", add_help=False
32     )
33     parser.add_argument(
34         "converter",
35         help="Specific converter to run",
36         choices=list(BaseFormatConverter.providers.keys())
37     )
38     parser.add_argument(
39         "-o", "--output_dir",
40         help="Directory to save converted annotation and meta info",
41         required=False,
42         type=partial(get_path, is_directory=True)
43     )
44     parser.add_argument("-m", "--meta_name", help="Meta info file name", required=False)
45     parser.add_argument("-a", "--annotation_name", help="Annotation file name", required=False)
46     parser.add_argument("-ss", "--subsample", help="Dataset subsample size", required=False)
47     parser.add_argument("--subsample_seed", help="Seed for generation dataset subsample", type=int, required=False)
48
49     return parser
50
51
52 def make_subset(annotation, size, seed=666):
53     dataset_size = len(annotation)
54     if dataset_size < size:
55         warnings.warn('dataset size - {} less than subsample size - {}'.format(dataste_size, size))
56         return annotation
57     np.random.seed(seed)
58     return list(np.random.choice(annotation, size=size, replace=False))
59
60
61 def main():
62     main_argparser = build_argparser()
63     args, _ = main_argparser.parse_known_args()
64     converter, converter_argparser, converter_args = get_converter_arguments(args)
65
66     main_argparser = ArgumentParser(parents=[main_argparser, converter_argparser])
67     args = main_argparser.parse_args()
68
69     converter = configure_converter(converter_args, args, converter)
70     out_dir = args.output_dir or Path.cwd()
71
72     result, meta = converter.convert()
73
74     subsample = args.subsample
75     if subsample:
76         if subsample.endswith('%'):
77             subsample_ratio = float(subsample[:-1]) / 100
78             subsample_size = int(len(result) * subsample_ratio)
79         else:
80             subsample_size = int(args.subsample)
81
82         result = make_subset(result, subsample_size)
83
84     converter_name = converter.get_name()
85     annotation_name = args.annotation_name or "{}.pickle".format(converter_name)
86     meta_name = args.meta_name or "{}.json".format(converter_name)
87
88     annotation_file = out_dir / annotation_name
89     meta_file = out_dir / meta_name
90
91     save_annotation(result, meta, annotation_file, meta_file)
92
93
94 def save_annotation(annotation, meta, annotation_file, meta_file):
95     if annotation_file:
96         with annotation_file.open('wb') as file:
97             for representation in annotation:
98                 representation.dump(file)
99     if meta_file and meta:
100         with meta_file.open('wt') as file:
101             json.dump(meta, file)
102
103
104 def configure_converter(converter_options, args, converter):
105     args_dict, converter_options_dict = vars(args), vars(converter_options)
106     converter_config = {
107         option_name: option_value for option_name, option_value in args_dict.items()
108         if option_name in converter_options_dict and option_value is not None
109     }
110     converter_config['converter'] = args.converter
111     converter.config = converter_config
112     converter.validate_config()
113     converter.configure()
114
115     return converter
116
117
118 def get_converter_arguments(arguments):
119     converter = BaseFormatConverter.provide(arguments.converter)
120     converter_argparser = converter.get_argparser()
121     converter_options, _ = converter_argparser.parse_known_args()
122     return converter, converter_argparser, converter_options
123
124
125 if __name__ == '__main__':
126     main()