blob: c53fbd7fd682e30706c7357c2eb36d308131eb97 [file] [log] [blame]
alexander3c798932021-03-26 21:42:19 +00001# Copyright (c) 2021 Arm Limited. All rights reserved.
2# SPDX-License-Identifier: Apache-2.0
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"""
17Utility script to convert a set of RGB images in a given location into
18corresponding cpp files and a single hpp file referencing the vectors
19from the cpp files.
20"""
21import datetime
22import glob
23import math
24import os
25import numpy as np
26
27from argparse import ArgumentParser
28from PIL import Image, UnidentifiedImageError
29from jinja2 import Environment, FileSystemLoader
30
31parser = ArgumentParser()
32parser.add_argument("--image_path", type=str, help="path to images folder or image file to convert.")
33parser.add_argument("--source_folder_path", type=str, help="path to source folder to be generated.")
34parser.add_argument("--header_folder_path", type=str, help="path to header folder to be generated.")
35parser.add_argument("--image_size", type=int, nargs=2, help="Size (width and height) of the converted images.")
36parser.add_argument("--license_template", type=str, help="Header template file",
37 default="header_template.txt")
38args = parser.parse_args()
39
40env = Environment(loader=FileSystemLoader(os.path.join(os.path.dirname(__file__), 'templates')),
41 trim_blocks=True,
42 lstrip_blocks=True)
43
44
45def write_hpp_file(header_file_path, cc_file_path, header_template_file, num_images, image_filenames,
46 image_array_names, image_size):
47 print(f"++ Generating {header_file_path}")
48 header_template = env.get_template(header_template_file)
49 hdr = header_template.render(script_name=os.path.basename(__file__),
50 gen_time=datetime.datetime.now(),
51 year=datetime.datetime.now().year)
52 env.get_template('Images.hpp.template').stream(common_template_header=hdr,
53 imgs_count=num_images,
54 img_size=str(image_size[0] * image_size[1] * 3),
55 var_names=image_array_names) \
56 .dump(str(header_file_path))
57
58 env.get_template('Images.cc.template').stream(common_template_header=hdr,
59 var_names=image_array_names,
60 img_names=image_filenames) \
61 .dump(str(cc_file_path))
62
63
64def write_individual_img_cc_file(image_filename, cc_filename, header_template_file, original_image,
65 image_size, array_name):
66 print(f"++ Converting {image_filename} to {os.path.basename(cc_filename)}")
67
68 header_template = env.get_template(header_template_file)
69 hdr = header_template.render(script_name=os.path.basename(__file__),
70 gen_time=datetime.datetime.now(),
71 file_name=os.path.basename(image_filename),
72 year=datetime.datetime.now().year)
Isabella Gottardi79d41542021-10-20 15:52:32 +010073 # IFM size
74 ifm_width = image_size[0]
75 ifm_height = image_size[1]
alexander3c798932021-03-26 21:42:19 +000076
Isabella Gottardi79d41542021-10-20 15:52:32 +010077 # Aspect ratio resize
78 scale_ratio = (float)(max(ifm_width, ifm_height)) / (float)(min(original_image.size[0], original_image.size[1]))
79 resized_width = (int)(original_image.size[0] * scale_ratio)
80 resized_height = (int)(original_image.size[1] * scale_ratio)
81 resized_image = original_image.resize([resized_width,resized_height], Image.BILINEAR)
82
83 # Crop the center of the image
84 resized_image = resized_image.crop((
85 (resized_width - ifm_width) / 2, # left
86 (resized_height - ifm_height) / 2, # top
87 (resized_width + ifm_width) / 2, # right
88 (resized_height + ifm_height) / 2 # bottom
89 ))
alexander3c798932021-03-26 21:42:19 +000090
91 # Convert the image and write it to the cc file
92 rgb_data = np.array(resized_image, dtype=np.uint8).flatten()
93 hex_line_generator = (', '.join(map(hex, sub_arr))
94 for sub_arr in np.array_split(rgb_data, math.ceil(len(rgb_data) / 20)))
95 env.get_template('image.cc.template').stream(common_template_header=hdr,
96 var_name=array_name,
97 img_data=hex_line_generator) \
98 .dump(str(cc_filename))
99
100
101def main(args):
102 # Keep the count of the images converted
103 image_idx = 0
104 image_filenames = []
105 image_array_names = []
106
107
108 if os.path.isdir(args.image_path):
109 filepaths = sorted(glob.glob(os.path.join(args.image_path, '**/*.*'), recursive=True))
110 elif os.path.isfile(args.image_path):
111 filepaths = [args.image_path]
112 else:
113 raise OSError("Directory or file does not exist.")
114
115 for filepath in filepaths:
116 filename = os.path.basename(filepath)
117
118 try:
119 original_image = Image.open(filepath).convert("RGB")
120 except UnidentifiedImageError:
121 print(f"-- Skipping file {filepath} due to unsupported image format.")
122 continue
123
124 image_filenames.append(filename)
125
126 # Save the cc file
127 cc_filename = os.path.join(args.source_folder_path,
128 (filename.rsplit(".")[0]).replace(" ", "_") + ".cc")
129 array_name = "im" + str(image_idx)
130 image_array_names.append(array_name)
131 write_individual_img_cc_file(filename, cc_filename, args.license_template,
132 original_image, args.image_size, array_name)
133
134 # Increment image index
135 image_idx = image_idx + 1
136
137 header_filename = "InputFiles.hpp"
138 header_filepath = os.path.join(args.header_folder_path, header_filename)
139 common_cc_filename = "InputFiles.cc"
140 common_cc_filepath = os.path.join(args.source_folder_path, common_cc_filename)
Kshitij Sisodia659fcd92021-05-19 10:30:06 +0100141
142 if len(image_filenames) > 0:
143 write_hpp_file(header_filepath, common_cc_filepath, args.license_template,
144 image_idx, image_filenames, image_array_names, args.image_size)
145 else:
146 raise FileNotFoundError("No valid images found.")
alexander3c798932021-03-26 21:42:19 +0000147
148
149if __name__ == '__main__':
150 main(args)