CTfLiteClass.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. #include "CTfLiteClass.h"
  2. #include "ClassLogFile.h"
  3. #include "Helper.h"
  4. #include <sys/stat.h>
  5. // #define DEBUG_DETAIL_ON
  6. //#define GET_MEMORY(X) malloc(X)
  7. #define GET_MEMORY(X) heap_caps_malloc(X, MALLOC_CAP_SPIRAM)
  8. float CTfLiteClass::GetOutputValue(int nr)
  9. {
  10. TfLiteTensor* output2 = interpreter->output(0);
  11. int numeroutput = output2->dims->data[1];
  12. if ((nr+1) > numeroutput)
  13. return -1000;
  14. return output2->data.f[nr];
  15. }
  16. int CTfLiteClass::GetClassFromImageBasis(CImageBasis *rs)
  17. {
  18. if (!LoadInputImageBasis(rs))
  19. return -1000;
  20. Invoke();
  21. return GetOutClassification();
  22. }
  23. int CTfLiteClass::GetOutClassification()
  24. {
  25. TfLiteTensor* output2 = interpreter->output(0);
  26. float zw_max = 0;
  27. float zw;
  28. int zw_class = -1;
  29. if (output2 == NULL)
  30. return -1;
  31. int numeroutput = output2->dims->data[1];
  32. for (int i = 0; i < numeroutput; ++i)
  33. {
  34. zw = output2->data.f[i];
  35. if (zw > zw_max)
  36. {
  37. zw_max = zw;
  38. zw_class = i;
  39. }
  40. }
  41. return zw_class;
  42. }
  43. void CTfLiteClass::GetInputDimension(bool silent = false)
  44. {
  45. TfLiteTensor* input2 = interpreter->input(0);
  46. int numdim = input2->dims->size;
  47. if (!silent) printf("NumDimension: %d\n", numdim);
  48. int sizeofdim;
  49. for (int j = 0; j < numdim; ++j)
  50. {
  51. sizeofdim = input2->dims->data[j];
  52. if (!silent) printf("SizeOfDimension %d: %d\n", j, sizeofdim);
  53. if (j == 1) im_height = sizeofdim;
  54. if (j == 2) im_width = sizeofdim;
  55. if (j == 3) im_channel = sizeofdim;
  56. }
  57. }
  58. void CTfLiteClass::GetOutPut()
  59. {
  60. TfLiteTensor* output2 = interpreter->output(0);
  61. int numdim = output2->dims->size;
  62. printf("NumDimension: %d\n", numdim);
  63. int sizeofdim;
  64. for (int j = 0; j < numdim; ++j)
  65. {
  66. sizeofdim = output2->dims->data[j];
  67. printf("SizeOfDimension %d: %d\n", j, sizeofdim);
  68. }
  69. float fo;
  70. // Process the inference results.
  71. int numeroutput = output2->dims->data[1];
  72. for (int i = 0; i < numeroutput; ++i)
  73. {
  74. fo = output2->data.f[i];
  75. printf("Result %d: %f\n", i, fo);
  76. }
  77. }
  78. void CTfLiteClass::Invoke()
  79. {
  80. interpreter->Invoke();
  81. }
  82. bool CTfLiteClass::LoadInputImageBasis(CImageBasis *rs)
  83. {
  84. std::string zw = "ClassFlowAnalog::doNeuralNetwork nach LoadInputResizeImage: ";
  85. unsigned int w = rs->width;
  86. unsigned int h = rs->height;
  87. unsigned char red, green, blue;
  88. // printf("Image: %s size: %d x %d\n", _fn.c_str(), w, h);
  89. input_i = 0;
  90. float* input_data_ptr = (interpreter->input(0))->data.f;
  91. for (int y = 0; y < h; ++y)
  92. for (int x = 0; x < w; ++x)
  93. {
  94. red = rs->GetPixelColor(x, y, 0);
  95. green = rs->GetPixelColor(x, y, 1);
  96. blue = rs->GetPixelColor(x, y, 2);
  97. *(input_data_ptr) = (float) red;
  98. input_data_ptr++;
  99. *(input_data_ptr) = (float) green;
  100. input_data_ptr++;
  101. *(input_data_ptr) = (float) blue;
  102. input_data_ptr++;
  103. }
  104. #ifdef DEBUG_DETAIL_ON
  105. LogFile.WriteToFile("Nach dem Laden in input");
  106. #endif
  107. return true;
  108. }
  109. void CTfLiteClass::MakeAllocate()
  110. {
  111. static tflite::AllOpsResolver resolver;
  112. // printf(LogFile.getESPHeapInfo().c_str()); printf("\n");
  113. interpreter = new tflite::MicroInterpreter(model, resolver, tensor_arena, kTensorArenaSize, error_reporter);
  114. // printf(LogFile.getESPHeapInfo().c_str()); printf("\n");
  115. TfLiteStatus allocate_status = interpreter->AllocateTensors();
  116. if (allocate_status != kTfLiteOk) {
  117. TF_LITE_REPORT_ERROR(error_reporter, "AllocateTensors() failed");
  118. GetInputDimension();
  119. return;
  120. }
  121. // printf("Allocate Done.\n");
  122. }
  123. void CTfLiteClass::GetInputTensorSize(){
  124. float *zw = input;
  125. int test = sizeof(zw);
  126. #ifdef DEBUG_DETAIL_ON
  127. printf("Input Tensor Dimension: %d\n", test);
  128. #endif
  129. }
  130. long CTfLiteClass::GetFileSize(std::string filename)
  131. {
  132. struct stat stat_buf;
  133. long rc = stat(filename.c_str(), &stat_buf);
  134. return rc == 0 ? stat_buf.st_size : -1;
  135. }
  136. unsigned char* CTfLiteClass::ReadFileToCharArray(std::string _fn)
  137. {
  138. long size;
  139. size = GetFileSize(_fn);
  140. if (size == -1)
  141. {
  142. printf("\nFile existiert nicht.\n");
  143. return NULL;
  144. }
  145. unsigned char *result = (unsigned char*) malloc(size);
  146. int anz = 1;
  147. TickType_t xDelay;
  148. while (!result && (anz < 6)) // maximal 5x versuchen (= 5s)
  149. {
  150. #ifdef DEBUG_DETAIL_ON
  151. printf("Speicher ist voll - Versuche es erneut: %d.\n", anz);
  152. #endif
  153. xDelay = 1000 / portTICK_PERIOD_MS;
  154. result = (unsigned char*) malloc(size);
  155. anz++;
  156. }
  157. if(result != NULL) {
  158. FILE* f = OpenFileAndWait(_fn.c_str(), "rb"); // vorher nur "r"
  159. fread(result, 1, size, f);
  160. fclose(f);
  161. }else {
  162. printf("\nKein freier Speicher vorhanden.\n");
  163. }
  164. return result;
  165. }
  166. void CTfLiteClass::LoadModel(std::string _fn){
  167. #ifdef SUPRESS_TFLITE_ERRORS
  168. error_reporter = new tflite::OwnMicroErrorReporter;
  169. #else
  170. error_reporter = new tflite::MicroErrorReporter;
  171. #endif
  172. unsigned char *rd;
  173. rd = ReadFileToCharArray(_fn.c_str());
  174. model = tflite::GetModel(rd);
  175. free(rd);
  176. TFLITE_MINIMAL_CHECK(model != nullptr);
  177. MakeAllocate();
  178. }
  179. CTfLiteClass::CTfLiteClass()
  180. {
  181. model = nullptr;
  182. interpreter = nullptr;
  183. input = nullptr;
  184. output = nullptr;
  185. kTensorArenaSize = 200 * 1024; /// laut testfile: 108000 - bisher 600
  186. tensor_arena = (uint8_t*) GET_MEMORY(kTensorArenaSize);
  187. // tensor_arena = new uint8_t[kTensorArenaSize];
  188. }
  189. CTfLiteClass::~CTfLiteClass()
  190. {
  191. delete tensor_arena;
  192. delete interpreter;
  193. delete error_reporter;
  194. }
  195. namespace tflite {
  196. int OwnMicroErrorReporter::Report(const char* format, va_list args) {
  197. return 0;
  198. }
  199. }