| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- #include "defines.h"
- #include "CFindTemplate.h"
- #include "ClassLogFile.h"
- #include "Helper.h"
- #include <esp_log.h>
- static const char *TAG = "C FIND TEMPL";
- bool CFindTemplate::FindTemplate(RefInfo *_ref)
- {
- if (file_size(_ref->image_file.c_str()) == 0)
- {
- LogFile.WriteToFile(ESP_LOG_ERROR, TAG, _ref->image_file + " is empty!");
- return false;
- }
- uint8_t *rgb_template = stbi_load(_ref->image_file.c_str(), &tpl_width, &tpl_height, &tpl_bpp, channels);
- if (rgb_template == NULL)
- {
- LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to load " + _ref->image_file + "! Is it corrupted?");
- return false;
- }
- // ESP_LOGD(TAG, "FindTemplate 01");
- if (_ref->search_x == 0)
- {
- _ref->search_x = width;
- _ref->found_x = 0;
- }
- if (_ref->search_y == 0)
- {
- _ref->search_y = height;
- _ref->found_y = 0;
- }
- int x_search_area_start = std::max((_ref->target_x - _ref->search_x), 0);
- int x_search_area_stop = _ref->target_x + _ref->search_x;
- if ((x_search_area_stop + tpl_width) > width)
- {
- x_search_area_stop = width - tpl_width;
- }
- int x_search_area = x_search_area_stop - x_search_area_start + 1;
- int y_search_area_start = std::max((_ref->target_y - _ref->search_y), 0);
- int y_search_area_stop = _ref->target_y + _ref->search_y;
- if ((y_search_area_stop + tpl_height) > height)
- {
- y_search_area_stop = height - tpl_height;
- }
- int y_search_area = y_search_area_stop - y_search_area_start + 1;
- float avg = 0, SAD = 0;
- int min = 0, max = 0;
- bool isSimilar = false;
- // ESP_LOGD(TAG, "FindTemplate 02");
- if ((_ref->alignment_algo == 2) && (_ref->fastalg_x > -1) && (_ref->fastalg_y > -1))
- {
- 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);
- }
- // ESP_LOGD(TAG, "FindTemplate 03");
- if (isSimilar)
- {
- _ref->found_x = _ref->fastalg_x;
- _ref->found_y = _ref->fastalg_y;
- stbi_image_free(rgb_template);
- return true;
- }
- // ESP_LOGD(TAG, "FindTemplate 04");
- double minSAD = pow(tpl_width * tpl_height * 255, 2);
- RGBImageLock();
- // ESP_LOGD(TAG, "FindTemplate 05");
- int _anzchannels = channels;
- if (_ref->alignment_algo == 0)
- {
- // 0 = "Default" (nur R-Kanal)
- _anzchannels = 1;
- }
- for (int x_outer = x_search_area_start; x_outer <= x_search_area_stop; x_outer++)
- {
- for (int y_outer = y_search_area_start; y_outer <= y_search_area_stop; ++y_outer)
- {
- double aktSAD = 0;
- for (int tpl_x = 0; tpl_x < tpl_width; tpl_x++)
- {
- for (int tpl_y = 0; tpl_y < tpl_height; tpl_y++)
- {
- stbi_uc *p_org = rgb_image + (channels * ((y_outer + tpl_y) * width + (x_outer + tpl_x)));
- stbi_uc *p_tpl = rgb_template + (channels * (tpl_y * tpl_width + tpl_x));
- for (int tpl_ch = 0; tpl_ch < _anzchannels; ++tpl_ch)
- {
- aktSAD += pow(p_tpl[tpl_ch] - p_org[tpl_ch], 2);
- }
- }
- }
- if (aktSAD < minSAD)
- {
- minSAD = aktSAD;
- _ref->found_x = x_outer;
- _ref->found_y = y_outer;
- }
- }
- }
- // ESP_LOGD(TAG, "FindTemplate 06");
- if (_ref->alignment_algo == 2)
- {
- 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);
- }
- // ESP_LOGD(TAG, "FindTemplate 07");
- if (isSimilar)
- {
- _ref->fastalg_x = _ref->found_x;
- _ref->fastalg_y = _ref->found_y;
- _ref->fastalg_min = min;
- _ref->fastalg_max = max;
- _ref->fastalg_avg = avg;
- _ref->fastalg_SAD = SAD;
- RGBImageRelease();
- stbi_image_free(rgb_template);
- return true;
- }
- RGBImageRelease();
- stbi_image_free(rgb_template);
- // ESP_LOGD(TAG, "FindTemplate 09");
- return false;
- }
- 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)
- {
- int dif = 0;
- int minDif = 255;
- int maxDif = -255;
- double avgDifSum = 0;
- long int anz = 0;
- double aktSAD = 0;
- for (int x_outer = 0; x_outer <= _sizex; x_outer++)
- {
- for (int y_outer = 0; y_outer <= _sizey; ++y_outer)
- {
- stbi_uc *p_org = rgb_image + (channels * ((y_outer + _starty) * width + (x_outer + _startx)));
- stbi_uc *p_tpl = _rgb_tmpl + (channels * (y_outer * tpl_width + x_outer));
- for (int _ch = 0; _ch < channels; ++_ch)
- {
- dif = p_tpl[_ch] - p_org[_ch];
- aktSAD += pow(p_tpl[_ch] - p_org[_ch], 2);
- if (dif < minDif)
- {
- minDif = dif;
- }
- if (dif > maxDif)
- {
- maxDif = dif;
- }
- avgDifSum += dif;
- anz++;
- }
- }
- }
- avg = avgDifSum / anz;
- min = minDif;
- max = maxDif;
- SAD = sqrt(aktSAD) / anz;
- float _SADdif = abs(SAD - _SADold);
- ESP_LOGD(TAG, "Anzahl %ld, avgDifSum %fd, avg %f, SAD_neu: %fd, _SAD_old: %f, _SAD_crit:%f", anz, avgDifSum, avg, SAD, _SADold, _SADdif);
- if (_SADdif <= _SADcrit)
- {
- return true;
- }
- return false;
- }
|