ClassFlowCNNGeneral.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661
  1. #include "ClassFlowCNNGeneral.h"
  2. #include <math.h>
  3. #include <iomanip>
  4. #include <sys/types.h>
  5. #include <sstream> // std::stringstream
  6. #include "CTfLiteClass.h"
  7. #include "ClassLogFile.h"
  8. static const char* TAG = "flow_analog";
  9. bool debugdetailgeneral = false;
  10. ClassFlowCNNGeneral::ClassFlowCNNGeneral(ClassFlowAlignment *_flowalign, t_CNNType _cnntype) : ClassFlowImage(NULL, TAG)
  11. {
  12. string cnnmodelfile = "";
  13. modelxsize = 1;
  14. modelysize = 1;
  15. ListFlowControll = NULL;
  16. previousElement = NULL;
  17. SaveAllFiles = false;
  18. disabled = false;
  19. isLogImageSelect = false;
  20. CNNType = AutoDetect;
  21. CNNType = _cnntype;
  22. flowpostalignment = _flowalign;
  23. }
  24. string ClassFlowCNNGeneral::getReadout(int _analog = 0, bool _extendedResolution = false)
  25. {
  26. string result = "";
  27. if (GENERAL[_analog]->ROI.size() == 0)
  28. return result;
  29. if (CNNType == Analogue)
  30. {
  31. float zahl = GENERAL[_analog]->ROI[GENERAL[_analog]->ROI.size() - 1]->result_float;
  32. int ergebnis_nachkomma = ((int) floor(zahl * 10) + 10) % 10;
  33. int prev = -1;
  34. prev = ZeigerEval(GENERAL[_analog]->ROI[GENERAL[_analog]->ROI.size() - 1]->result_float, prev);
  35. result = std::to_string(prev);
  36. if (_extendedResolution && (CNNType != Digital))
  37. result = result + std::to_string(ergebnis_nachkomma);
  38. for (int i = GENERAL[_analog]->ROI.size() - 2; i >= 0; --i)
  39. {
  40. prev = ZeigerEval(GENERAL[_analog]->ROI[i]->result_float, prev);
  41. result = std::to_string(prev) + result;
  42. }
  43. return result;
  44. }
  45. if (CNNType == Digital)
  46. {
  47. for (int i = 0; i < GENERAL[_analog]->ROI.size(); ++i)
  48. {
  49. if (GENERAL[_analog]->ROI[i]->result_klasse >= 10)
  50. result = result + "N";
  51. else
  52. result = result + std::to_string(GENERAL[_analog]->ROI[i]->result_klasse);
  53. }
  54. return result;
  55. }
  56. if (CNNType == DigitalHyprid)
  57. {
  58. int zif_akt = -1;
  59. float zahl = GENERAL[_analog]->ROI[GENERAL[_analog]->ROI.size() - 1]->result_float;
  60. if (zahl >= 0) // NaN?
  61. {
  62. if (_extendedResolution)
  63. {
  64. int ergebnis_nachkomma = ((int) floor(zahl * 10)) % 10;
  65. int ergebnis_vorkomma = ((int) floor(zahl)) % 10;
  66. result = std::to_string(ergebnis_vorkomma) + std::to_string(ergebnis_nachkomma);
  67. zif_akt = ergebnis_vorkomma;
  68. }
  69. else
  70. {
  71. zif_akt = ZeigerEvalHybrid(GENERAL[_analog]->ROI[GENERAL[_analog]->ROI.size() - 1]->result_float, -1, -1);
  72. result = std::to_string(zif_akt);
  73. }
  74. }
  75. else
  76. {
  77. result = "N";
  78. if (_extendedResolution && (CNNType != Digital))
  79. result = "NN";
  80. }
  81. for (int i = GENERAL[_analog]->ROI.size() - 2; i >= 0; --i)
  82. {
  83. if (GENERAL[_analog]->ROI[i]->result_float >= 0)
  84. {
  85. zif_akt = ZeigerEvalHybrid(GENERAL[_analog]->ROI[i]->result_float, GENERAL[_analog]->ROI[i+1]->result_float, zif_akt);
  86. result = std::to_string(zif_akt) + result;
  87. }
  88. else
  89. {
  90. zif_akt = -1;
  91. result = "N" + result;
  92. }
  93. }
  94. return result;
  95. }
  96. return result;
  97. }
  98. int ClassFlowCNNGeneral::ZeigerEvalHybrid(float zahl, float zahl_vorgaenger, int eval_vorgaenger)
  99. {
  100. int ergebnis_nachkomma = ((int) floor(zahl * 10)) % 10;
  101. if (zahl_vorgaenger < 0) // keine Vorzahl vorhanden !!! --> Runde die Zahl
  102. {
  103. if ((ergebnis_nachkomma <= 2) || (ergebnis_nachkomma >= 8)) // Band um die Ziffer --> Runden, da Ziffer im Rahmen Ungenauigkeit erreicht
  104. return ((int) round(zahl) + 10) % 10;
  105. else
  106. return ((int) trunc(zahl) + 10) % 10;
  107. }
  108. if (zahl_vorgaenger > 9.2) // Ziffernwechsel beginnt
  109. {
  110. if (eval_vorgaenger == 0) // Wechsel hat schon stattgefunden
  111. {
  112. return ((int) round(zahl) + 10) % 10; // Annahme, dass die neue Zahl schon in der Nähe des Ziels ist
  113. }
  114. else
  115. {
  116. if (zahl_vorgaenger <= 9.5) // Wechsel startet gerade, aber beginnt erst
  117. {
  118. if ((ergebnis_nachkomma <= 2) || (ergebnis_nachkomma >= 8)) // Band um die Ziffer --> Runden, da Ziffer im Rahmen Ungenauigkeit erreicht
  119. return ((int) round(zahl) + 10) % 10;
  120. else
  121. return ((int) trunc(zahl) + 10) % 10;
  122. }
  123. else
  124. {
  125. return ((int) trunc(zahl) + 10) % 10; // Wechsel schon weiter fortgeschritten, d.h. über 2 als Nachkomma
  126. }
  127. }
  128. }
  129. if ((ergebnis_nachkomma <= 2) || (ergebnis_nachkomma >= 8)) // Band um die Ziffer --> Runden, da Ziffer im Rahmen Ungenauigkeit erreicht
  130. return ((int) round(zahl) + 10) % 10;
  131. return ((int) trunc(zahl) + 10) % 10;
  132. }
  133. int ClassFlowCNNGeneral::ZeigerEval(float zahl, int ziffer_vorgaenger)
  134. {
  135. int ergebnis_nachkomma = ((int) floor(zahl * 10) + 10) % 10;
  136. int ergebnis_vorkomma = ((int) floor(zahl) + 10) % 10;
  137. int ergebnis, ergebnis_rating;
  138. if (ziffer_vorgaenger == -1)
  139. return ergebnis_vorkomma % 10;
  140. ergebnis_rating = ergebnis_nachkomma - ziffer_vorgaenger;
  141. if (ergebnis_nachkomma >= 5)
  142. ergebnis_rating-=5;
  143. else
  144. ergebnis_rating+=5;
  145. ergebnis = (int) round(zahl);
  146. if (ergebnis_rating < 0)
  147. ergebnis-=1;
  148. if (ergebnis == -1)
  149. ergebnis+=10;
  150. ergebnis = (ergebnis + 10) % 10;
  151. return ergebnis;
  152. }
  153. bool ClassFlowCNNGeneral::ReadParameter(FILE* pfile, string& aktparamgraph)
  154. {
  155. std::vector<string> zerlegt;
  156. aktparamgraph = trim(aktparamgraph);
  157. if (aktparamgraph.size() == 0)
  158. if (!this->GetNextParagraph(pfile, aktparamgraph))
  159. return false;
  160. if ((toUpper(aktparamgraph) != "[ANALOG]") && (toUpper(aktparamgraph) != ";[ANALOG]")
  161. && (toUpper(aktparamgraph) != "[DIGIT]") && (toUpper(aktparamgraph) != ";[DIGIT]")
  162. && (toUpper(aktparamgraph) != "[DIGITS]") && (toUpper(aktparamgraph) != ";[DIGITS]")
  163. ) // Paragraph passt nicht
  164. return false;
  165. if (aktparamgraph[0] == ';')
  166. {
  167. disabled = true;
  168. while (getNextLine(pfile, &aktparamgraph) && !isNewParagraph(aktparamgraph));
  169. printf("[Analog/Digit] is disabled !!!\n");
  170. return true;
  171. }
  172. while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph))
  173. {
  174. zerlegt = this->ZerlegeZeile(aktparamgraph);
  175. if ((zerlegt[0] == "LogImageLocation") && (zerlegt.size() > 1))
  176. {
  177. this->LogImageLocation = "/sdcard" + zerlegt[1];
  178. this->isLogImage = true;
  179. }
  180. if ((zerlegt[0] == "LogImageSelect") && (zerlegt.size() > 1))
  181. {
  182. LogImageSelect = zerlegt[1];
  183. isLogImageSelect = true;
  184. }
  185. if ((toUpper(zerlegt[0]) == "LOGFILERETENTIONINDAYS") && (zerlegt.size() > 1))
  186. {
  187. this->logfileRetentionInDays = std::stoi(zerlegt[1]);
  188. }
  189. if ((toUpper(zerlegt[0]) == "MODELTYPE") && (zerlegt.size() > 1))
  190. {
  191. if (toUpper(zerlegt[1]) == "DIGITHYPRID")
  192. CNNType = DigitalHyprid;
  193. }
  194. if ((zerlegt[0] == "Model") && (zerlegt.size() > 1))
  195. {
  196. this->cnnmodelfile = zerlegt[1];
  197. }
  198. if ((zerlegt[0] == "ModelInputSize") && (zerlegt.size() > 2))
  199. {
  200. this->modelxsize = std::stoi(zerlegt[1]);
  201. this->modelysize = std::stoi(zerlegt[2]);
  202. }
  203. if (zerlegt.size() >= 5)
  204. {
  205. general* _analog = GetGENERAL(zerlegt[0], true);
  206. roi* neuroi = _analog->ROI[_analog->ROI.size()-1];
  207. neuroi->posx = std::stoi(zerlegt[1]);
  208. neuroi->posy = std::stoi(zerlegt[2]);
  209. neuroi->deltax = std::stoi(zerlegt[3]);
  210. neuroi->deltay = std::stoi(zerlegt[4]);
  211. neuroi->result_float = -1;
  212. neuroi->image = NULL;
  213. neuroi->image_org = NULL;
  214. }
  215. if ((toUpper(zerlegt[0]) == "SAVEALLFILES") && (zerlegt.size() > 1))
  216. {
  217. if (toUpper(zerlegt[1]) == "TRUE")
  218. SaveAllFiles = true;
  219. }
  220. }
  221. for (int _ana = 0; _ana < GENERAL.size(); ++_ana)
  222. for (int i = 0; i < GENERAL[_ana]->ROI.size(); ++i)
  223. {
  224. GENERAL[_ana]->ROI[i]->image = new CImageBasis(modelxsize, modelysize, 3);
  225. GENERAL[_ana]->ROI[i]->image_org = new CImageBasis(GENERAL[_ana]->ROI[i]->deltax, GENERAL[_ana]->ROI[i]->deltay, 3);
  226. }
  227. return true;
  228. }
  229. general* ClassFlowCNNGeneral::FindGENERAL(string _name_number)
  230. {
  231. for (int i = 0; i < GENERAL.size(); ++i)
  232. if (GENERAL[i]->name == _name_number)
  233. return GENERAL[i];
  234. return NULL;
  235. }
  236. general* ClassFlowCNNGeneral::GetGENERAL(string _name, bool _create = true)
  237. {
  238. string _analog, _roi;
  239. int _pospunkt = _name.find_first_of(".");
  240. if (_pospunkt > -1)
  241. {
  242. _analog = _name.substr(0, _pospunkt);
  243. _roi = _name.substr(_pospunkt+1, _name.length() - _pospunkt - 1);
  244. }
  245. else
  246. {
  247. _analog = "default";
  248. _roi = _name;
  249. }
  250. general *_ret = NULL;
  251. for (int i = 0; i < GENERAL.size(); ++i)
  252. if (GENERAL[i]->name == _analog)
  253. _ret = GENERAL[i];
  254. if (!_create) // nicht gefunden und soll auch nicht erzeugt werden
  255. return _ret;
  256. if (_ret == NULL)
  257. {
  258. _ret = new general;
  259. _ret->name = _analog;
  260. GENERAL.push_back(_ret);
  261. }
  262. roi* neuroi = new roi;
  263. neuroi->name = _roi;
  264. _ret->ROI.push_back(neuroi);
  265. printf("GetGENERAL - GENERAL %s - roi %s\n", _analog.c_str(), _roi.c_str());
  266. return _ret;
  267. }
  268. string ClassFlowCNNGeneral::getHTMLSingleStep(string host)
  269. {
  270. string result, zw;
  271. std::vector<HTMLInfo*> htmlinfo;
  272. result = "<p>Found ROIs: </p> <p><img src=\"" + host + "/img_tmp/alg_roi.jpg\"></p>\n";
  273. result = result + "Analog Pointers: <p> ";
  274. htmlinfo = GetHTMLInfo();
  275. for (int i = 0; i < htmlinfo.size(); ++i)
  276. {
  277. std::stringstream stream;
  278. stream << std::fixed << std::setprecision(1) << htmlinfo[i]->val;
  279. zw = stream.str();
  280. result = result + "<img src=\"" + host + "/img_tmp/" + htmlinfo[i]->filename + "\"> " + zw;
  281. delete htmlinfo[i];
  282. }
  283. htmlinfo.clear();
  284. return result;
  285. }
  286. bool ClassFlowCNNGeneral::doFlow(string time)
  287. {
  288. if (disabled)
  289. return true;
  290. if (!doAlignAndCut(time)){
  291. return false;
  292. };
  293. if (debugdetailgeneral) LogFile.WriteToFile("ClassFlowCNNGeneral::doFlow nach Alignment");
  294. doNeuralNetwork(time);
  295. RemoveOldLogs();
  296. return true;
  297. }
  298. bool ClassFlowCNNGeneral::doAlignAndCut(string time)
  299. {
  300. if (disabled)
  301. return true;
  302. CAlignAndCutImage *caic = flowpostalignment->GetAlignAndCutImage();
  303. for (int _ana = 0; _ana < GENERAL.size(); ++_ana)
  304. for (int i = 0; i < GENERAL[_ana]->ROI.size(); ++i)
  305. {
  306. printf("General %d - Align&Cut\n", i);
  307. caic->CutAndSave(GENERAL[_ana]->ROI[i]->posx, GENERAL[_ana]->ROI[i]->posy, GENERAL[_ana]->ROI[i]->deltax, GENERAL[_ana]->ROI[i]->deltay, GENERAL[_ana]->ROI[i]->image_org);
  308. if (SaveAllFiles)
  309. {
  310. if (GENERAL[_ana]->name == "default")
  311. GENERAL[_ana]->ROI[i]->image_org->SaveToFile(FormatFileName("/sdcard/img_tmp/" + GENERAL[_ana]->ROI[i]->name + ".jpg"));
  312. else
  313. GENERAL[_ana]->ROI[i]->image_org->SaveToFile(FormatFileName("/sdcard/img_tmp/" + GENERAL[_ana]->name + "_" + GENERAL[_ana]->ROI[i]->name + ".jpg"));
  314. }
  315. GENERAL[_ana]->ROI[i]->image_org->Resize(modelxsize, modelysize, GENERAL[_ana]->ROI[i]->image);
  316. if (SaveAllFiles)
  317. {
  318. if (GENERAL[_ana]->name == "default")
  319. GENERAL[_ana]->ROI[i]->image->SaveToFile(FormatFileName("/sdcard/img_tmp/" + GENERAL[_ana]->ROI[i]->name + ".bmp"));
  320. else
  321. GENERAL[_ana]->ROI[i]->image->SaveToFile(FormatFileName("/sdcard/img_tmp/" + GENERAL[_ana]->name + "_" + GENERAL[_ana]->ROI[i]->name + ".bmp"));
  322. }
  323. }
  324. return true;
  325. }
  326. void ClassFlowCNNGeneral::DrawROI(CImageBasis *_zw)
  327. {
  328. if (CNNType == Analogue)
  329. {
  330. int r = 0;
  331. int g = 255;
  332. int b = 0;
  333. for (int _ana = 0; _ana < GENERAL.size(); ++_ana)
  334. for (int i = 0; i < GENERAL[_ana]->ROI.size(); ++i)
  335. {
  336. _zw->drawRect(GENERAL[_ana]->ROI[i]->posx, GENERAL[_ana]->ROI[i]->posy, GENERAL[_ana]->ROI[i]->deltax, GENERAL[_ana]->ROI[i]->deltay, r, g, b, 1);
  337. // _zw->drawCircle((int) (GENERAL[_ana]->ROI[i]->posx + GENERAL[_ana]->ROI[i]->deltax/2), (int) (GENERAL[_ana]->ROI[i]->posy + GENERAL[_ana]->ROI[i]->deltay/2), (int) (GENERAL[_ana]->ROI[i]->deltax/2), r, g, b, 2);
  338. _zw->drawEllipse( (int) (GENERAL[_ana]->ROI[i]->posx + GENERAL[_ana]->ROI[i]->deltax/2), (int) (GENERAL[_ana]->ROI[i]->posy + GENERAL[_ana]->ROI[i]->deltay/2), (int) (GENERAL[_ana]->ROI[i]->deltax/2), (int) (GENERAL[_ana]->ROI[i]->deltay/2), r, g, b, 2);
  339. _zw->drawLine((int) (GENERAL[_ana]->ROI[i]->posx + GENERAL[_ana]->ROI[i]->deltax/2), (int) GENERAL[_ana]->ROI[i]->posy, (int) (GENERAL[_ana]->ROI[i]->posx + GENERAL[_ana]->ROI[i]->deltax/2), (int) (GENERAL[_ana]->ROI[i]->posy + GENERAL[_ana]->ROI[i]->deltay), r, g, b, 2);
  340. _zw->drawLine((int) GENERAL[_ana]->ROI[i]->posx, (int) (GENERAL[_ana]->ROI[i]->posy + GENERAL[_ana]->ROI[i]->deltay/2), (int) GENERAL[_ana]->ROI[i]->posx + GENERAL[_ana]->ROI[i]->deltax, (int) (GENERAL[_ana]->ROI[i]->posy + GENERAL[_ana]->ROI[i]->deltay/2), r, g, b, 2);
  341. }
  342. }
  343. else
  344. {
  345. for (int _dig = 0; _dig < GENERAL.size(); ++_dig)
  346. for (int i = 0; i < GENERAL[_dig]->ROI.size(); ++i)
  347. _zw->drawRect(GENERAL[_dig]->ROI[i]->posx, GENERAL[_dig]->ROI[i]->posy, GENERAL[_dig]->ROI[i]->deltax, GENERAL[_dig]->ROI[i]->deltay, 0, 0, (255 - _dig*100), 2);
  348. }
  349. }
  350. bool ClassFlowCNNGeneral::doNeuralNetwork(string time)
  351. {
  352. if (disabled)
  353. return true;
  354. string logPath = CreateLogFolder(time);
  355. CTfLiteClass *tflite = new CTfLiteClass;
  356. string zwcnn = "/sdcard" + cnnmodelfile;
  357. zwcnn = FormatFileName(zwcnn);
  358. printf(zwcnn.c_str());printf("\n");
  359. if (!tflite->LoadModel(zwcnn)) {
  360. printf("Can't read model file /sdcard%s\n", cnnmodelfile.c_str());
  361. LogFile.WriteToFile("Cannot load model");
  362. delete tflite;
  363. return false;
  364. }
  365. tflite->MakeAllocate();
  366. if (CNNType == AutoDetect)
  367. {
  368. int _anzoutputdimensions = tflite->GetAnzOutPut();
  369. switch (_anzoutputdimensions)
  370. {
  371. case 2:
  372. CNNType = Analogue;
  373. printf("TFlite-Type set to Analogue\n");
  374. break;
  375. case 11:
  376. CNNType = Digital;
  377. printf("TFlite-Type set to Digital\n");
  378. break;
  379. case 20:
  380. CNNType = DigitalHyprid10;
  381. printf("TFlite-Type set to DigitalHyprid10\n");
  382. break;
  383. case 22:
  384. CNNType = DigitalHyprid;
  385. printf("TFlite-Type set to DigitalHyprid\n");
  386. break;
  387. default:
  388. printf("ERROR ERROR ERROR - tflite passt nicht zur Firmware - ERROR ERROR ERROR\n");
  389. }
  390. }
  391. for (int _ana = 0; _ana < GENERAL.size(); ++_ana)
  392. {
  393. for (int i = 0; i < GENERAL[_ana]->ROI.size(); ++i)
  394. {
  395. printf("General %d - TfLite\n", i);
  396. switch (CNNType) {
  397. case Analogue:
  398. {
  399. float f1, f2;
  400. f1 = 0; f2 = 0;
  401. tflite->LoadInputImageBasis(GENERAL[_ana]->ROI[i]->image);
  402. tflite->Invoke();
  403. if (debugdetailgeneral) LogFile.WriteToFile("Nach Invoke");
  404. f1 = tflite->GetOutputValue(0);
  405. f2 = tflite->GetOutputValue(1);
  406. float result = fmod(atan2(f1, f2) / (M_PI * 2) + 2, 1);
  407. GENERAL[_ana]->ROI[i]->result_float = result * 10;
  408. printf("Result General(Analog)%i: %f\n", i, GENERAL[_ana]->ROI[i]->result_float);
  409. if (isLogImage)
  410. LogImage(logPath, GENERAL[_ana]->ROI[i]->name, &GENERAL[_ana]->ROI[i]->result_float, NULL, time, GENERAL[_ana]->ROI[i]->image_org);
  411. } break;
  412. case Digital:
  413. {
  414. GENERAL[_ana]->ROI[i]->result_klasse = 0;
  415. GENERAL[_ana]->ROI[i]->result_klasse = tflite->GetClassFromImageBasis(GENERAL[_ana]->ROI[i]->image);
  416. printf("Result General(Digit)%i: %d\n", i, GENERAL[_ana]->ROI[i]->result_klasse);
  417. if (isLogImage)
  418. {
  419. if (isLogImageSelect)
  420. {
  421. if (LogImageSelect.find(GENERAL[_ana]->ROI[i]->name) != std::string::npos)
  422. LogImage(logPath, GENERAL[_ana]->ROI[i]->name, NULL, &GENERAL[_ana]->ROI[i]->result_klasse, time, GENERAL[_ana]->ROI[i]->image_org);
  423. }
  424. else
  425. {
  426. LogImage(logPath, GENERAL[_ana]->ROI[i]->name, NULL, &GENERAL[_ana]->ROI[i]->result_klasse, time, GENERAL[_ana]->ROI[i]->image_org);
  427. }
  428. }
  429. } break;
  430. case DigitalHyprid:
  431. {
  432. int _num, _nachkomma;
  433. tflite->LoadInputImageBasis(GENERAL[_ana]->ROI[i]->image);
  434. tflite->Invoke();
  435. if (debugdetailgeneral) LogFile.WriteToFile("Nach Invoke");
  436. _num = tflite->GetOutClassification(0, 10);
  437. _nachkomma = tflite->GetOutClassification(11, 21);
  438. string _zwres = "Nach Invoke - Nummer: " + to_string(_num) + " Nachkomma: " + to_string(_nachkomma);
  439. if (debugdetailgeneral) LogFile.WriteToFile(_zwres);
  440. if ((_num == 10) || (_nachkomma == 10)) // NaN detektiert
  441. GENERAL[_ana]->ROI[i]->result_float = -1;
  442. else
  443. GENERAL[_ana]->ROI[i]->result_float = fmod((double) _num + (((double)_nachkomma)-5)/10 + (double) 10, 10);
  444. printf("Result General(DigitalHyprid)%i: %f\n", i, GENERAL[_ana]->ROI[i]->result_float);
  445. _zwres = "Result General(DigitalHyprid)" + to_string(i) + ": " + to_string(GENERAL[_ana]->ROI[i]->result_float);
  446. if (debugdetailgeneral) LogFile.WriteToFile(_zwres);
  447. if (isLogImage)
  448. LogImage(logPath, GENERAL[_ana]->ROI[i]->name, &GENERAL[_ana]->ROI[i]->result_float, NULL, time, GENERAL[_ana]->ROI[i]->image_org);
  449. } break;
  450. case DigitalHyprid10:
  451. {
  452. int _num, _nachkomma;
  453. tflite->LoadInputImageBasis(GENERAL[_ana]->ROI[i]->image);
  454. tflite->Invoke();
  455. if (debugdetailgeneral) LogFile.WriteToFile("Nach Invoke");
  456. _num = tflite->GetOutClassification(0, 9);
  457. _nachkomma = tflite->GetOutClassification(10, 19);
  458. string _zwres = "Nach Invoke - Nummer: " + to_string(_num) + " Nachkomma: " + to_string(_nachkomma);
  459. if (debugdetailgeneral) LogFile.WriteToFile(_zwres);
  460. GENERAL[_ana]->ROI[i]->result_float = fmod((double) _num + (((double)_nachkomma)-5)/10 + (double) 10, 10);
  461. printf("Result General(DigitalHyprid)%i: %f\n", i, GENERAL[_ana]->ROI[i]->result_float);
  462. _zwres = "Result General(DigitalHyprid)" + to_string(i) + ": " + to_string(GENERAL[_ana]->ROI[i]->result_float);
  463. if (debugdetailgeneral) LogFile.WriteToFile(_zwres);
  464. if (isLogImage)
  465. LogImage(logPath, GENERAL[_ana]->ROI[i]->name, &GENERAL[_ana]->ROI[i]->result_float, NULL, time, GENERAL[_ana]->ROI[i]->image_org);
  466. } break;
  467. default:
  468. break;
  469. }
  470. }
  471. }
  472. delete tflite;
  473. return true;
  474. }
  475. bool ClassFlowCNNGeneral::isExtendedResolution(int _number)
  476. {
  477. if (!(CNNType == Digital))
  478. return true;
  479. return false;
  480. }
  481. std::vector<HTMLInfo*> ClassFlowCNNGeneral::GetHTMLInfo()
  482. {
  483. std::vector<HTMLInfo*> result;
  484. for (int _ana = 0; _ana < GENERAL.size(); ++_ana)
  485. for (int i = 0; i < GENERAL[_ana]->ROI.size(); ++i)
  486. {
  487. if (GENERAL[_ana]->name == "default")
  488. GENERAL[_ana]->ROI[i]->image->SaveToFile(FormatFileName("/sdcard/img_tmp/" + GENERAL[_ana]->ROI[i]->name + ".bmp"));
  489. else
  490. GENERAL[_ana]->ROI[i]->image->SaveToFile(FormatFileName("/sdcard/img_tmp/" + GENERAL[_ana]->name + "_" + GENERAL[_ana]->ROI[i]->name + ".bmp"));
  491. HTMLInfo *zw = new HTMLInfo;
  492. if (GENERAL[_ana]->name == "default")
  493. {
  494. zw->filename = GENERAL[_ana]->ROI[i]->name + ".bmp";
  495. zw->filename_org = GENERAL[_ana]->ROI[i]->name + ".jpg";
  496. }
  497. else
  498. {
  499. zw->filename = GENERAL[_ana]->name + "_" + GENERAL[_ana]->ROI[i]->name + ".bmp";
  500. zw->filename_org = GENERAL[_ana]->name + "_" + GENERAL[_ana]->ROI[i]->name + ".jpg";
  501. }
  502. if (CNNType == Digital)
  503. zw->val = GENERAL[_ana]->ROI[i]->result_klasse;
  504. else
  505. zw->val = GENERAL[_ana]->ROI[i]->result_float;
  506. zw->image = GENERAL[_ana]->ROI[i]->image;
  507. zw->image_org = GENERAL[_ana]->ROI[i]->image_org;
  508. result.push_back(zw);
  509. }
  510. return result;
  511. }
  512. int ClassFlowCNNGeneral::getAnzahlGENERAL()
  513. {
  514. return GENERAL.size();
  515. }
  516. string ClassFlowCNNGeneral::getNameGENERAL(int _analog)
  517. {
  518. if (_analog < GENERAL.size())
  519. return GENERAL[_analog]->name;
  520. return "GENERAL DOES NOT EXIST";
  521. }
  522. general* ClassFlowCNNGeneral::GetGENERAL(int _analog)
  523. {
  524. if (_analog < GENERAL.size())
  525. return GENERAL[_analog];
  526. return NULL;
  527. }
  528. void ClassFlowCNNGeneral::UpdateNameNumbers(std::vector<std::string> *_name_numbers)
  529. {
  530. for (int _dig = 0; _dig < GENERAL.size(); _dig++)
  531. {
  532. std::string _name = GENERAL[_dig]->name;
  533. bool found = false;
  534. for (int i = 0; i < (*_name_numbers).size(); ++i)
  535. {
  536. if ((*_name_numbers)[i] == _name)
  537. found = true;
  538. }
  539. if (!found)
  540. (*_name_numbers).push_back(_name);
  541. }
  542. }