blob: 67e784bf034497f5776b219536243befbf977e14 [file] [log] [blame]
alexander3c798932021-03-26 21:42:19 +00001/*
Liam Barrye9588502022-01-25 14:31:15 +00002 * Copyright (c) 2021-2022 Arm Limited. All rights reserved.
alexander3c798932021-03-26 21:42:19 +00003 * SPDX-License-Identifier: Apache-2.0
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17#include "UseCaseCommonUtils.hpp"
alexander3c798932021-03-26 21:42:19 +000018#include "InputFiles.hpp"
Kshitij Sisodiaf9c19ea2021-05-07 16:08:14 +010019#include <inttypes.h>
20
Éanna Ó Catháin8f958872021-09-15 09:32:30 +010021
22void DisplayCommonMenu()
23{
24 printf("\n\n");
25 printf("User input required\n");
26 printf("Enter option number from:\n\n");
27 printf(" %u. Classify next ifm\n", common::MENU_OPT_RUN_INF_NEXT);
28 printf(" %u. Classify ifm at chosen index\n", common::MENU_OPT_RUN_INF_CHOSEN);
29 printf(" %u. Run classification on all ifm\n", common::MENU_OPT_RUN_INF_ALL);
30 printf(" %u. Show NN model info\n", common::MENU_OPT_SHOW_MODEL_INFO);
31 printf(" %u. List ifm\n\n", common::MENU_OPT_LIST_IFM);
32 printf(" Choice: ");
33 fflush(stdout);
34}
35
36void image::ConvertImgToInt8(void* data, const size_t kMaxImageSize)
37{
Isabella Gottardi79d41542021-10-20 15:52:32 +010038 auto* tmp_req_data = static_cast<uint8_t *>(data);
39 auto* tmp_signed_req_data = static_cast<int8_t *>(data);
Éanna Ó Catháin8f958872021-09-15 09:32:30 +010040
41 for (size_t i = 0; i < kMaxImageSize; i++) {
42 tmp_signed_req_data[i] = (int8_t) (
43 (int32_t) (tmp_req_data[i]) - 128);
44 }
45}
46
Éanna Ó Catháin8f958872021-09-15 09:32:30 +010047
Kshitij Sisodiab48b5b62021-12-29 14:32:58 +000048bool image::PresentInferenceResult(
49 hal_platform &platform,
Liam Barrye9588502022-01-25 14:31:15 +000050 const std::vector<arm::app::ClassificationResult> &results)
Éanna Ó Catháin8f958872021-09-15 09:32:30 +010051{
52 constexpr uint32_t dataPsnTxtStartX1 = 150;
53 constexpr uint32_t dataPsnTxtStartY1 = 30;
54
55 constexpr uint32_t dataPsnTxtStartX2 = 10;
56 constexpr uint32_t dataPsnTxtStartY2 = 150;
57
58 constexpr uint32_t dataPsnTxtYIncr = 16; /* Row index increment. */
59
Éanna Ó Catháin8f958872021-09-15 09:32:30 +010060 platform.data_psn->set_text_color(COLOR_GREEN);
61
62 /* Display each result. */
63 uint32_t rowIdx1 = dataPsnTxtStartY1 + 2 * dataPsnTxtYIncr;
64 uint32_t rowIdx2 = dataPsnTxtStartY2;
65
Liam Barrye9588502022-01-25 14:31:15 +000066 info("Final results:\n");
67 info("Total number of inferences: 1\n");
Éanna Ó Catháin8f958872021-09-15 09:32:30 +010068
69 for (uint32_t i = 0; i < results.size(); ++i) {
70 std::string resultStr =
71 std::to_string(i + 1) + ") " +
72 std::to_string(results[i].m_labelIdx) +
73 " (" + std::to_string(results[i].m_normalisedVal) + ")";
74
75 platform.data_psn->present_data_text(
76 resultStr.c_str(), resultStr.size(),
77 dataPsnTxtStartX1, rowIdx1, 0);
78 rowIdx1 += dataPsnTxtYIncr;
79
80 resultStr = std::to_string(i + 1) + ") " + results[i].m_label;
81 platform.data_psn->present_data_text(
82 resultStr.c_str(), resultStr.size(),
83 dataPsnTxtStartX2, rowIdx2, 0);
84 rowIdx2 += dataPsnTxtYIncr;
85
Richard Burton9b8d67a2021-12-10 12:32:51 +000086 info("%" PRIu32 ") %" PRIu32 " (%f) -> %s\n", i,
87 results[i].m_labelIdx, results[i].m_normalisedVal,
88 results[i].m_label.c_str());
Éanna Ó Catháin8f958872021-09-15 09:32:30 +010089 }
90
91 return true;
92}
93
Isabella Gottardi3107aa22022-01-27 16:39:37 +000094void image::RgbToGrayscale(const uint8_t *srcPtr, uint8_t *dstPtr, const size_t dstImgSz)
95{
96 float R=0.299;
97 float G=0.587;
98 float B=0.114;
99 for (size_t i = 0; i < dstImgSz; ++i, srcPtr += 3) {
100 uint32_t int_gray = R * (*srcPtr) +
101 G * (*(srcPtr + 1)) +
102 B * (*(srcPtr + 2));
103 *dstPtr++ = int_gray <= std::numeric_limits<uint8_t>::max() ?
104 int_gray : std::numeric_limits<uint8_t>::max();
105 }
106}
107
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100108void IncrementAppCtxIfmIdx(arm::app::ApplicationContext& ctx, std::string useCase)
109{
Kshitij Sisodiaaa5e1f62021-09-24 14:42:08 +0100110#if NUMBER_OF_FILES > 0
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100111 auto curImIdx = ctx.Get<uint32_t>(useCase);
112
113 if (curImIdx + 1 >= NUMBER_OF_FILES) {
114 ctx.Set<uint32_t>(useCase, 0);
115 return;
116 }
117 ++curImIdx;
118 ctx.Set<uint32_t>(useCase, curImIdx);
Kshitij Sisodiaaa5e1f62021-09-24 14:42:08 +0100119#else /* NUMBER_OF_FILES > 0 */
120 UNUSED(ctx);
121 UNUSED(useCase);
122#endif /* NUMBER_OF_FILES > 0 */
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100123}
124
125bool SetAppCtxIfmIdx(arm::app::ApplicationContext& ctx, uint32_t idx, std::string ctxIfmName)
126{
Kshitij Sisodiaaa5e1f62021-09-24 14:42:08 +0100127#if NUMBER_OF_FILES > 0
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100128 if (idx >= NUMBER_OF_FILES) {
129 printf_err("Invalid idx %" PRIu32 " (expected less than %u)\n",
130 idx, NUMBER_OF_FILES);
131 return false;
132 }
133 ctx.Set<uint32_t>(ctxIfmName, idx);
134 return true;
Kshitij Sisodiaaa5e1f62021-09-24 14:42:08 +0100135#else /* NUMBER_OF_FILES > 0 */
136 UNUSED(ctx);
137 UNUSED(idx);
138 UNUSED(ctxIfmName);
139 return false;
140#endif /* NUMBER_OF_FILES > 0 */
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100141}
142
alexander3c798932021-03-26 21:42:19 +0000143namespace arm {
144namespace app {
145
alexander3c798932021-03-26 21:42:19 +0000146
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100147bool RunInference(arm::app::Model& model, Profiler& profiler)
148{
149 profiler.StartProfiling("Inference");
150 bool runInf = model.RunInference();
151 profiler.StopProfiling();
152
153 return runInf;
154}
155
156int ReadUserInputAsInt(hal_platform& platform)
157{
158 char chInput[128];
159 memset(chInput, 0, sizeof(chInput));
160
161 platform.data_acq->get_input(chInput, sizeof(chInput));
162 return atoi(chInput);
163}
164
165void DumpTensorData(const uint8_t* tensorData,
166 size_t size,
167 size_t lineBreakForNumElements)
168{
169 char strhex[8];
170 std::string strdump;
171
172 for (size_t i = 0; i < size; ++i) {
173 if (0 == i % lineBreakForNumElements) {
174 printf("%s\n\t", strdump.c_str());
175 strdump.clear();
176 }
177 snprintf(strhex, sizeof(strhex) - 1,
178 "0x%02x, ", tensorData[i]);
179 strdump += std::string(strhex);
alexander3c798932021-03-26 21:42:19 +0000180 }
181
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100182 if (!strdump.empty()) {
183 printf("%s\n", strdump.c_str());
184 }
185}
alexander3c798932021-03-26 21:42:19 +0000186
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100187void DumpTensor(const TfLiteTensor* tensor, const size_t lineBreakForNumElements)
188{
189 if (!tensor) {
190 printf_err("invalid tensor\n");
191 return;
alexander3c798932021-03-26 21:42:19 +0000192 }
193
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100194 const uint32_t tensorSz = tensor->bytes;
195 const uint8_t* tensorData = tflite::GetTensorData<uint8_t>(tensor);
alexander3c798932021-03-26 21:42:19 +0000196
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100197 DumpTensorData(tensorData, tensorSz, lineBreakForNumElements);
198}
alexander80eecfb2021-07-06 19:47:59 +0100199
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100200bool ListFilesHandler(ApplicationContext& ctx)
201{
202 auto& model = ctx.Get<Model&>("model");
203 auto& platform = ctx.Get<hal_platform&>("platform");
alexander80eecfb2021-07-06 19:47:59 +0100204
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100205 constexpr uint32_t dataPsnTxtStartX = 20;
206 constexpr uint32_t dataPsnTxtStartY = 40;
alexander3c798932021-03-26 21:42:19 +0000207
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100208 if (!model.IsInited()) {
209 printf_err("Model is not initialised! Terminating processing.\n");
210 return false;
alexander3c798932021-03-26 21:42:19 +0000211 }
212
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100213 /* Clear the LCD */
214 platform.data_psn->clear(COLOR_BLACK);
alexander3c798932021-03-26 21:42:19 +0000215
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100216 /* Show the total number of embedded files. */
217 std::string strNumFiles = std::string{"Total Number of Files: "} +
218 std::to_string(NUMBER_OF_FILES);
219 platform.data_psn->present_data_text(strNumFiles.c_str(),
220 strNumFiles.size(),
221 dataPsnTxtStartX,
222 dataPsnTxtStartY,
223 false);
alexander3c798932021-03-26 21:42:19 +0000224
225#if NUMBER_OF_FILES > 0
226 constexpr uint32_t dataPsnTxtYIncr = 16;
227 info("List of Files:\n");
228 uint32_t yVal = dataPsnTxtStartY + dataPsnTxtYIncr;
229 for (uint32_t i = 0; i < NUMBER_OF_FILES; ++i, yVal += dataPsnTxtYIncr) {
230
231 std::string currentFilename{get_filename(i)};
232 platform.data_psn->present_data_text(currentFilename.c_str(),
233 currentFilename.size(),
alexander80eecfb2021-07-06 19:47:59 +0100234 dataPsnTxtStartX, yVal, false);
alexander3c798932021-03-26 21:42:19 +0000235
Kshitij Sisodiaf9c19ea2021-05-07 16:08:14 +0100236 info("\t%" PRIu32 " => %s\n", i, currentFilename.c_str());
alexander3c798932021-03-26 21:42:19 +0000237 }
238#endif /* NUMBER_OF_FILES > 0 */
239
240 return true;
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100241}
alexander3c798932021-03-26 21:42:19 +0000242
243} /* namespace app */
Isabella Gottardi3107aa22022-01-27 16:39:37 +0000244} /* namespace arm */