CFindTemplate.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. #include "defines.h"
  2. #include "CFindTemplate.h"
  3. #include "ClassLogFile.h"
  4. #include "Helper.h"
  5. #include <esp_log.h>
  6. static const char *TAG = "C FIND TEMPL";
  7. bool CFindTemplate::FindTemplate(RefInfo *_ref)
  8. {
  9. if (file_size(_ref->image_file.c_str()) == 0)
  10. {
  11. LogFile.WriteToFile(ESP_LOG_ERROR, TAG, _ref->image_file + " is empty!");
  12. return false;
  13. }
  14. uint8_t *rgb_template = stbi_load(_ref->image_file.c_str(), &tpl_width, &tpl_height, &tpl_bpp, channels);
  15. if (rgb_template == NULL)
  16. {
  17. LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to load " + _ref->image_file + "! Is it corrupted?");
  18. return false;
  19. }
  20. // ESP_LOGD(TAG, "FindTemplate 01");
  21. if (_ref->search_x == 0)
  22. {
  23. _ref->search_x = width;
  24. _ref->found_x = 0;
  25. }
  26. if (_ref->search_y == 0)
  27. {
  28. _ref->search_y = height;
  29. _ref->found_y = 0;
  30. }
  31. int x_search_area_start = std::max((_ref->target_x - _ref->search_x), 0);
  32. int x_search_area_stop = _ref->target_x + _ref->search_x;
  33. if ((x_search_area_stop + tpl_width) > width)
  34. {
  35. x_search_area_stop = width - tpl_width;
  36. }
  37. int x_search_area = x_search_area_stop - x_search_area_start + 1;
  38. int y_search_area_start = std::max((_ref->target_y - _ref->search_y), 0);
  39. int y_search_area_stop = _ref->target_y + _ref->search_y;
  40. if ((y_search_area_stop + tpl_height) > height)
  41. {
  42. y_search_area_stop = height - tpl_height;
  43. }
  44. int y_search_area = y_search_area_stop - y_search_area_start + 1;
  45. float avg = 0, SAD = 0;
  46. int min = 0, max = 0;
  47. bool isSimilar = false;
  48. // ESP_LOGD(TAG, "FindTemplate 02");
  49. if ((_ref->alignment_algo == 2) && (_ref->fastalg_x > -1) && (_ref->fastalg_y > -1))
  50. {
  51. isSimilar = CalculateSimularities(rgb_template, _ref->fastalg_x, _ref->fastalg_y, x_search_area, y_search_area, min, avg, max, SAD, _ref->fastalg_SAD, _ref->fastalg_SAD_criteria);
  52. }
  53. // ESP_LOGD(TAG, "FindTemplate 03");
  54. if (isSimilar)
  55. {
  56. _ref->found_x = _ref->fastalg_x;
  57. _ref->found_y = _ref->fastalg_y;
  58. stbi_image_free(rgb_template);
  59. return true;
  60. }
  61. // ESP_LOGD(TAG, "FindTemplate 04");
  62. double minSAD = pow(tpl_width * tpl_height * 255, 2);
  63. RGBImageLock();
  64. // ESP_LOGD(TAG, "FindTemplate 05");
  65. int _anzchannels = channels;
  66. if (_ref->alignment_algo == 0)
  67. {
  68. // 0 = "Default" (nur R-Kanal)
  69. _anzchannels = 1;
  70. }
  71. for (int x_outer = x_search_area_start; x_outer <= x_search_area_stop; x_outer++)
  72. {
  73. for (int y_outer = y_search_area_start; y_outer <= y_search_area_stop; ++y_outer)
  74. {
  75. double aktSAD = 0;
  76. for (int tpl_x = 0; tpl_x < tpl_width; tpl_x++)
  77. {
  78. for (int tpl_y = 0; tpl_y < tpl_height; tpl_y++)
  79. {
  80. stbi_uc *p_org = rgb_image + (channels * ((y_outer + tpl_y) * width + (x_outer + tpl_x)));
  81. stbi_uc *p_tpl = rgb_template + (channels * (tpl_y * tpl_width + tpl_x));
  82. for (int tpl_ch = 0; tpl_ch < _anzchannels; ++tpl_ch)
  83. {
  84. aktSAD += pow(p_tpl[tpl_ch] - p_org[tpl_ch], 2);
  85. }
  86. }
  87. }
  88. if (aktSAD < minSAD)
  89. {
  90. minSAD = aktSAD;
  91. _ref->found_x = x_outer;
  92. _ref->found_y = y_outer;
  93. }
  94. }
  95. }
  96. // ESP_LOGD(TAG, "FindTemplate 06");
  97. if (_ref->alignment_algo == 2)
  98. {
  99. isSimilar = CalculateSimularities(rgb_template, _ref->found_x, _ref->found_y, x_search_area, y_search_area, min, avg, max, SAD, _ref->fastalg_SAD, _ref->fastalg_SAD_criteria);
  100. }
  101. // ESP_LOGD(TAG, "FindTemplate 07");
  102. if (isSimilar)
  103. {
  104. _ref->fastalg_x = _ref->found_x;
  105. _ref->fastalg_y = _ref->found_y;
  106. _ref->fastalg_min = min;
  107. _ref->fastalg_max = max;
  108. _ref->fastalg_avg = avg;
  109. _ref->fastalg_SAD = SAD;
  110. RGBImageRelease();
  111. stbi_image_free(rgb_template);
  112. return true;
  113. }
  114. RGBImageRelease();
  115. stbi_image_free(rgb_template);
  116. // ESP_LOGD(TAG, "FindTemplate 09");
  117. return false;
  118. }
  119. bool CFindTemplate::CalculateSimularities(uint8_t *_rgb_tmpl, int _startx, int _starty, int _sizex, int _sizey, int &min, float &avg, int &max, float &SAD, float _SADold, float _SADcrit)
  120. {
  121. int dif = 0;
  122. int minDif = 255;
  123. int maxDif = -255;
  124. double avgDifSum = 0;
  125. long int anz = 0;
  126. double aktSAD = 0;
  127. for (int x_outer = 0; x_outer <= _sizex; x_outer++)
  128. {
  129. for (int y_outer = 0; y_outer <= _sizey; ++y_outer)
  130. {
  131. stbi_uc *p_org = rgb_image + (channels * ((y_outer + _starty) * width + (x_outer + _startx)));
  132. stbi_uc *p_tpl = _rgb_tmpl + (channels * (y_outer * tpl_width + x_outer));
  133. for (int _ch = 0; _ch < channels; ++_ch)
  134. {
  135. dif = p_tpl[_ch] - p_org[_ch];
  136. aktSAD += pow(p_tpl[_ch] - p_org[_ch], 2);
  137. if (dif < minDif)
  138. {
  139. minDif = dif;
  140. }
  141. if (dif > maxDif)
  142. {
  143. maxDif = dif;
  144. }
  145. avgDifSum += dif;
  146. anz++;
  147. }
  148. }
  149. }
  150. avg = avgDifSum / anz;
  151. min = minDif;
  152. max = maxDif;
  153. SAD = sqrt(aktSAD) / anz;
  154. float _SADdif = abs(SAD - _SADold);
  155. ESP_LOGD(TAG, "Anzahl %ld, avgDifSum %fd, avg %f, SAD_neu: %fd, _SAD_old: %f, _SAD_crit:%f", anz, avgDifSum, avg, SAD, _SADold, _SADdif);
  156. if (_SADdif <= _SADcrit)
  157. {
  158. return true;
  159. }
  160. return false;
  161. }