12 ssl._create_default_https_context = ssl._create_unverified_context
15 from hydra.core.hydra_config
import HydraConfig
16 from omegaconf
import DictConfig
18 import tensorflow
as tf
20 from common.utils
import aspect_ratio_dict, color_mode_n6_dict
25 Generates a C header file containing user configuration for the AI model.
28 config: A configuration object containing user configuration for the AI model.
29 quantized_model_path: The path to the quantized model file.
33 def __init__(self, **entries):
34 self.__dict__.update(entries)
36 params = Flags(**config)
37 interpreter_quant = tf.lite.Interpreter(model_path=quantized_model_path)
38 input_details = interpreter_quant.get_input_details()[0]
39 output_details = interpreter_quant.get_output_details()[0]
40 input_shape = input_details[
'shape']
42 path = os.path.join(HydraConfig.get().runtime.output_dir,
"C_header/")
46 except OSError
as error:
51 with open(os.path.join(path,
"app_config.h"),
"wt")
as f:
53 f.write(
"******************************************************************************\n")
54 f.write(
"* @file app_config.h\n")
55 f.write(
"* @author GPM Application Team\n")
57 f.write(
"******************************************************************************\n")
58 f.write(
"* @attention\n")
60 f.write(
"* Copyright (c) 2023 STMicroelectronics.\n")
61 f.write(
"* All rights reserved.\n")
63 f.write(
"* This software is licensed under terms that can be found in the LICENSE file\n")
64 f.write(
"* in the root directory of this software component.\n")
65 f.write(
"* If no LICENSE file comes with this software, it is provided AS-IS.\n")
67 f.write(
"******************************************************************************\n")
69 f.write(
"/* --------------- Generated code ----------------- */\n")
70 f.write(
"#ifndef APP_CONFIG\n")
71 f.write(
"#define APP_CONFIG\n\n")
72 f.write(
'#include "arm_math.h"\n\n')
73 f.write(
"#define USE_DCACHE\n\n")
74 f.write(
"/*Defines: CMW_MIRRORFLIP_NONE; CMW_MIRRORFLIP_FLIP; CMW_MIRRORFLIP_MIRROR; CMW_MIRRORFLIP_FLIP_MIRROR;*/\n")
75 f.write(
"#define CAMERA_FLIP CMW_MIRRORFLIP_NONE\n\n")
77 f.write(
"#define ASPECT_RATIO_CROP (1) /* Crop both pipes to nn input aspect ratio; Original aspect ratio kept */\n")
78 f.write(
"#define ASPECT_RATIO_FIT (2) /* Resize both pipe to NN input aspect ratio; Original aspect ratio not kept */\n")
79 f.write(
"#define ASPECT_RATIO_FULLSCREEN (3) /* Resize camera image to NN input size and display a fullscreen image */\n")
80 f.write(
"#define ASPECT_RATIO_MODE {}\n".format(aspect_ratio_dict[params.preprocessing.resizing.aspect_ratio]))
83 f.write(
"/* Postprocessing type configuration */\n")
85 if params.general.model_type ==
"heatmaps_spe":
86 f.write(
"#define POSTPROCESS_TYPE POSTPROCESS_SPE_MOVENET_UF\n\n")
87 elif params.general.model_type ==
"yolo_mpe":
88 f.write(
"#define POSTPROCESS_TYPE POSTPROCESS_MPE_YOLO_V8_UF\n\n")
90 raise ValueError(
"Please select one supported post-processing option: heatmaps_spe or yolo_mpe.")
92 f.write(
"#define NN_HEIGHT ({})\n".format(int(input_shape[1])))
93 f.write(
"#define NN_WIDTH ({})\n".format(int(input_shape[2])))
94 f.write(
"#define NN_BPP 3")
96 f.write(
"#define COLOR_BGR (0)\n")
97 f.write(
"#define COLOR_RGB (1)\n")
98 f.write(
"#define COLOR_MODE {}\n".format(color_mode_n6_dict[params.preprocessing.color_mode]))
100 if params.general.model_type ==
"heatmaps_spe":
101 f.write(
"\n/* Post processing values */\n")
102 f.write(
"#define AI_POSE_PP_CONF_THRESHOLD ({})\n".format(float(params.postprocessing.kpts_conf_thresh)))
103 f.write(
"#define AI_POSE_PP_POSE_KEYPOINTS_NB ({})\n".format(int(output_details[
'shape'][3])))
104 f.write(
"#define AI_SPE_MOVENET_POSTPROC_HEATMAP_WIDTH (NN_WIDTH/4)\n")
105 f.write(
"#define AI_SPE_MOVENET_POSTPROC_HEATMAP_HEIGHT (NN_HEIGHT/4)\n")
106 f.write(
"#define AI_SPE_MOVENET_POSTPROC_NB_KEYPOINTS (AI_POSE_PP_POSE_KEYPOINTS_NB) /* Only 13 and 17 keypoints are supported for the skeleton reconstruction */\n\n")
107 elif params.general.model_type ==
"yolo_mpe":
108 out_shape = output_details[
"shape"]
109 nb_kpt = (out_shape[1]-5)/3
110 f.write(
"\n/* Post processing values */\n")
111 f.write(
"#define AI_MPE_YOLOV8_PP_NB_CLASSES (1)\n")
112 f.write(
"#define AI_MPE_YOLOV8_PP_TOTAL_BOXES ({})\n".format(int(out_shape[2])))
113 f.write(
"#define AI_MPE_YOLOV8_PP_MAX_BOXES_LIMIT ({})\n".format(int(params.postprocessing.max_detection_boxes)))
114 f.write(
"#define AI_MPE_YOLOV8_PP_IOU_THRESHOLD ({})\n".format(float(params.postprocessing.NMS_thresh)))
115 f.write(
"#define AI_MPE_YOLOV8_PP_CONF_THRESHOLD ({})\n\n".format(float(params.postprocessing.confidence_thresh)))
117 f.write(
"#define AI_POSE_PP_CONF_THRESHOLD ({})\n".format(float(params.postprocessing.kpts_conf_thresh)))
118 f.write(
"#define AI_POSE_PP_POSE_KEYPOINTS_NB ({})\n".format(int(nb_kpt)))
120 raise ValueError(f
"model_type not supported: {params.general.model_type}")
121 f.write(
'/* Display */\n')
122 f.write(
'#define WELCOME_MSG_0 "Single/multi pose estimation - Hand landmark"\n')
123 f.write(
'#define WELCOME_MSG_1 "{}"\n'.format(os.path.basename(params.general.model_path)))
124 if config.deployment.hardware_setup.board ==
'NUCLEO-N657X0-Q':
125 f.write(
'#define WELCOME_MSG_2 ((char *[2]) {"Model Running in STM32 MCU", "internal memory"})')
127 f.write(
'#define WELCOME_MSG_2 "{}"\n'.format(
"Model Running in STM32 MCU internal memory"))
129 f.write(
"#endif /* APP_CONFIG */\n")
None gen_h_user_file_n6(DictConfig config=None, str quantized_model_path=None)