mirror of
https://github.com/jomjol/AI-on-the-edge-device.git
synced 2025-12-07 03:56:57 +03:00
Compare commits
48 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fa3e300c37 | ||
|
|
78744840eb | ||
|
|
46cfe45cf6 | ||
|
|
91ff41a9d9 | ||
|
|
3869da9d06 | ||
|
|
2530691347 | ||
|
|
c65de27e9d | ||
|
|
9bb715fcb2 | ||
|
|
8c4f39ab49 | ||
|
|
e5206091dd | ||
|
|
e53c6fe64c | ||
|
|
b893b24d88 | ||
|
|
c7caa55223 | ||
|
|
c675019ef3 | ||
|
|
f2fea0a402 | ||
|
|
aeafd631d5 | ||
|
|
aa442632ea | ||
|
|
2a4b5f88a7 | ||
|
|
0e36010937 | ||
|
|
8a06825871 | ||
|
|
ce2f1bcde6 | ||
|
|
c59826471c | ||
|
|
9c8f64f602 | ||
|
|
d4342a77c8 | ||
|
|
054d2296c4 | ||
|
|
ae116981ef | ||
|
|
becb886ab7 | ||
|
|
3502ac9263 | ||
|
|
c64cb94b7d | ||
|
|
dffb28816d | ||
|
|
6e521f07c4 | ||
|
|
c05313aefc | ||
|
|
db0ca1cb9b | ||
|
|
584a73255a | ||
|
|
3a66385059 | ||
|
|
7e4f83c2f5 | ||
|
|
9971c82e99 | ||
|
|
b418525b3b | ||
|
|
f5c28107d4 | ||
|
|
793f928e6e | ||
|
|
a8fb2e37d5 | ||
|
|
11fed9394a | ||
|
|
bcdd0c66c0 | ||
|
|
e988215d8a | ||
|
|
f616643335 | ||
|
|
816f93222b | ||
|
|
9e85b1240a | ||
|
|
c5059b4568 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -4,6 +4,7 @@
|
||||
.code-workspace
|
||||
.helper/
|
||||
/sd-card/htm./.vscode/
|
||||
/code/build
|
||||
|
||||
CMakeLists.txt.user
|
||||
CMakeCache.txt
|
||||
|
||||
59
README.md
59
README.md
@@ -13,24 +13,78 @@ A 3d-printable housing can be found here: https://www.thingiverse.com/thing:4571
|
||||
|
||||
|
||||
|
||||
## Donate
|
||||
|
||||
------
|
||||
|
||||
If you would like to support the developer with a cup of coffee you can do that via [Paypal](https://www.paypal.com/donate?hosted_button_id=8TRSVYNYKDSWL).
|
||||
|
||||
<form action="https://www.paypal.com/donate" method="post" target="_top">
|
||||
<input type="hidden" name="hosted_button_id" value="8TRSVYNYKDSWL" />
|
||||
<input type="image" src="https://www.paypalobjects.com/en_US/DK/i/btn/btn_donateCC_LG.gif" border="0" name="submit" title="PayPal - The safer, easier way to pay online!" alt="Donate with PayPal button" />
|
||||
<img alt="" border="0" src="https://www.paypal.com/en_DE/i/scr/pixel.gif" width="1" height="1" />
|
||||
</form>
|
||||
|
||||
|
||||
## Change log
|
||||
|
||||
------
|
||||
|
||||
### Known Issues
|
||||
|
||||
* Reboot on extensive web access due to the limits of the internal web server
|
||||
* slow response of web server during picture analysis
|
||||
* spontaneous reboots (mostly due to html access during image processing) - self recovery implemented
|
||||
|
||||
------
|
||||
|
||||
**General remark:** Beside the `firmware.bin`, typically also the content of `/html` needs to be updated!
|
||||
|
||||
|
||||
|
||||
##### 6.1.0 Image Processing in Memory - (2021-01-20)
|
||||
|
||||
* Disabling of analog / digital counters in configuration
|
||||
* Improved Alignment Algorithm (`AlignmentAlgo` = `Default`, `Accurate` , `Fast`)
|
||||
* Analog counters: `ExtendedResolution` (last digit is extended by sub comma value of CNN)
|
||||
* `config.ini`: additional parameter `hostname` (additional to wlan.ini)
|
||||
* Switching of GPIO12/13 via http-interface: `/GPIO?GPIO=12&Status=high/low`
|
||||
* Bug fixing: html configuration page, wlan password ("=" now possible)
|
||||
|
||||
##### 6.0.0 Image Processing in Memory - (2021-01-02)
|
||||
|
||||
* **Major change**: image processing fully in memory - no need of SD card buffer anymore
|
||||
|
||||
* Need to limit camera resolution to VGA (due to memory limits)
|
||||
|
||||
* MQTT: Last Will Testament (LWT) implemented: "connection lost" in case of connection lost to `TopicError`
|
||||
|
||||
* Disabled `CheckDigitIncreaseConsistency` in default configuration - must now be explicit enabled if needed
|
||||
|
||||
* Update digital CNN to v7.2.1 (additional digital images trained)
|
||||
|
||||
* Setting of arbitrary time server in `config.ini`
|
||||
|
||||
* Option for fixed IP-, DNS-Settings in `wlan.ini`
|
||||
|
||||
* Increased stability (internal image and camera handling)
|
||||
|
||||
* Bug fixing: edit digits, handling PreValue, html-bugs
|
||||
|
||||
|
||||
|
||||
##### 5.0.0 Setup Modus - (2020-12-06)
|
||||
|
||||
* Implementation of initial setup modus for fresh installation
|
||||
|
||||
* Code restructuring (full compatibility between pure ESP-IDF and Platformio w/ espressif)
|
||||
|
||||
|
||||
|
||||
##### 4.1.1 Configuration editor - (2020-12-02)
|
||||
|
||||
* Bug fixing: internal improvement of file handling (reduce not responding)
|
||||
|
||||
|
||||
|
||||
##### 4.1.0 Configuration editor - (2020-11-30)
|
||||
|
||||
* Implementation of configuration editor (including basic and expert mode)
|
||||
@@ -47,7 +101,6 @@ A 3d-printable housing can be found here: https://www.thingiverse.com/thing:4571
|
||||
|
||||
|
||||
|
||||
|
||||
##### 4.0.0 Tflite Core - (2020-11-15)
|
||||
* Implementation of rolling log-files
|
||||
|
||||
|
||||
@@ -11,6 +11,10 @@
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "Helper.h"
|
||||
|
||||
@@ -23,6 +27,9 @@ std::string ssid;
|
||||
std::string passphrase;
|
||||
std::string hostname;
|
||||
std::string ipaddress;
|
||||
std::string gw;
|
||||
std::string netmask;
|
||||
std::string dns;
|
||||
|
||||
std::string std_hostname = "watermeter";
|
||||
|
||||
@@ -86,7 +93,7 @@ static esp_err_t event_handler(void *ctx, system_event_t *event)
|
||||
{
|
||||
switch(event->event_id) {
|
||||
case SYSTEM_EVENT_STA_START:
|
||||
blinkstatus(200, 5);
|
||||
blinkstatus(200, 1);
|
||||
wifi_connect();
|
||||
break;
|
||||
case SYSTEM_EVENT_STA_GOT_IP:
|
||||
@@ -125,10 +132,163 @@ void initialise_wifi(std::string _ssid, std::string _passphrase, std::string _ho
|
||||
tcpip_adapter_ip_info_t ip_info;
|
||||
ESP_ERROR_CHECK(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip_info));
|
||||
ipaddress = std::string(ip4addr_ntoa(&ip_info.ip));
|
||||
netmask = std::string(ip4addr_ntoa(&ip_info.netmask));
|
||||
gw = std::string(ip4addr_ntoa(&ip_info.gw));
|
||||
printf("IPv4 : %s\n", ip4addr_ntoa(&ip_info.ip));
|
||||
printf("HostName : %s\n", hostname.c_str());
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
void strinttoip4(std::string ip, int &a, int &b, int &c, int &d) {
|
||||
std::stringstream s(ip);
|
||||
char ch; //to temporarily store the '.'
|
||||
s >> a >> ch >> b >> ch >> c >> ch >> d;
|
||||
}
|
||||
|
||||
void initialise_wifi_fixed_ip(std::string _ip, std::string _gw, std::string _netmask, std::string _ssid, std::string _passphrase, std::string _hostname, std::string _dns)
|
||||
{
|
||||
|
||||
ssid = _ssid;
|
||||
passphrase = _passphrase;
|
||||
hostname = _hostname;
|
||||
dns = _dns;
|
||||
|
||||
wifi_event_group = xEventGroupCreate();
|
||||
|
||||
ESP_ERROR_CHECK(esp_netif_init());
|
||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||
|
||||
esp_netif_t *my_sta = esp_netif_create_default_wifi_sta();
|
||||
|
||||
esp_netif_dhcpc_stop(my_sta);
|
||||
|
||||
esp_netif_ip_info_t ip_info;
|
||||
|
||||
int a, b, c, d;
|
||||
|
||||
strinttoip4(_ip, a, b, c, d);
|
||||
IP4_ADDR(&ip_info.ip, a, b, c, d);
|
||||
|
||||
strinttoip4(_gw, a, b, c, d);
|
||||
IP4_ADDR(&ip_info.gw, a, b, c, d);
|
||||
|
||||
strinttoip4(_netmask, a, b, c, d);
|
||||
IP4_ADDR(&ip_info.netmask, a, b, c, d);
|
||||
|
||||
esp_netif_set_ip_info(my_sta, &ip_info);
|
||||
|
||||
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
||||
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
|
||||
|
||||
if (dns.length() > 0) {
|
||||
esp_netif_dns_info_t dns_info;
|
||||
ip4_addr_t ip;
|
||||
ip.addr = esp_ip4addr_aton(dns.c_str());
|
||||
ip_addr_set_ip4_u32(&dns_info.ip, ip.addr);
|
||||
ESP_ERROR_CHECK(esp_netif_set_dns_info(my_sta, ESP_NETIF_DNS_MAIN, &dns_info));
|
||||
}
|
||||
|
||||
ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL) );
|
||||
|
||||
wifi_config_t wifi_config = { };
|
||||
strcpy((char*)wifi_config.sta.ssid, (const char*)ssid.c_str());
|
||||
strcpy((char*)wifi_config.sta.password, (const char*)passphrase.c_str());
|
||||
|
||||
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );
|
||||
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) );
|
||||
ESP_ERROR_CHECK(esp_wifi_start() );
|
||||
|
||||
ESP_LOGI(MAIN_TAG, "wifi_init_sta finished.");
|
||||
|
||||
EventBits_t bits = xEventGroupWaitBits(wifi_event_group,CONNECTED_BIT,true,true,portMAX_DELAY);
|
||||
|
||||
if (bits & CONNECTED_BIT) {
|
||||
ESP_LOGI(MAIN_TAG, "connected to ap SSID:%s password:%s",
|
||||
ssid.c_str(), passphrase.c_str());
|
||||
} else {
|
||||
ESP_LOGI(MAIN_TAG, "Failed to connect to SSID:%s, password:%s",
|
||||
ssid.c_str(), passphrase.c_str());
|
||||
}
|
||||
tcpip_adapter_ip_info_t ip_info2;
|
||||
ESP_ERROR_CHECK(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip_info2));
|
||||
ipaddress = std::string(ip4addr_ntoa(&ip_info2.ip));
|
||||
netmask = std::string(ip4addr_ntoa(&ip_info2.netmask));
|
||||
gw = std::string(ip4addr_ntoa(&ip_info2.gw));
|
||||
|
||||
// vEventGroupDelete(wifi_event_group);
|
||||
}
|
||||
|
||||
|
||||
bool ChangeHostName(std::string fn, std::string _newhostname)
|
||||
{
|
||||
if (_newhostname == hostname)
|
||||
return false;
|
||||
|
||||
string line = "";
|
||||
std::vector<string> zerlegt;
|
||||
|
||||
bool found = false;
|
||||
|
||||
std::vector<string> neuesfile;
|
||||
|
||||
FILE* pFile;
|
||||
fn = FormatFileName(fn);
|
||||
pFile = OpenFileAndWait(fn.c_str(), "r");
|
||||
|
||||
printf("file loaded\n");
|
||||
|
||||
if (pFile == NULL)
|
||||
return false;
|
||||
|
||||
char zw[1024];
|
||||
fgets(zw, 1024, pFile);
|
||||
line = std::string(zw);
|
||||
|
||||
while ((line.size() > 0) || !(feof(pFile)))
|
||||
{
|
||||
printf("%s", line.c_str());
|
||||
zerlegt = ZerlegeZeile(line, "=");
|
||||
zerlegt[0] = trim(zerlegt[0], " ");
|
||||
|
||||
if ((zerlegt.size() > 1) && (toUpper(zerlegt[0]) == "HOSTNAME")){
|
||||
line = "hostname = \"" + _newhostname + "\"\n";
|
||||
found = true;
|
||||
}
|
||||
|
||||
neuesfile.push_back(line);
|
||||
|
||||
if (fgets(zw, 1024, pFile) == NULL)
|
||||
{
|
||||
line = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
line = std::string(zw);
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
line = "hostname = \"" + _newhostname + "\"\n";
|
||||
neuesfile.push_back(line);
|
||||
}
|
||||
|
||||
fclose(pFile);
|
||||
|
||||
pFile = OpenFileAndWait(fn.c_str(), "w+");
|
||||
|
||||
for (int i = 0; i < neuesfile.size(); ++i)
|
||||
{
|
||||
fputs(neuesfile[i].c_str(), pFile);
|
||||
}
|
||||
|
||||
fclose(pFile);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void LoadWlanFromFile(std::string fn, std::string &_ssid, std::string &_passphrase, std::string &_hostname)
|
||||
{
|
||||
@@ -138,7 +298,9 @@ void LoadWlanFromFile(std::string fn, std::string &_ssid, std::string &_passphra
|
||||
|
||||
FILE* pFile;
|
||||
fn = FormatFileName(fn);
|
||||
pFile = fopen(fn.c_str(), "r");
|
||||
pFile = OpenFileAndWait(fn.c_str(), "r");
|
||||
|
||||
printf("file loaded\n");
|
||||
|
||||
if (pFile == NULL)
|
||||
return;
|
||||
@@ -149,9 +311,11 @@ void LoadWlanFromFile(std::string fn, std::string &_ssid, std::string &_passphra
|
||||
|
||||
while ((line.size() > 0) || !(feof(pFile)))
|
||||
{
|
||||
// printf("%s", line.c_str());
|
||||
printf("%s", line.c_str());
|
||||
zerlegt = ZerlegeZeile(line, "=");
|
||||
zerlegt[0] = trim(zerlegt[0], " ");
|
||||
for (int i = 2; i < zerlegt.size(); ++i)
|
||||
zerlegt[i] = zerlegt[i-1] + zerlegt[i];
|
||||
|
||||
if ((zerlegt.size() > 1) && (toUpper(zerlegt[0]) == "HOSTNAME")){
|
||||
_hostname = trim(zerlegt[1]);
|
||||
@@ -192,6 +356,71 @@ void LoadWlanFromFile(std::string fn, std::string &_ssid, std::string &_passphra
|
||||
}
|
||||
}
|
||||
|
||||
void LoadNetConfigFromFile(std::string fn, std::string &_ip, std::string &_gw, std::string &_netmask, std::string &_dns)
|
||||
{
|
||||
string line = "";
|
||||
std::vector<string> zerlegt;
|
||||
|
||||
FILE* pFile;
|
||||
fn = FormatFileName(fn);
|
||||
pFile = OpenFileAndWait(fn.c_str(), "r");
|
||||
|
||||
printf("file loaded\n");
|
||||
|
||||
if (pFile == NULL)
|
||||
return;
|
||||
|
||||
char zw[1024];
|
||||
fgets(zw, 1024, pFile);
|
||||
line = std::string(zw);
|
||||
|
||||
while ((line.size() > 0) || !(feof(pFile)))
|
||||
{
|
||||
printf("%s", line.c_str());
|
||||
zerlegt = ZerlegeZeile(line, "=");
|
||||
zerlegt[0] = trim(zerlegt[0], " ");
|
||||
|
||||
if ((zerlegt.size() > 1) && (toUpper(zerlegt[0]) == "IP")){
|
||||
_ip = zerlegt[1];
|
||||
if ((_ip[0] == '"') && (_ip[_ip.length()-1] == '"')){
|
||||
_ip = _ip.substr(1, _ip.length()-2);
|
||||
}
|
||||
}
|
||||
|
||||
if ((zerlegt.size() > 1) && (toUpper(zerlegt[0]) == "GATEWAY")){
|
||||
_gw = zerlegt[1];
|
||||
if ((_gw[0] == '"') && (_gw[_gw.length()-1] == '"')){
|
||||
_gw = _gw.substr(1, _gw.length()-2);
|
||||
}
|
||||
}
|
||||
|
||||
if ((zerlegt.size() > 1) && (toUpper(zerlegt[0]) == "NETMASK")){
|
||||
_netmask = zerlegt[1];
|
||||
if ((_netmask[0] == '"') && (_netmask[_netmask.length()-1] == '"')){
|
||||
_netmask = _netmask.substr(1, _netmask.length()-2);
|
||||
}
|
||||
}
|
||||
|
||||
if ((zerlegt.size() > 1) && (toUpper(zerlegt[0]) == "DNS")){
|
||||
_dns = zerlegt[1];
|
||||
if ((_dns[0] == '"') && (_dns[_dns.length()-1] == '"')){
|
||||
_dns = _dns.substr(1, _dns.length()-2);
|
||||
}
|
||||
}
|
||||
|
||||
if (fgets(zw, 1024, pFile) == NULL)
|
||||
{
|
||||
line = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
line = std::string(zw);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(pFile);
|
||||
}
|
||||
|
||||
|
||||
std::string getHostname(){
|
||||
return hostname;
|
||||
@@ -204,3 +433,12 @@ std::string getIPAddress(){
|
||||
std::string getSSID(){
|
||||
return ssid;
|
||||
}
|
||||
|
||||
std::string getNetMask(){
|
||||
return netmask;
|
||||
}
|
||||
|
||||
std::string getGW(){
|
||||
return gw;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,11 +7,18 @@
|
||||
const int CONNECTED_BIT = BIT0;
|
||||
|
||||
void initialise_wifi(std::string _ssid, std::string _passphrase, std::string _hostname);
|
||||
void initialise_wifi_fixed_ip(std::string _ip, std::string _gw, std::string _netmask, std::string _ssid, std::string _passphrase, std::string _hostname, std::string _dns = "");
|
||||
|
||||
|
||||
void LoadWlanFromFile(std::string fn, std::string &_ssid, std::string &_passphrase, std::string &_hostname);
|
||||
void LoadNetConfigFromFile(std::string fn, std::string &_ip, std::string &_gw, std::string &_netmask, std::string &_dns);
|
||||
|
||||
bool ChangeHostName(std::string fn, std::string _newhostname);
|
||||
|
||||
std::string getHostname();
|
||||
std::string getIPAddress();
|
||||
std::string getSSID();
|
||||
std::string getNetMask();
|
||||
std::string getGW();
|
||||
|
||||
#endif
|
||||
9
code/components/jomjol_controlGPIO/CMakeLists.txt
Normal file
9
code/components/jomjol_controlGPIO/CMakeLists.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
FILE(GLOB_RECURSE app_sources ${CMAKE_CURRENT_SOURCE_DIR}/*.*)
|
||||
|
||||
list(APPEND EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)
|
||||
|
||||
idf_component_register(SRCS ${app_sources}
|
||||
INCLUDE_DIRS "."
|
||||
REQUIRES esp_http_server jomjol_logfile)
|
||||
|
||||
|
||||
124
code/components/jomjol_controlGPIO/server_GPIO.cpp
Normal file
124
code/components/jomjol_controlGPIO/server_GPIO.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
#include <string>
|
||||
#include "string.h"
|
||||
|
||||
#include <string.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_log.h"
|
||||
#include "driver/gpio.h"
|
||||
//#include "errno.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "server_GPIO.h"
|
||||
|
||||
#include "ClassLogFile.h"
|
||||
|
||||
#include "Helper.h"
|
||||
|
||||
// #define DEBUG_DETAIL_ON
|
||||
|
||||
esp_err_t handler_switch_GPIO(httpd_req_t *req)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_switch_GPIO - Start");
|
||||
#endif
|
||||
|
||||
LogFile.WriteToFile("handler_switch_GPIO");
|
||||
char _query[200];
|
||||
char _valueGPIO[30];
|
||||
char _valueStatus[30];
|
||||
std::string gpio, status, zw;
|
||||
int gpionum = 0;
|
||||
gpio_num_t gpio_num;
|
||||
|
||||
if (httpd_req_get_url_query_str(req, _query, 200) == ESP_OK)
|
||||
{
|
||||
printf("Query: "); printf(_query); printf("\n");
|
||||
|
||||
if (httpd_query_key_value(_query, "GPIO", _valueGPIO, 30) == ESP_OK)
|
||||
{
|
||||
printf("GPIO is found"); printf(_valueGPIO); printf("\n");
|
||||
gpio = std::string(_valueGPIO);
|
||||
}
|
||||
if (httpd_query_key_value(_query, "Status", _valueStatus, 30) == ESP_OK)
|
||||
{
|
||||
printf("Status is found"); printf(_valueStatus); printf("\n");
|
||||
status = std::string(_valueStatus);
|
||||
}
|
||||
};
|
||||
|
||||
status = toUpper(status);
|
||||
if (!(status == "HIGH") && !(status == "LOW"))
|
||||
{
|
||||
zw = "Status not valid: " + status;;
|
||||
httpd_resp_sendstr_chunk(req, zw.c_str());
|
||||
httpd_resp_sendstr_chunk(req, NULL);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
gpionum = stoi(gpio);
|
||||
|
||||
// frei: 16; 12-15; 2; 4 // nur 12 und 13 funktionieren 2: reboot, 4: BlitzLED, 14/15: DMA für SDKarte ???
|
||||
|
||||
switch (gpionum) {
|
||||
case 12:
|
||||
gpio_num = GPIO_NUM_12;
|
||||
break;
|
||||
case 13:
|
||||
gpio_num = GPIO_NUM_13;
|
||||
break;
|
||||
default:
|
||||
zw = "GPIO" + std::to_string(gpionum) + " not support - only 12 & 13 free";
|
||||
httpd_resp_sendstr_chunk(req, zw.c_str());
|
||||
httpd_resp_sendstr_chunk(req, NULL);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
if (status == "HIGH")
|
||||
gpio_set_level(gpio_num, 1);
|
||||
else
|
||||
gpio_set_level(gpio_num, 0);
|
||||
|
||||
|
||||
zw = "GPIO" + std::to_string(gpionum) + " switched to " + status;
|
||||
httpd_resp_sendstr_chunk(req, zw.c_str());
|
||||
httpd_resp_sendstr_chunk(req, NULL);
|
||||
return ESP_OK;
|
||||
};
|
||||
|
||||
void initGPIO()
|
||||
{
|
||||
gpio_config_t io_conf;
|
||||
//disable interrupt
|
||||
io_conf.intr_type = GPIO_INTR_DISABLE;
|
||||
//set as output mode
|
||||
io_conf.mode = GPIO_MODE_OUTPUT;
|
||||
//bit mask of the pins that you want to set,e.g.GPIO18/19
|
||||
// io_conf.pin_bit_mask = ((1ULL<<GPIO_OUTPUT_IO_0) | (1ULL<<GPIO_OUTPUT_IO_1));
|
||||
// io_conf.pin_bit_mask = ((1ULL << GPIO_NUM_12) | (1ULL << GPIO_NUM_2) | (1ULL << GPIO_NUM_4) | (1ULL << GPIO_NUM_12) | (1ULL << GPIO_NUM_13) | (1ULL << GPIO_NUM_14) | (1ULL << GPIO_NUM_15));
|
||||
io_conf.pin_bit_mask = ((1ULL << GPIO_NUM_12) | (1ULL << GPIO_NUM_13));
|
||||
//disable pull-down mode
|
||||
io_conf.pull_down_en = (gpio_pulldown_t) 0;
|
||||
//disable pull-up mode
|
||||
io_conf.pull_up_en = (gpio_pullup_t) 0;
|
||||
//configure GPIO with the given settings
|
||||
gpio_config(&io_conf);
|
||||
}
|
||||
|
||||
|
||||
void register_server_GPIO_uri(httpd_handle_t server)
|
||||
{
|
||||
ESP_LOGI(TAGPARTGPIO, "server_GPIO - Registering URI handlers");
|
||||
|
||||
httpd_uri_t camuri = { };
|
||||
camuri.method = HTTP_GET;
|
||||
camuri.uri = "/GPIO";
|
||||
camuri.handler = handler_switch_GPIO;
|
||||
camuri.user_ctx = (void*) "switch GPIO";
|
||||
httpd_register_uri_handler(server, &camuri);
|
||||
|
||||
initGPIO();
|
||||
}
|
||||
10
code/components/jomjol_controlGPIO/server_GPIO.h
Normal file
10
code/components/jomjol_controlGPIO/server_GPIO.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#include <esp_log.h>
|
||||
|
||||
#include <esp_http_server.h>
|
||||
|
||||
//#include "ClassControllCamera.h"
|
||||
|
||||
static const char *TAGPARTGPIO = "server_GPIO";
|
||||
|
||||
void register_server_GPIO_uri(httpd_handle_t server);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "ClassControllCamera.h"
|
||||
#include "ClassLogFile.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include "driver/gpio.h"
|
||||
@@ -6,34 +7,11 @@
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "Helper.h"
|
||||
#include "CFindTemplate.h"
|
||||
#include "CImageBasis.h"
|
||||
|
||||
// #include "camera_define.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
#define BOARD_ESP32CAM_AITHINKER
|
||||
|
||||
/**
|
||||
* 2. Kconfig setup
|
||||
*
|
||||
* If you have a Kconfig file, copy the content from
|
||||
* https://github.com/espressif/esp32-camera/blob/master/Kconfig into it.
|
||||
* In case you haven't, copy and paste this Kconfig file inside the src directory.
|
||||
* This Kconfig file has definitions that allows more control over the camera and
|
||||
* how it will be initialized.
|
||||
*/
|
||||
|
||||
/**
|
||||
* 3. Enable PSRAM on sdkconfig:
|
||||
*
|
||||
* CONFIG_ESP32_SPIRAM_SUPPORT=y
|
||||
*
|
||||
* More info on
|
||||
* https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/kconfig.html#config-esp32-spiram-support
|
||||
*/
|
||||
|
||||
// ================================ CODE ======================================
|
||||
|
||||
#include <esp_event_loop.h>
|
||||
#include <esp_log.h>
|
||||
@@ -47,31 +25,10 @@
|
||||
|
||||
#include "esp_camera.h"
|
||||
|
||||
// WROVER-KIT PIN Map
|
||||
#ifdef BOARD_WROVER_KIT
|
||||
// #define DEBUG_DETAIL_ON
|
||||
|
||||
#define CAM_PIN_PWDN -1 //power down is not used
|
||||
#define CAM_PIN_RESET -1 //software reset will be performed
|
||||
#define CAM_PIN_XCLK 21
|
||||
#define CAM_PIN_SIOD 26
|
||||
#define CAM_PIN_SIOC 27
|
||||
|
||||
#define CAM_PIN_D7 35
|
||||
#define CAM_PIN_D6 34
|
||||
#define CAM_PIN_D5 39
|
||||
#define CAM_PIN_D4 36
|
||||
#define CAM_PIN_D3 19
|
||||
#define CAM_PIN_D2 18
|
||||
#define CAM_PIN_D1 5
|
||||
#define CAM_PIN_D0 4
|
||||
#define CAM_PIN_VSYNC 25
|
||||
#define CAM_PIN_HREF 23
|
||||
#define CAM_PIN_PCLK 22
|
||||
|
||||
#endif
|
||||
|
||||
// ESP32Cam (AiThinker) PIN Map
|
||||
#ifdef BOARD_ESP32CAM_AITHINKER
|
||||
|
||||
#define CAM_PIN_PWDN (gpio_num_t) 32
|
||||
#define CAM_PIN_RESET -1 //software reset will be performed
|
||||
@@ -91,8 +48,6 @@
|
||||
#define CAM_PIN_HREF 23
|
||||
#define CAM_PIN_PCLK 22
|
||||
|
||||
#endif
|
||||
|
||||
static const char *TAG = "example:take_picture";
|
||||
|
||||
static camera_config_t camera_config = {
|
||||
@@ -115,12 +70,14 @@ static camera_config_t camera_config = {
|
||||
.pin_pclk = CAM_PIN_PCLK,
|
||||
|
||||
//XCLK 20MHz or 10MHz for OV2640 double FPS (Experimental)
|
||||
.xclk_freq_hz = 20000000,
|
||||
// .xclk_freq_hz = 20000000, // Orginalwert
|
||||
.xclk_freq_hz = 5000000, // Test, um die Bildfehler los zu werden !!!!
|
||||
.ledc_timer = LEDC_TIMER_0,
|
||||
.ledc_channel = LEDC_CHANNEL_0,
|
||||
|
||||
.pixel_format = PIXFORMAT_JPEG, //YUV422,GRAYSCALE,RGB565,JPEG
|
||||
.frame_size = FRAMESIZE_UXGA, //QQVGA-UXGA Do not use sizes above QVGA when not JPEG
|
||||
.frame_size = FRAMESIZE_VGA, //QQVGA-UXGA Do not use sizes above QVGA when not JPEG
|
||||
// .frame_size = FRAMESIZE_UXGA, //QQVGA-UXGA Do not use sizes above QVGA when not JPEG
|
||||
|
||||
|
||||
|
||||
@@ -128,15 +85,13 @@ static camera_config_t camera_config = {
|
||||
.fb_count = 1 //if more than one, i2s runs in continuous mode. Use only with JPEG
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "driver/ledc.h"
|
||||
|
||||
CCamera Camera;
|
||||
|
||||
|
||||
#define FLASH_GPIO GPIO_NUM_4
|
||||
#define BLINK_GPIO GPIO_NUM_33
|
||||
|
||||
typedef struct {
|
||||
httpd_req_t *req;
|
||||
@@ -144,8 +99,6 @@ typedef struct {
|
||||
} jpg_chunking_t;
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#define LEDC_LS_CH2_GPIO (4)
|
||||
#define LEDC_LS_CH2_CHANNEL LEDC_CHANNEL_2
|
||||
#define LEDC_LS_TIMER LEDC_TIMER_1
|
||||
@@ -171,14 +124,6 @@ void test(){
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static size_t jpg_encode_stream(void * arg, size_t index, const void* data, size_t len){
|
||||
jpg_chunking_t *j = (jpg_chunking_t *)arg;
|
||||
if(!index){
|
||||
@@ -199,14 +144,145 @@ void CCamera::SetQualitySize(int qual, framesize_t resol)
|
||||
s->set_framesize(s, resol);
|
||||
ActualResolution = resol;
|
||||
ActualQuality = qual;
|
||||
|
||||
if (resol == FRAMESIZE_QVGA)
|
||||
{
|
||||
image_height = 240;
|
||||
image_width = 320;
|
||||
}
|
||||
if (resol == FRAMESIZE_VGA)
|
||||
{
|
||||
image_height = 480;
|
||||
image_width = 640;
|
||||
}
|
||||
// No higher Mode than VGA, damit der Kameraspeicher ausreicht.
|
||||
/*
|
||||
if (resol == FRAMESIZE_SVGA)
|
||||
{
|
||||
image_height = 600;
|
||||
image_width = 800;
|
||||
}
|
||||
if (resol == FRAMESIZE_XGA)
|
||||
{
|
||||
image_height = 768;
|
||||
image_width = 1024;
|
||||
}
|
||||
if (resol == FRAMESIZE_SXGA)
|
||||
{
|
||||
image_height = 1024;
|
||||
image_width = 1280;
|
||||
}
|
||||
if (resol == FRAMESIZE_UXGA)
|
||||
{
|
||||
image_height = 1200;
|
||||
image_width = 1600;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
esp_err_t CCamera::CaptureToBasisImage(CImageBasis *_Image, int delay)
|
||||
{
|
||||
string ftype;
|
||||
|
||||
uint8_t *zwischenspeicher = NULL;
|
||||
|
||||
|
||||
LEDOnOff(true);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("CCamera::CaptureToBasisImage - Start");
|
||||
#endif
|
||||
|
||||
if (delay > 0)
|
||||
{
|
||||
LightOnOff(true);
|
||||
const TickType_t xDelay = delay / portTICK_PERIOD_MS;
|
||||
vTaskDelay( xDelay );
|
||||
}
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("CCamera::CaptureToBasisImage - After LightOn");
|
||||
#endif
|
||||
|
||||
camera_fb_t * fb = esp_camera_fb_get();
|
||||
if (!fb) {
|
||||
ESP_LOGE(TAGCAMERACLASS, "Camera Capture Failed");
|
||||
LEDOnOff(false);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
int _size = fb->len;
|
||||
zwischenspeicher = (uint8_t*) malloc(_size);
|
||||
for (int i = 0; i < _size; ++i)
|
||||
*(zwischenspeicher + i) = *(fb->buf + i);
|
||||
esp_camera_fb_return(fb);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("CCamera::CaptureToBasisImage - After fb_get");
|
||||
#endif
|
||||
|
||||
LEDOnOff(false);
|
||||
|
||||
if (delay > 0)
|
||||
LightOnOff(false);
|
||||
|
||||
// TickType_t xDelay = 1000 / portTICK_PERIOD_MS;
|
||||
// vTaskDelay( xDelay ); // wait for power to recover
|
||||
|
||||
uint8_t * buf = NULL;
|
||||
|
||||
CImageBasis _zwImage;
|
||||
_zwImage.LoadFromMemory(zwischenspeicher, _size);
|
||||
free(zwischenspeicher);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("CCamera::CaptureToBasisImage - After LoadFromMemory");
|
||||
#endif
|
||||
|
||||
stbi_uc* p_target;
|
||||
stbi_uc* p_source;
|
||||
int channels = 3;
|
||||
int width = image_width;
|
||||
int height = image_height;
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
std::string _zw = "Targetimage: " + std::to_string((int) _Image->rgb_image) + " Size: " + std::to_string(_Image->width) + ", " + std::to_string(_Image->height);
|
||||
_zw = _zw + " _zwImage: " + std::to_string((int) _zwImage.rgb_image) + " Size: " + std::to_string(_zwImage.width) + ", " + std::to_string(_zwImage.height);
|
||||
LogFile.WriteToFile(_zw);
|
||||
#endif
|
||||
|
||||
for (int x = 0; x < width; ++x)
|
||||
for (int y = 0; y < height; ++y)
|
||||
{
|
||||
p_target = _Image->rgb_image + (channels * (y * width + x));
|
||||
p_source = _zwImage.rgb_image + (channels * (y * width + x));
|
||||
p_target[0] = p_source[0];
|
||||
p_target[1] = p_source[1];
|
||||
p_target[2] = p_source[2];
|
||||
}
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("CCamera::CaptureToBasisImage - After Copy To Target");
|
||||
#endif
|
||||
|
||||
free(buf);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("CCamera::CaptureToBasisImage - Done");
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
esp_err_t CCamera::CaptureToFile(std::string nm, int delay)
|
||||
{
|
||||
// nm = "/sdcard/josef_zw.bmp";
|
||||
string ftype;
|
||||
|
||||
LEDOnOff(true); // Abgeschaltet, um Strom zu sparen !!!!!!
|
||||
|
||||
if (delay > 0)
|
||||
{
|
||||
LightOnOff(true);
|
||||
@@ -217,14 +293,26 @@ esp_err_t CCamera::CaptureToFile(std::string nm, int delay)
|
||||
camera_fb_t * fb = esp_camera_fb_get();
|
||||
if (!fb) {
|
||||
ESP_LOGE(TAGCAMERACLASS, "Camera Capture Failed");
|
||||
LEDOnOff(false);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
LEDOnOff(false);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
printf("w %d, h %d, size %d\n", fb->width, fb->height, fb->len);
|
||||
#endif
|
||||
|
||||
nm = FormatFileName(nm);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
printf("Save Camera to : %s\n", nm.c_str());
|
||||
#endif
|
||||
|
||||
ftype = toUpper(getFileType(nm));
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
printf("Filetype: %s\n", ftype.c_str());
|
||||
#endif
|
||||
|
||||
uint8_t * buf = NULL;
|
||||
size_t buf_len = 0;
|
||||
@@ -249,7 +337,7 @@ esp_err_t CCamera::CaptureToFile(std::string nm, int delay)
|
||||
}
|
||||
}
|
||||
|
||||
FILE * fp = fopen(nm.c_str(), "wb");
|
||||
FILE * fp = OpenFileAndWait(nm.c_str(), "wb");
|
||||
if (fp == NULL) /* If an error occurs during the file creation */
|
||||
{
|
||||
fprintf(stderr, "fopen() failed for '%s'\n", nm.c_str());
|
||||
@@ -280,15 +368,29 @@ esp_err_t CCamera::CaptureToHTTP(httpd_req_t *req, int delay)
|
||||
size_t fb_len = 0;
|
||||
int64_t fr_start = esp_timer_get_time();
|
||||
|
||||
|
||||
LEDOnOff(true);
|
||||
|
||||
if (delay > 0)
|
||||
{
|
||||
LightOnOff(true);
|
||||
const TickType_t xDelay = delay / portTICK_PERIOD_MS;
|
||||
vTaskDelay( xDelay );
|
||||
}
|
||||
|
||||
|
||||
fb = esp_camera_fb_get();
|
||||
if (!fb) {
|
||||
ESP_LOGE(TAGCAMERACLASS, "Camera capture failed");
|
||||
httpd_resp_send_500(req);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
LEDOnOff(false);
|
||||
|
||||
res = httpd_resp_set_type(req, "image/jpeg");
|
||||
if(res == ESP_OK){
|
||||
res = httpd_resp_set_hdr(req, "Content-Disposition", "inline; filename=capture.jpg");
|
||||
res = httpd_resp_set_hdr(req, "Content-Disposition", "inline; filename=raw.jpg");
|
||||
}
|
||||
|
||||
if(res == ESP_OK){
|
||||
@@ -306,6 +408,12 @@ esp_err_t CCamera::CaptureToHTTP(httpd_req_t *req, int delay)
|
||||
int64_t fr_end = esp_timer_get_time();
|
||||
|
||||
ESP_LOGI(TAGCAMERACLASS, "JPG: %uKB %ums", (uint32_t)(fb_len/1024), (uint32_t)((fr_end - fr_start)/1000));
|
||||
|
||||
if (delay > 0)
|
||||
{
|
||||
LightOnOff(false);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -322,6 +430,20 @@ void CCamera::LightOnOff(bool status)
|
||||
gpio_set_level(FLASH_GPIO, 0);
|
||||
}
|
||||
|
||||
void CCamera::LEDOnOff(bool status)
|
||||
{
|
||||
// Init the GPIO
|
||||
gpio_pad_select_gpio(BLINK_GPIO);
|
||||
/* Set the GPIO as a push/pull output */
|
||||
gpio_set_direction(BLINK_GPIO, GPIO_MODE_OUTPUT);
|
||||
|
||||
if (!status)
|
||||
gpio_set_level(BLINK_GPIO, 1);
|
||||
else
|
||||
gpio_set_level(BLINK_GPIO, 0);
|
||||
}
|
||||
|
||||
|
||||
void CCamera::GetCameraParameter(httpd_req_t *req, int &qual, framesize_t &resol)
|
||||
{
|
||||
char _query[100];
|
||||
@@ -337,7 +459,9 @@ void CCamera::GetCameraParameter(httpd_req_t *req, int &qual, framesize_t &resol
|
||||
printf("Query: "); printf(_query); printf("\n");
|
||||
if (httpd_query_key_value(_query, "size", _size, 10) == ESP_OK)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
printf("Size: "); printf(_size); printf("\n");
|
||||
#endif
|
||||
if (strcmp(_size, "QVGA") == 0)
|
||||
resol = FRAMESIZE_QVGA; // 320x240
|
||||
if (strcmp(_size, "VGA") == 0)
|
||||
@@ -349,11 +473,13 @@ void CCamera::GetCameraParameter(httpd_req_t *req, int &qual, framesize_t &resol
|
||||
if (strcmp(_size, "SXGA") == 0)
|
||||
resol = FRAMESIZE_SXGA; // 1280x1024
|
||||
if (strcmp(_size, "UXGA") == 0)
|
||||
resol = FRAMESIZE_UXGA; // 1600x1200
|
||||
resol = FRAMESIZE_UXGA; // 1600x1200
|
||||
}
|
||||
if (httpd_query_key_value(_query, "quality", _qual, 10) == ESP_OK)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
printf("Quality: "); printf(_qual); printf("\n");
|
||||
#endif
|
||||
qual = atoi(_qual);
|
||||
|
||||
if (qual > 63)
|
||||
@@ -384,13 +510,13 @@ framesize_t CCamera::TextToFramesize(const char * _size)
|
||||
|
||||
CCamera::CCamera()
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
printf("CreateClassCamera\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
esp_err_t CCamera::InitCam()
|
||||
{
|
||||
printf("Init Flash\n");
|
||||
//power up the camera if PWDN pin is defined
|
||||
if(CAM_PIN_PWDN != -1){
|
||||
// Init the GPIO
|
||||
gpio_pad_select_gpio(CAM_PIN_PWDN);
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "esp_camera.h"
|
||||
#include <string>
|
||||
#include <esp_http_server.h>
|
||||
#include "CImageBasis.h"
|
||||
|
||||
|
||||
#define CAMERA_MODEL_AI_THINKER
|
||||
@@ -24,23 +25,24 @@ class CCamera {
|
||||
framesize_t ActualResolution;
|
||||
|
||||
public:
|
||||
int image_height, image_width;
|
||||
|
||||
CCamera();
|
||||
esp_err_t InitCam();
|
||||
|
||||
void LightOnOff(bool status);
|
||||
void LEDOnOff(bool status);
|
||||
esp_err_t CaptureToHTTP(httpd_req_t *req, int delay = 0);
|
||||
void SetQualitySize(int qual, framesize_t resol);
|
||||
void GetCameraParameter(httpd_req_t *req, int &qual, framesize_t &resol);
|
||||
|
||||
framesize_t TextToFramesize(const char * text);
|
||||
|
||||
|
||||
esp_err_t CaptureToFile(std::string nm, int delay = 0);
|
||||
|
||||
esp_err_t CaptureToBasisImage(CImageBasis *_Image, int delay = 0);
|
||||
};
|
||||
|
||||
|
||||
extern CCamera Camera;
|
||||
|
||||
|
||||
#endif
|
||||
@@ -11,6 +11,9 @@
|
||||
#define SCRATCH_BUFSIZE2 8192
|
||||
char scratch2[SCRATCH_BUFSIZE2];
|
||||
|
||||
//#define DEBUG_DETAIL_ON
|
||||
|
||||
|
||||
|
||||
void PowerResetCamera(){
|
||||
ESP_LOGD(TAGPARTCAMERA, "Resetting camera by power down line");
|
||||
@@ -29,43 +32,72 @@ void PowerResetCamera(){
|
||||
|
||||
esp_err_t handler_lightOn(httpd_req_t *req)
|
||||
{
|
||||
LogFile.WriteToFile("handler_lightOn");
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_lightOn - Start");
|
||||
printf("handler_lightOn uri:\n"); printf(req->uri); printf("\n");
|
||||
#endif
|
||||
|
||||
Camera.LightOnOff(true);
|
||||
const char* resp_str = (const char*) req->user_ctx;
|
||||
httpd_resp_send(req, resp_str, strlen(resp_str));
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_lightOn - Done");
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
};
|
||||
|
||||
esp_err_t handler_lightOff(httpd_req_t *req)
|
||||
{
|
||||
LogFile.WriteToFile("handler_lightOff");
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_lightOff - Start");
|
||||
printf("handler_lightOff uri:\n"); printf(req->uri); printf("\n");
|
||||
#endif
|
||||
Camera.LightOnOff(false);
|
||||
const char* resp_str = (const char*) req->user_ctx;
|
||||
httpd_resp_send(req, resp_str, strlen(resp_str));
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_lightOff - Done");
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
};
|
||||
|
||||
esp_err_t handler_capture(httpd_req_t *req)
|
||||
{
|
||||
LogFile.WriteToFile("handler_capture");
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_capture - Start");
|
||||
#endif
|
||||
|
||||
int quality;
|
||||
framesize_t res;
|
||||
|
||||
Camera.GetCameraParameter(req, quality, res);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
printf("Size: %d", res); printf(" Quality: %d\n", quality);
|
||||
#endif
|
||||
|
||||
Camera.SetQualitySize(quality, res);
|
||||
|
||||
esp_err_t ressult;
|
||||
ressult = Camera.CaptureToHTTP(req);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_capture - Done");
|
||||
#endif
|
||||
|
||||
return ressult;
|
||||
};
|
||||
|
||||
|
||||
esp_err_t handler_capture_with_ligth(httpd_req_t *req)
|
||||
{
|
||||
LogFile.WriteToFile("handler_capture_with_ligth");
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_capture_with_ligth - Start");
|
||||
#endif
|
||||
char _query[100];
|
||||
char _delay[10];
|
||||
|
||||
@@ -78,7 +110,9 @@ esp_err_t handler_capture_with_ligth(httpd_req_t *req)
|
||||
printf("Query: "); printf(_query); printf("\n");
|
||||
if (httpd_query_key_value(_query, "delay", _delay, 10) == ESP_OK)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
printf("Delay: "); printf(_delay); printf("\n");
|
||||
#endif
|
||||
delay = atoi(_delay);
|
||||
|
||||
if (delay < 0)
|
||||
@@ -87,9 +121,12 @@ esp_err_t handler_capture_with_ligth(httpd_req_t *req)
|
||||
};
|
||||
|
||||
Camera.GetCameraParameter(req, quality, res);
|
||||
printf("Size: %d", res); printf(" Quality: %d\n", quality);
|
||||
Camera.SetQualitySize(quality, res);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
printf("Size: %d", res); printf(" Quality: %d\n", quality);
|
||||
#endif
|
||||
|
||||
Camera.SetQualitySize(quality, res);
|
||||
Camera.LightOnOff(true);
|
||||
const TickType_t xDelay = delay / portTICK_PERIOD_MS;
|
||||
vTaskDelay( xDelay );
|
||||
@@ -99,6 +136,10 @@ esp_err_t handler_capture_with_ligth(httpd_req_t *req)
|
||||
|
||||
Camera.LightOnOff(false);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_capture_with_ligth - Done");
|
||||
#endif
|
||||
|
||||
return ressult;
|
||||
};
|
||||
|
||||
@@ -106,7 +147,10 @@ esp_err_t handler_capture_with_ligth(httpd_req_t *req)
|
||||
|
||||
esp_err_t handler_capture_save_to_file(httpd_req_t *req)
|
||||
{
|
||||
LogFile.WriteToFile("handler_capture_save_to_file");
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_capture_save_to_file - Start");
|
||||
#endif
|
||||
|
||||
char _query[100];
|
||||
char _delay[10];
|
||||
int delay = 0;
|
||||
@@ -123,14 +167,18 @@ esp_err_t handler_capture_save_to_file(httpd_req_t *req)
|
||||
if (httpd_query_key_value(_query, "filename", filename, 100) == ESP_OK)
|
||||
{
|
||||
fn.append(filename);
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
printf("Filename: "); printf(fn.c_str()); printf("\n");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
fn.append("noname.jpg");
|
||||
|
||||
if (httpd_query_key_value(_query, "delay", _delay, 10) == ESP_OK)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
printf("Delay: "); printf(_delay); printf("\n");
|
||||
#endif
|
||||
delay = atoi(_delay);
|
||||
|
||||
if (delay < 0)
|
||||
@@ -142,7 +190,9 @@ esp_err_t handler_capture_save_to_file(httpd_req_t *req)
|
||||
fn.append("noname.jpg");
|
||||
|
||||
Camera.GetCameraParameter(req, quality, res);
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
printf("Size: %d", res); printf(" Quality: %d\n", quality);
|
||||
#endif
|
||||
Camera.SetQualitySize(quality, res);
|
||||
|
||||
esp_err_t ressult;
|
||||
@@ -151,6 +201,10 @@ esp_err_t handler_capture_save_to_file(httpd_req_t *req)
|
||||
const char* resp_str = (const char*) fn.c_str();
|
||||
httpd_resp_send(req, resp_str, strlen(resp_str));
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_capture_save_to_file - Done");
|
||||
#endif
|
||||
|
||||
return ressult;
|
||||
};
|
||||
|
||||
@@ -158,7 +212,9 @@ esp_err_t handler_capture_save_to_file(httpd_req_t *req)
|
||||
|
||||
void register_server_camera_uri(httpd_handle_t server)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGI(TAGPARTCAMERA, "server_part_camera - Registering URI handlers");
|
||||
#endif
|
||||
|
||||
httpd_uri_t camuri = { };
|
||||
camuri.method = HTTP_GET;
|
||||
|
||||
@@ -65,21 +65,6 @@ static esp_err_t index_html_get_handler(httpd_req_t *req)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/* Handler to respond with an icon file embedded in flash.
|
||||
* Browsers expect to GET website icon at URI /favicon.ico.
|
||||
* This can be overridden by uploading file with same name */
|
||||
static esp_err_t favicon_get_handler(httpd_req_t *req)
|
||||
{
|
||||
extern const unsigned char favicon_ico_start[] asm("_binary_favicon_ico_start");
|
||||
extern const unsigned char favicon_ico_end[] asm("_binary_favicon_ico_end");
|
||||
const size_t favicon_ico_size = (favicon_ico_end - favicon_ico_start);
|
||||
httpd_resp_set_type(req, "image/x-icon");
|
||||
httpd_resp_send(req, (const char *)favicon_ico_start, favicon_ico_size);
|
||||
/* Respond with an empty chunk to signal HTTP response completion */
|
||||
httpd_resp_send_chunk(req, NULL, 0);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/* Send HTTP response with a run-time generated html consisting of
|
||||
* a list of all files and folders under the requested path.
|
||||
* In case of SPIFFS this returns empty list when path is any
|
||||
@@ -121,7 +106,7 @@ static esp_err_t http_resp_dir_html(httpd_req_t *req, const char *dirpath, const
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
if (!readonly) {
|
||||
FILE *fd = fopen("/sdcard/html/upload_script.html", "r");
|
||||
FILE *fd = OpenFileAndWait("/sdcard/html/upload_script.html", "r");
|
||||
char *chunk = ((struct file_server_data *)req->user_ctx)->scratch;
|
||||
size_t chunksize;
|
||||
do {
|
||||
@@ -231,7 +216,7 @@ static esp_err_t logfileact_get_handler(httpd_req_t *req)
|
||||
std::string currentfilename = LogFile.GetCurrentFileName();
|
||||
|
||||
|
||||
fd = fopen(currentfilename.c_str(), "r");
|
||||
fd = OpenFileAndWait(currentfilename.c_str(), "r");
|
||||
if (!fd) {
|
||||
ESP_LOGE(TAG, "Failed to read existing file : %s", filepath);
|
||||
/* Respond with 500 Internal Server Error */
|
||||
@@ -337,7 +322,7 @@ static esp_err_t download_get_handler(httpd_req_t *req)
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
fd = fopen(filepath, "r");
|
||||
fd = OpenFileAndWait(filepath, "r");
|
||||
if (!fd) {
|
||||
ESP_LOGE(TAG, "Failed to read existing file : %s", filepath);
|
||||
/* Respond with 500 Internal Server Error */
|
||||
@@ -424,7 +409,7 @@ static esp_err_t upload_post_handler(httpd_req_t *req)
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
fd = fopen(filepath, "w");
|
||||
fd = OpenFileAndWait(filepath, "w");
|
||||
if (!fd) {
|
||||
ESP_LOGE(TAG, "Failed to create file : %s", filepath);
|
||||
/* Respond with 500 Internal Server Error */
|
||||
@@ -710,7 +695,7 @@ void unzip(std::string _in_zip_file, std::string _target_directory){
|
||||
zw = std::string(archive_filename);
|
||||
zw = _target_directory + zw;
|
||||
printf("Filename to extract: %s", zw.c_str());
|
||||
FILE* fpTargetFile = fopen(zw.c_str(), "wb");
|
||||
FILE* fpTargetFile = OpenFileAndWait(zw.c_str(), "wb");
|
||||
fwrite(p, 1, (uint)uncomp_size, fpTargetFile);
|
||||
fclose(fpTargetFile);
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "Helper.h"
|
||||
|
||||
#include "esp_http_server.h"
|
||||
|
||||
|
||||
@@ -23,9 +25,9 @@ char scratch[SCRATCH_BUFSIZE];
|
||||
(strcasecmp(&filename[strlen(filename) - sizeof(ext) + 1], ext) == 0)
|
||||
|
||||
|
||||
esp_err_t send_file(httpd_req_t *req, std::string filename, struct stat * file_stat)
|
||||
esp_err_t send_file(httpd_req_t *req, std::string filename)
|
||||
{
|
||||
FILE *fd = fopen(filename.c_str(), "r");
|
||||
FILE *fd = OpenFileAndWait(filename.c_str(), "r");
|
||||
if (!fd) {
|
||||
ESP_LOGE(TAG, "Failed to read existing file : %s", filename.c_str());
|
||||
/* Respond with 500 Internal Server Error */
|
||||
@@ -33,7 +35,7 @@ esp_err_t send_file(httpd_req_t *req, std::string filename, struct stat * file_
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Sending file : %s (%ld bytes)...", filename.c_str(), file_stat->st_size);
|
||||
ESP_LOGI(TAG, "Sending file : %s ...", filename.c_str());
|
||||
set_content_type_from_file(req, filename.c_str());
|
||||
|
||||
/* Retrieve the pointer to scratch buffer for temporary storage */
|
||||
@@ -65,6 +67,7 @@ esp_err_t send_file(httpd_req_t *req, std::string filename, struct stat * file_
|
||||
|
||||
|
||||
|
||||
|
||||
/* Copies the full path into destination buffer and returns
|
||||
* pointer to path (skipping the preceding base path) */
|
||||
const char* get_path_from_uri(char *dest, const char *base_path, const char *uri, size_t destsize)
|
||||
|
||||
@@ -5,6 +5,6 @@
|
||||
|
||||
const char* get_path_from_uri(char *dest, const char *base_path, const char *uri, size_t destsize);
|
||||
|
||||
esp_err_t send_file(httpd_req_t *req, std::string filename, struct stat * file_stat);
|
||||
esp_err_t send_file(httpd_req_t *req, std::string filename);
|
||||
|
||||
esp_err_t set_content_type_from_file(httpd_req_t *req, const char *filename);
|
||||
@@ -31,6 +31,10 @@
|
||||
|
||||
#include "ClassLogFile.h"
|
||||
|
||||
#include "Helper.h"
|
||||
|
||||
|
||||
// #define DEBUG_DETAIL_ON
|
||||
|
||||
|
||||
#define BUFFSIZE 1024
|
||||
@@ -89,7 +93,7 @@ static bool ota_example_task(std::string fn)
|
||||
|
||||
int data_read;
|
||||
|
||||
FILE* f = fopen(fn.c_str(), "rb"); // vorher nur "r"
|
||||
FILE* f = OpenFileAndWait(fn.c_str(), "rb"); // vorher nur "r"
|
||||
data_read = fread(ota_write_data, 1, BUFFSIZE, f);
|
||||
|
||||
while (data_read > 0) {
|
||||
@@ -301,6 +305,10 @@ void CheckOTAUpdate(void)
|
||||
|
||||
esp_err_t handler_ota_update(httpd_req_t *req)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_ota_update - Start");
|
||||
#endif
|
||||
|
||||
LogFile.WriteToFile("handler_ota_update");
|
||||
char _query[200];
|
||||
char _filename[30];
|
||||
@@ -377,6 +385,10 @@ esp_err_t handler_ota_update(httpd_req_t *req)
|
||||
|
||||
httpd_resp_send(req, resp_str, strlen(resp_str));
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_ota_update - Done");
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
};
|
||||
|
||||
@@ -412,6 +424,10 @@ void doReboot(){
|
||||
|
||||
esp_err_t handler_reboot(httpd_req_t *req)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_reboot - Start");
|
||||
#endif
|
||||
|
||||
LogFile.WriteToFile("handler_reboot");
|
||||
ESP_LOGI(TAGPARTOTA, "!!! System will restart within 5 sec!!!");
|
||||
const char* resp_str = "!!! System will restart within 5 sec!!!";
|
||||
@@ -419,6 +435,10 @@ esp_err_t handler_reboot(httpd_req_t *req)
|
||||
|
||||
doReboot();
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_reboot - Done");
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,3 +9,4 @@ static const char *TAGPARTOTA = "server_ota";
|
||||
void register_server_ota_sdcard_uri(httpd_handle_t server);
|
||||
void CheckOTAUpdate();
|
||||
void doReboot();
|
||||
|
||||
|
||||
@@ -2,6 +2,6 @@ FILE(GLOB_RECURSE app_sources ${CMAKE_CURRENT_SOURCE_DIR}/*.*)
|
||||
|
||||
idf_component_register(SRCS ${app_sources}
|
||||
INCLUDE_DIRS "."
|
||||
REQUIRES jomjol_tfliteclass jomjol_helper jomjol_controlcamera jomjol_mqtt jomjol_fileserver_ota)
|
||||
REQUIRES jomjol_tfliteclass jomjol_helper jomjol_controlcamera jomjol_mqtt jomjol_fileserver_ota jomjol_image_proc connect_wlan)
|
||||
|
||||
|
||||
|
||||
@@ -9,9 +9,12 @@
|
||||
void ClassFlow::SetInitialParameter(void)
|
||||
{
|
||||
ListFlowControll = NULL;
|
||||
previousElement = NULL;
|
||||
disabled = false;
|
||||
}
|
||||
|
||||
//std::vector<string> ClassFlow::ZerlegeZeile(std::string input, std::string delimiter);
|
||||
|
||||
|
||||
|
||||
std::vector<string> ClassFlow::ZerlegeZeile(std::string input, std::string delimiter)
|
||||
{
|
||||
@@ -37,16 +40,18 @@ std::vector<string> ClassFlow::ZerlegeZeile(std::string input, std::string delim
|
||||
|
||||
bool ClassFlow::isNewParagraph(string input)
|
||||
{
|
||||
if (input[0] == '[')
|
||||
if ((input[0] == '[') || ((input[0] == ';') && (input[1] == '[')))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ClassFlow::GetNextParagraph(FILE* pfile, string& aktparamgraph)
|
||||
{
|
||||
while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph));
|
||||
while (getNextLine(pfile, &aktparamgraph) && !isNewParagraph(aktparamgraph));
|
||||
|
||||
if (this->isNewParagraph(aktparamgraph))
|
||||
if (isNewParagraph(aktparamgraph))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@@ -55,7 +60,6 @@ bool ClassFlow::GetNextParagraph(FILE* pfile, string& aktparamgraph)
|
||||
ClassFlow::ClassFlow(void)
|
||||
{
|
||||
SetInitialParameter();
|
||||
ListFlowControll = NULL;
|
||||
}
|
||||
|
||||
ClassFlow::ClassFlow(std::vector<ClassFlow*> * lfc)
|
||||
@@ -64,6 +68,13 @@ ClassFlow::ClassFlow(std::vector<ClassFlow*> * lfc)
|
||||
ListFlowControll = lfc;
|
||||
}
|
||||
|
||||
ClassFlow::ClassFlow(std::vector<ClassFlow*> * lfc, ClassFlow *_prev)
|
||||
{
|
||||
SetInitialParameter();
|
||||
ListFlowControll = lfc;
|
||||
previousElement = _prev;
|
||||
}
|
||||
|
||||
bool ClassFlow::ReadParameter(FILE* pfile, string &aktparamgraph)
|
||||
{
|
||||
return false;
|
||||
@@ -100,7 +111,7 @@ bool ClassFlow::getNextLine(FILE* pfile, string *rt)
|
||||
}
|
||||
*rt = zw;
|
||||
*rt = trim(*rt);
|
||||
while (zw[0] == '#' || (rt->size() == 0)) // Kommentarzeilen und Leerzeilen überspringen
|
||||
while ((zw[0] == ';' || zw[0] == '#' || (rt->size() == 0)) && !(zw[1] == '[')) // Kommentarzeilen (; oder #) und Leerzeilen überspringen, es sei denn es ist ein neuer auskommentierter Paragraph
|
||||
{
|
||||
fgets(zw, 1024, pfile);
|
||||
printf("%s", zw);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "Helper.h"
|
||||
#include "CFindTemplate.h"
|
||||
#include "CImageBasis.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -16,7 +16,10 @@ using namespace std;
|
||||
struct HTMLInfo
|
||||
{
|
||||
float val;
|
||||
CImageBasis *image = NULL;
|
||||
CImageBasis *image_org = NULL;
|
||||
std::string filename;
|
||||
std::string filename_org;
|
||||
};
|
||||
|
||||
|
||||
@@ -24,18 +27,23 @@ class ClassFlow
|
||||
{
|
||||
protected:
|
||||
// std::vector<string> ZerlegeZeile(string input);
|
||||
std::vector<string> ZerlegeZeile(string input, string delimiter = " =, ");
|
||||
std::vector<string> ZerlegeZeile(string input, string delimiter = " =, \t");
|
||||
bool isNewParagraph(string input);
|
||||
bool GetNextParagraph(FILE* pfile, string& aktparamgraph);
|
||||
bool getNextLine(FILE* pfile, string* rt);
|
||||
|
||||
std::vector<ClassFlow*>* ListFlowControll;
|
||||
ClassFlow *previousElement;
|
||||
|
||||
virtual void SetInitialParameter(void);
|
||||
|
||||
bool disabled;
|
||||
|
||||
public:
|
||||
ClassFlow(void);
|
||||
ClassFlow(std::vector<ClassFlow*> * lfc);
|
||||
ClassFlow(std::vector<ClassFlow*> * lfc, ClassFlow *_prev);
|
||||
|
||||
virtual bool ReadParameter(FILE* pfile, string &aktparamgraph);
|
||||
virtual bool doFlow(string time);
|
||||
virtual string getHTMLSingleStep(string host);
|
||||
|
||||
@@ -1,32 +1,64 @@
|
||||
#include "ClassFlowAlignment.h"
|
||||
#include "ClassFlowMakeImage.h"
|
||||
#include "ClassFlow.h"
|
||||
|
||||
#include "CRotateImage.h"
|
||||
|
||||
|
||||
#include "ClassLogFile.h"
|
||||
|
||||
ClassFlowAlignment::ClassFlowAlignment()
|
||||
|
||||
|
||||
bool AlignmentExtendedDebugging = true;
|
||||
|
||||
// #define DEBUG_DETAIL_ON
|
||||
|
||||
|
||||
void ClassFlowAlignment::SetInitialParameter(void)
|
||||
{
|
||||
initalrotate = 0;
|
||||
anz_ref = 0;
|
||||
suchex = 40;
|
||||
suchey = 40;
|
||||
initialmirror = false;
|
||||
SaveAllFiles = false;
|
||||
namerawimage = "/sdcard/img_tmp/raw.jpg";
|
||||
FileStoreRefAlignment = "/sdcard/config/align.txt";
|
||||
ListFlowControll = NULL;
|
||||
AlignAndCutImage = NULL;
|
||||
ImageBasis = NULL;
|
||||
ImageTMP = NULL;
|
||||
previousElement = NULL;
|
||||
disabled = false;
|
||||
SAD_criteria = 0.05;
|
||||
}
|
||||
|
||||
ClassFlowAlignment::ClassFlowAlignment(std::vector<ClassFlow*>* lfc)
|
||||
{
|
||||
initalrotate = 0;
|
||||
anz_ref = 0;
|
||||
suchex = 40;
|
||||
suchey = 40;
|
||||
initialmirror = false;
|
||||
namerawimage = "/sdcard/img_tmp/raw.jpg";
|
||||
SetInitialParameter();
|
||||
ListFlowControll = lfc;
|
||||
|
||||
for (int i = 0; i < ListFlowControll->size(); ++i)
|
||||
{
|
||||
if (((*ListFlowControll)[i])->name().compare("ClassFlowMakeImage") == 0)
|
||||
{
|
||||
ImageBasis = ((ClassFlowMakeImage*) (*ListFlowControll)[i])->rawImage;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ImageBasis) // die Funktion Bilder aufnehmen existiert nicht --> muss erst erzeugt werden NUR ZU TESTZWECKEN
|
||||
{
|
||||
if (AlignmentExtendedDebugging) printf("CImageBasis musste erzeugt werden\n");
|
||||
ImageBasis = new CImageBasis(namerawimage);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool ClassFlowAlignment::ReadParameter(FILE* pfile, string& aktparamgraph)
|
||||
{
|
||||
std::vector<string> zerlegt;
|
||||
int suchex = 40;
|
||||
int suchey = 40;
|
||||
int alg_algo = 0;
|
||||
|
||||
|
||||
aktparamgraph = trim(aktparamgraph);
|
||||
|
||||
@@ -39,32 +71,64 @@ bool ClassFlowAlignment::ReadParameter(FILE* pfile, string& aktparamgraph)
|
||||
|
||||
while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph))
|
||||
{
|
||||
zerlegt = this->ZerlegeZeile(aktparamgraph);
|
||||
if ((zerlegt[0] == "InitialMirror") && (zerlegt.size() > 1))
|
||||
zerlegt = ZerlegeZeile(aktparamgraph);
|
||||
if ((toUpper(zerlegt[0]) == "INITIALMIRROR") && (zerlegt.size() > 1))
|
||||
{
|
||||
if (toUpper(zerlegt[1]) == "TRUE")
|
||||
initialmirror = true;
|
||||
}
|
||||
if (((zerlegt[0] == "InitalRotate") || (zerlegt[0] == "InitialRotate")) && (zerlegt.size() > 1))
|
||||
if (((toUpper(zerlegt[0]) == "INITALROTATE") || (toUpper(zerlegt[0]) == "INITIALROTATE")) && (zerlegt.size() > 1))
|
||||
{
|
||||
this->initalrotate = std::stod(zerlegt[1]);
|
||||
}
|
||||
if ((zerlegt[0] == "SearchFieldX") && (zerlegt.size() > 1))
|
||||
if ((toUpper(zerlegt[0]) == "SEARCHFIELDX") && (zerlegt.size() > 1))
|
||||
{
|
||||
this->suchex = std::stod(zerlegt[1]);
|
||||
suchex = std::stod(zerlegt[1]);
|
||||
}
|
||||
if ((zerlegt[0] == "SearchFieldY") && (zerlegt.size() > 1))
|
||||
if ((toUpper(zerlegt[0]) == "SEARCHFIELDY") && (zerlegt.size() > 1))
|
||||
{
|
||||
this->suchey = std::stod(zerlegt[1]);
|
||||
suchey = std::stod(zerlegt[1]);
|
||||
}
|
||||
if ((zerlegt.size() == 3) && (anz_ref < 2))
|
||||
{
|
||||
this->reffilename[anz_ref] = FormatFileName("/sdcard" + zerlegt[0]);
|
||||
this->ref_x[anz_ref] = std::stod(zerlegt[1]);
|
||||
this->ref_y[anz_ref] = std::stod(zerlegt[2]);
|
||||
References[anz_ref].image_file = FormatFileName("/sdcard" + zerlegt[0]);
|
||||
References[anz_ref].target_x = std::stod(zerlegt[1]);
|
||||
References[anz_ref].target_y = std::stod(zerlegt[2]);
|
||||
anz_ref++;
|
||||
}
|
||||
|
||||
if ((toUpper(zerlegt[0]) == "SAVEALLFILES") && (zerlegt.size() > 1))
|
||||
{
|
||||
if (toUpper(zerlegt[1]) == "TRUE")
|
||||
SaveAllFiles = true;
|
||||
}
|
||||
if ((toUpper(zerlegt[0]) == "ALIGNMENTALGO") && (zerlegt.size() > 1))
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
std::string zw2 = "Alignmentmodus gewählt: " + zerlegt[1];
|
||||
LogFile.WriteToFile(zw2);
|
||||
#endif
|
||||
if (toUpper(zerlegt[1]) == "HIGHACCURACY")
|
||||
alg_algo = 1;
|
||||
if (toUpper(zerlegt[1]) == "FAST")
|
||||
alg_algo = 2;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < anz_ref; ++i)
|
||||
{
|
||||
References[i].search_x = suchex;
|
||||
References[i].search_y = suchey;
|
||||
References[i].fastalg_SAD_criteria = SAD_criteria;
|
||||
References[i].alignment_algo = alg_algo;
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
std::string zw2 = "Alignmentmodus geschrieben: " + std::to_string(alg_algo);
|
||||
LogFile.WriteToFile(zw2);
|
||||
#endif
|
||||
}
|
||||
|
||||
LoadReferenceAlignmentValues();
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
@@ -82,70 +146,178 @@ string ClassFlowAlignment::getHTMLSingleStep(string host)
|
||||
|
||||
bool ClassFlowAlignment::doFlow(string time)
|
||||
{
|
||||
string input = namerawimage;
|
||||
string output = "/sdcard/img_tmp/rot.jpg";
|
||||
string output3 = "/sdcard/img_tmp/rot_roi.jpg";
|
||||
string output2 = "/sdcard/img_tmp/alg.jpg";
|
||||
string output4 = "/sdcard/img_tmp/alg_roi.jpg";
|
||||
string output1 = "/sdcard/img_tmp/mirror.jpg";
|
||||
if (!ImageTMP)
|
||||
ImageTMP = new CImageBasis(ImageBasis, 5);
|
||||
|
||||
input = FormatFileName(input);
|
||||
output = FormatFileName(output);
|
||||
output2 = FormatFileName(output2);
|
||||
if (AlignAndCutImage)
|
||||
delete AlignAndCutImage;
|
||||
AlignAndCutImage = new CAlignAndCutImage(ImageBasis, ImageTMP);
|
||||
|
||||
CRotateImage rt(AlignAndCutImage, ImageTMP);
|
||||
|
||||
if (initialmirror){
|
||||
CRotate *rt;
|
||||
rt = new CRotate(input);
|
||||
if (!rt->ImageOkay()){
|
||||
LogFile.WriteToFile("ClassFlowAlignment::doFlow CRotate Inital Mirror raw.jpg not okay!");
|
||||
delete rt;
|
||||
return false;
|
||||
}
|
||||
printf("do mirror\n");
|
||||
rt->Mirror();
|
||||
rt->SaveToFile(output1);
|
||||
input = output1;
|
||||
delete rt;
|
||||
rt.Mirror();
|
||||
if (SaveAllFiles) AlignAndCutImage->SaveToFile(FormatFileName("/sdcard/img_tmp/mirror.jpg"));
|
||||
}
|
||||
|
||||
|
||||
if (initalrotate != 0)
|
||||
{
|
||||
CRotate *rt = NULL;
|
||||
printf("Load rotationfile: %s\n", input.c_str());
|
||||
rt = new CRotate(input);
|
||||
if (!rt->ImageOkay()){
|
||||
LogFile.WriteToFile("ClassFlowAlignment::doFlow CRotate raw.jpg not okay!");
|
||||
delete rt;
|
||||
return false;
|
||||
}
|
||||
rt->Rotate(this->initalrotate);
|
||||
rt->SaveToFile(output);
|
||||
delete rt;
|
||||
rt.Rotate(initalrotate);
|
||||
if (SaveAllFiles) AlignAndCutImage->SaveToFile(FormatFileName("/sdcard/img_tmp/rot.jpg"));
|
||||
}
|
||||
else
|
||||
|
||||
if (!AlignAndCutImage->Align(&References[0], &References[1]))
|
||||
{
|
||||
CopyFile(input, output);
|
||||
SaveReferenceAlignmentValues();
|
||||
}
|
||||
|
||||
CAlignAndCutImage *caic;
|
||||
caic = new CAlignAndCutImage(output);
|
||||
caic->Align(this->reffilename[0], this->ref_x[0], this->ref_y[0], this->reffilename[1], this->ref_x[1], this->ref_y[1], suchex, suchey, output3);
|
||||
caic->SaveToFile(output2);
|
||||
if (SaveAllFiles) AlignAndCutImage->SaveToFile(FormatFileName("/sdcard/img_tmp/alg.jpg"));
|
||||
|
||||
printf("Startwriting Output4:%s\n", output4.c_str());
|
||||
if (output4.length() > 0)
|
||||
if (SaveAllFiles)
|
||||
{
|
||||
caic->drawRect(ref_x[0], ref_y[0], caic->t0_dx, caic->t0_dy, 255, 0, 0, 2);
|
||||
caic->drawRect(ref_x[1], ref_y[1], caic->t1_dx, caic->t1_dy, 255, 0, 0, 2);
|
||||
caic->SaveToFile(output4);
|
||||
printf("Write output4: %s\n", output4.c_str());
|
||||
DrawRef(ImageTMP);
|
||||
ImageTMP->SaveToFile(FormatFileName("/sdcard/img_tmp/alg_roi.jpg"));
|
||||
}
|
||||
|
||||
delete caic;
|
||||
if (ImageTMP) // nuss gelöscht werden, um Speicherplatz für das Laden von tflite zu haben
|
||||
{
|
||||
delete ImageTMP;
|
||||
ImageTMP = NULL;
|
||||
}
|
||||
|
||||
LoadReferenceAlignmentValues();
|
||||
|
||||
// Align mit Templates
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ClassFlowAlignment::SaveReferenceAlignmentValues()
|
||||
{
|
||||
FILE* pFile;
|
||||
std::string zwtime, zwvalue;
|
||||
|
||||
pFile = fopen(FileStoreRefAlignment.c_str(), "w");
|
||||
|
||||
if (strlen(zwtime.c_str()) == 0)
|
||||
{
|
||||
time_t rawtime;
|
||||
struct tm* timeinfo;
|
||||
char buffer[80];
|
||||
|
||||
time(&rawtime);
|
||||
timeinfo = localtime(&rawtime);
|
||||
|
||||
strftime(buffer, 80, "%Y-%m-%d_%H-%M-%S", timeinfo);
|
||||
zwtime = std::string(buffer);
|
||||
}
|
||||
|
||||
fputs(zwtime.c_str(), pFile);
|
||||
fputs("\n", pFile);
|
||||
|
||||
zwvalue = std::to_string(References[0].fastalg_x) + "\t" + std::to_string(References[0].fastalg_y);
|
||||
zwvalue = zwvalue + "\t" +std::to_string(References[0].fastalg_SAD)+ "\t" +std::to_string(References[0].fastalg_min);
|
||||
zwvalue = zwvalue + "\t" +std::to_string(References[0].fastalg_max)+ "\t" +std::to_string(References[0].fastalg_avg);
|
||||
fputs(zwvalue.c_str(), pFile);
|
||||
fputs("\n", pFile);
|
||||
|
||||
zwvalue = std::to_string(References[1].fastalg_x) + "\t" + std::to_string(References[1].fastalg_y);
|
||||
zwvalue = zwvalue + "\t" +std::to_string(References[1].fastalg_SAD)+ "\t" +std::to_string(References[1].fastalg_min);
|
||||
zwvalue = zwvalue + "\t" +std::to_string(References[1].fastalg_max)+ "\t" +std::to_string(References[1].fastalg_avg);
|
||||
fputs(zwvalue.c_str(), pFile);
|
||||
fputs("\n", pFile);
|
||||
|
||||
fclose(pFile);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool ClassFlowAlignment::LoadReferenceAlignmentValues(void)
|
||||
{
|
||||
FILE* pFile;
|
||||
char zw[1024];
|
||||
string zwvalue;
|
||||
std::vector<string> zerlegt;
|
||||
|
||||
|
||||
// LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", "LoadReferenceAlignmentValues01");
|
||||
|
||||
pFile = fopen(FileStoreRefAlignment.c_str(), "r");
|
||||
if (pFile == NULL)
|
||||
return false;
|
||||
|
||||
// LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", "LoadReferenceAlignmentValues01");
|
||||
|
||||
fgets(zw, 1024, pFile);
|
||||
printf("%s", zw);
|
||||
|
||||
// zwvalue = "LoadReferenceAlignmentValues Time: " + std::string(zw);
|
||||
|
||||
// LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", zwvalue);
|
||||
|
||||
// LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", "LoadReferenceAlignmentValues02");
|
||||
|
||||
fgets(zw, 1024, pFile);
|
||||
zerlegt = ZerlegeZeile(std::string(zw), " \t");
|
||||
if (zerlegt.size() < 6)
|
||||
{
|
||||
// LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", "Exit 01");
|
||||
fclose(pFile);
|
||||
return false;
|
||||
}
|
||||
|
||||
// LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", "LoadReferenceAlignmentValues03");
|
||||
|
||||
References[0].fastalg_x = stoi(zerlegt[0]);
|
||||
References[0].fastalg_y = stoi(zerlegt[1]);
|
||||
References[0].fastalg_SAD = stof(zerlegt[2]);
|
||||
References[0].fastalg_min = stoi(zerlegt[3]);
|
||||
References[0].fastalg_max = stoi(zerlegt[4]);
|
||||
References[0].fastalg_avg = stof(zerlegt[5]);
|
||||
|
||||
fgets(zw, 1024, pFile);
|
||||
zerlegt = ZerlegeZeile(std::string(zw));
|
||||
if (zerlegt.size() < 6)
|
||||
{
|
||||
// LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", "Exit 02");
|
||||
fclose(pFile);
|
||||
return false;
|
||||
}
|
||||
|
||||
// LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", "LoadReferenceAlignmentValues03");
|
||||
|
||||
References[1].fastalg_x = stoi(zerlegt[0]);
|
||||
References[1].fastalg_y = stoi(zerlegt[1]);
|
||||
References[1].fastalg_SAD = stof(zerlegt[2]);
|
||||
References[1].fastalg_min = stoi(zerlegt[3]);
|
||||
References[1].fastalg_max = stoi(zerlegt[4]);
|
||||
References[1].fastalg_avg = stof(zerlegt[5]);
|
||||
|
||||
fclose(pFile);
|
||||
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
std::string _zw = "\tLoadReferences[0]\tx,y:\t" + std::to_string(References[0].fastalg_x) + "\t" + std::to_string(References[0].fastalg_x);
|
||||
_zw = _zw + "\tSAD, min, max, avg:\t" + std::to_string(References[0].fastalg_SAD) + "\t" + std::to_string(References[0].fastalg_min);
|
||||
_zw = _zw + "\t" + std::to_string(References[0].fastalg_max) + "\t" + std::to_string(References[0].fastalg_avg);
|
||||
LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", _zw);
|
||||
_zw = "\tLoadReferences[1]\tx,y:\t" + std::to_string(References[1].fastalg_x) + "\t" + std::to_string(References[1].fastalg_x);
|
||||
_zw = _zw + "\tSAD, min, max, avg:\t" + std::to_string(References[1].fastalg_SAD) + "\t" + std::to_string(References[1].fastalg_min);
|
||||
_zw = _zw + "\t" + std::to_string(References[1].fastalg_max) + "\t" + std::to_string(References[1].fastalg_avg);
|
||||
LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", _zw);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ClassFlowAlignment::DrawRef(CImageBasis *_zw)
|
||||
{
|
||||
_zw->drawRect(References[0].target_x, References[0].target_y, References[0].width, References[0].height, 255, 0, 0, 2);
|
||||
_zw->drawRect(References[1].target_x, References[1].target_y, References[1].width, References[1].height, 255, 0, 0, 2);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
#include "ClassFlow.h"
|
||||
#include "Helper.h"
|
||||
#include "CAlignAndCutImage.h"
|
||||
#include "CFindTemplate.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
@@ -13,15 +15,27 @@ class ClassFlowAlignment :
|
||||
protected:
|
||||
float initalrotate;
|
||||
bool initialmirror;
|
||||
string reffilename[2];
|
||||
int ref_x[2], ref_y[2];
|
||||
RefInfo References[2];
|
||||
int anz_ref;
|
||||
int suchex, suchey;
|
||||
string namerawimage;
|
||||
bool SaveAllFiles;
|
||||
CAlignAndCutImage *AlignAndCutImage;
|
||||
std::string FileStoreRefAlignment;
|
||||
float SAD_criteria;
|
||||
|
||||
void SetInitialParameter(void);
|
||||
bool LoadReferenceAlignmentValues(void);
|
||||
void SaveReferenceAlignmentValues();
|
||||
|
||||
public:
|
||||
ClassFlowAlignment();
|
||||
CImageBasis *ImageBasis, *ImageTMP;
|
||||
|
||||
ClassFlowAlignment(std::vector<ClassFlow*>* lfc);
|
||||
|
||||
CAlignAndCutImage* GetAlignAndCutImage(){return AlignAndCutImage;};
|
||||
|
||||
void DrawRef(CImageBasis *_zw);
|
||||
|
||||
bool ReadParameter(FILE* pfile, string& aktparamgraph);
|
||||
bool doFlow(string time);
|
||||
string getHTMLSingleStep(string host);
|
||||
|
||||
@@ -16,32 +16,68 @@ static const char* TAG = "flow_analog";
|
||||
|
||||
bool debugdetailanalog = false;
|
||||
|
||||
ClassFlowAnalog::ClassFlowAnalog() : ClassFlowImage(TAG)
|
||||
void ClassFlowAnalog::SetInitialParameter(void)
|
||||
{
|
||||
string cnnmodelfile = "";
|
||||
modelxsize = 1;
|
||||
modelysize = 1;
|
||||
ListFlowControll = NULL;
|
||||
previousElement = NULL;
|
||||
SaveAllFiles = false;
|
||||
disabled = false;
|
||||
extendedResolution = false;
|
||||
}
|
||||
|
||||
ClassFlowAnalog::ClassFlowAnalog(std::vector<ClassFlow*>* lfc) : ClassFlowImage(lfc, TAG)
|
||||
{
|
||||
string cnnmodelfile = "";
|
||||
modelxsize = 1;
|
||||
modelysize = 1;
|
||||
SetInitialParameter();
|
||||
ListFlowControll = lfc;
|
||||
|
||||
for (int i = 0; i < ListFlowControll->size(); ++i)
|
||||
{
|
||||
if (((*ListFlowControll)[i])->name().compare("ClassFlowAlignment") == 0)
|
||||
{
|
||||
flowpostalignment = (ClassFlowAlignment*) (*ListFlowControll)[i];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
int ClassFlowAnalog::AnzahlROIs()
|
||||
{
|
||||
int zw = ROI.size();
|
||||
if (extendedResolution)
|
||||
zw++;
|
||||
|
||||
return zw;
|
||||
}
|
||||
|
||||
|
||||
string ClassFlowAnalog::getReadout()
|
||||
{
|
||||
int prev = -1;
|
||||
string result = "";
|
||||
for (int i = ROI.size() - 1; i >= 0; --i)
|
||||
if (ROI.size() == 0)
|
||||
return result;
|
||||
|
||||
|
||||
float zahl = ROI[ROI.size() - 1]->result;
|
||||
int ergebnis_nachkomma = ((int) floor(zahl * 10)) % 10;
|
||||
|
||||
int prev = -1;
|
||||
|
||||
prev = ZeigerEval(ROI[ROI.size() - 1]->result, prev);
|
||||
result = std::to_string(prev);
|
||||
|
||||
if (extendedResolution)
|
||||
result = result + std::to_string(ergebnis_nachkomma);
|
||||
|
||||
for (int i = ROI.size() - 2; i >= 0; --i)
|
||||
{
|
||||
prev = ZeigerEval(ROI[i]->result, prev);
|
||||
result = std::to_string(prev) + result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -80,9 +116,18 @@ bool ClassFlowAnalog::ReadParameter(FILE* pfile, string& aktparamgraph)
|
||||
return false;
|
||||
|
||||
|
||||
if (aktparamgraph.compare("[Analog]") != 0) // Paragraph passt nich zu MakeImage
|
||||
if ((aktparamgraph.compare("[Analog]") != 0) && (aktparamgraph.compare(";[Analog]") != 0)) // Paragraph passt nich zu MakeImage
|
||||
return false;
|
||||
|
||||
if (aktparamgraph[0] == ';')
|
||||
{
|
||||
disabled = true;
|
||||
while (getNextLine(pfile, &aktparamgraph) && !isNewParagraph(aktparamgraph));
|
||||
printf("[Analog] is disabled !!!\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph))
|
||||
{
|
||||
zerlegt = this->ZerlegeZeile(aktparamgraph);
|
||||
@@ -113,9 +158,30 @@ bool ClassFlowAnalog::ReadParameter(FILE* pfile, string& aktparamgraph)
|
||||
neuroi->deltax = std::stoi(zerlegt[3]);
|
||||
neuroi->deltay = std::stoi(zerlegt[4]);
|
||||
neuroi->result = -1;
|
||||
neuroi->image = NULL;
|
||||
neuroi->image_org = NULL;
|
||||
ROI.push_back(neuroi);
|
||||
}
|
||||
|
||||
if ((toUpper(zerlegt[0]) == "SAVEALLFILES") && (zerlegt.size() > 1))
|
||||
{
|
||||
if (toUpper(zerlegt[1]) == "TRUE")
|
||||
SaveAllFiles = true;
|
||||
}
|
||||
|
||||
if ((toUpper(zerlegt[0]) == "EXTENDEDRESOLUTION") && (zerlegt.size() > 1))
|
||||
{
|
||||
if (toUpper(zerlegt[1]) == "TRUE")
|
||||
extendedResolution = true;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < ROI.size(); ++i)
|
||||
{
|
||||
ROI[i]->image = new CImageBasis(modelxsize, modelysize, 3);
|
||||
ROI[i]->image_org = new CImageBasis(ROI[i]->deltax, ROI[i]->deltay, 3);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -147,6 +213,9 @@ string ClassFlowAnalog::getHTMLSingleStep(string host)
|
||||
|
||||
bool ClassFlowAnalog::doFlow(string time)
|
||||
{
|
||||
if (disabled)
|
||||
return true;
|
||||
|
||||
if (!doAlignAndCut(time)){
|
||||
return false;
|
||||
};
|
||||
@@ -162,81 +231,45 @@ bool ClassFlowAnalog::doFlow(string time)
|
||||
|
||||
bool ClassFlowAnalog::doAlignAndCut(string time)
|
||||
{
|
||||
string input = "/sdcard/img_tmp/alg.jpg";
|
||||
string input_roi = "/sdcard/img_tmp/alg_roi.jpg";
|
||||
string ioresize = "/sdcard/img_tmp/resize.bmp";
|
||||
string output;
|
||||
string nm;
|
||||
input = FormatFileName(input);
|
||||
input_roi = FormatFileName(input_roi);
|
||||
if (disabled)
|
||||
return true;
|
||||
|
||||
CResizeImage *rs;
|
||||
CImageBasis *img_roi = NULL;
|
||||
CAlignAndCutImage *caic = new CAlignAndCutImage(input);
|
||||
|
||||
if (!caic->ImageOkay()){
|
||||
if (debugdetailanalog) LogFile.WriteToFile("ClassFlowAnalog::doAlignAndCut not okay!");
|
||||
delete caic;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (input_roi.length() > 0){
|
||||
img_roi = new CImageBasis(input_roi);
|
||||
if (!img_roi->ImageOkay()){
|
||||
if (debugdetailanalog) LogFile.WriteToFile("ClassFlowAnalog::doAlignAndCut ImageRoi not okay!");
|
||||
delete caic;
|
||||
delete img_roi;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
CAlignAndCutImage *caic = flowpostalignment->GetAlignAndCutImage();
|
||||
|
||||
for (int i = 0; i < ROI.size(); ++i)
|
||||
{
|
||||
printf("Analog %d - Align&Cut\n", i);
|
||||
output = "/sdcard/img_tmp/" + ROI[i]->name + ".jpg";
|
||||
output = FormatFileName(output);
|
||||
caic->CutAndSave(output, ROI[i]->posx, ROI[i]->posy, ROI[i]->deltax, ROI[i]->deltay);
|
||||
|
||||
rs = new CResizeImage(output);
|
||||
if (!rs->ImageOkay()){
|
||||
if (debugdetailanalog) LogFile.WriteToFile("ClassFlowAnalog::doAlignAndCut CResizeImage(output);!");
|
||||
delete caic;
|
||||
delete rs;
|
||||
return false;
|
||||
}
|
||||
caic->CutAndSave(ROI[i]->posx, ROI[i]->posy, ROI[i]->deltax, ROI[i]->deltay, ROI[i]->image_org);
|
||||
if (SaveAllFiles) ROI[i]->image_org->SaveToFile(FormatFileName("/sdcard/img_tmp/" + ROI[i]->name + ".jpg"));
|
||||
|
||||
rs->Resize(modelxsize, modelysize);
|
||||
ioresize = "/sdcard/img_tmp/ra" + std::to_string(i) + ".bmp";
|
||||
ioresize = FormatFileName(ioresize);
|
||||
rs->SaveToFile(ioresize);
|
||||
delete rs;
|
||||
|
||||
if (img_roi)
|
||||
{
|
||||
int r = 0;
|
||||
int g = 255;
|
||||
int b = 0;
|
||||
img_roi->drawRect(ROI[i]->posx, ROI[i]->posy, ROI[i]->deltax, ROI[i]->deltay, r, g, b, 1);
|
||||
img_roi->drawCircle((int) (ROI[i]->posx + ROI[i]->deltax/2), (int) (ROI[i]->posy + ROI[i]->deltay/2), (int) (ROI[i]->deltax/2), r, g, b, 2);
|
||||
img_roi->drawLine((int) (ROI[i]->posx + ROI[i]->deltax/2), (int) ROI[i]->posy, (int) (ROI[i]->posx + ROI[i]->deltax/2), (int) (ROI[i]->posy + ROI[i]->deltay), r, g, b, 2);
|
||||
img_roi->drawLine((int) ROI[i]->posx, (int) (ROI[i]->posy + ROI[i]->deltay/2), (int) ROI[i]->posx + ROI[i]->deltax, (int) (ROI[i]->posy + ROI[i]->deltay/2), r, g, b, 2);
|
||||
}
|
||||
ROI[i]->image_org->Resize(modelxsize, modelysize, ROI[i]->image);
|
||||
if (SaveAllFiles) ROI[i]->image->SaveToFile(FormatFileName("/sdcard/img_tmp/" + ROI[i]->name + ".bmp"));
|
||||
}
|
||||
delete caic;
|
||||
|
||||
|
||||
if (img_roi)
|
||||
{
|
||||
img_roi->SaveToFile(input_roi);
|
||||
delete img_roi;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ClassFlowAnalog::DrawROI(CImageBasis *_zw)
|
||||
{
|
||||
int r = 0;
|
||||
int g = 255;
|
||||
int b = 0;
|
||||
|
||||
for (int i = 0; i < ROI.size(); ++i)
|
||||
{
|
||||
_zw->drawRect(ROI[i]->posx, ROI[i]->posy, ROI[i]->deltax, ROI[i]->deltay, r, g, b, 1);
|
||||
_zw->drawCircle((int) (ROI[i]->posx + ROI[i]->deltax/2), (int) (ROI[i]->posy + ROI[i]->deltay/2), (int) (ROI[i]->deltax/2), r, g, b, 2);
|
||||
_zw->drawLine((int) (ROI[i]->posx + ROI[i]->deltax/2), (int) ROI[i]->posy, (int) (ROI[i]->posx + ROI[i]->deltax/2), (int) (ROI[i]->posy + ROI[i]->deltay), r, g, b, 2);
|
||||
_zw->drawLine((int) ROI[i]->posx, (int) (ROI[i]->posy + ROI[i]->deltay/2), (int) ROI[i]->posx + ROI[i]->deltax, (int) (ROI[i]->posy + ROI[i]->deltay/2), r, g, b, 2);
|
||||
}
|
||||
}
|
||||
|
||||
bool ClassFlowAnalog::doNeuralNetwork(string time)
|
||||
{
|
||||
if (disabled)
|
||||
return true;
|
||||
|
||||
string logPath = CreateLogFolder(time);
|
||||
|
||||
string input = "/sdcard/img_tmp/alg.jpg";
|
||||
@@ -265,7 +298,8 @@ bool ClassFlowAnalog::doNeuralNetwork(string time)
|
||||
|
||||
#ifndef OHNETFLITE
|
||||
// LogFile.WriteToFile("ClassFlowAnalog::doNeuralNetwork vor CNN tflite->LoadInputImage(ioresize)");
|
||||
tflite->LoadInputImage(ioresize);
|
||||
// tflite->LoadInputImage(ioresize);
|
||||
tflite->LoadInputImageBasis(ROI[i]->image);
|
||||
tflite->Invoke();
|
||||
if (debugdetailanalog) LogFile.WriteToFile("Nach Invoke");
|
||||
|
||||
@@ -280,7 +314,10 @@ bool ClassFlowAnalog::doNeuralNetwork(string time)
|
||||
|
||||
printf("Result Analog%i: %f\n", i, ROI[i]->result);
|
||||
|
||||
LogImage(logPath, ROI[i]->name, &ROI[i]->result, NULL, time);
|
||||
if (isLogImage)
|
||||
{
|
||||
LogImage(logPath, ROI[i]->name, &ROI[i]->result, NULL, time, ROI[i]->image_org);
|
||||
}
|
||||
}
|
||||
#ifndef OHNETFLITE
|
||||
delete tflite;
|
||||
@@ -297,8 +334,11 @@ std::vector<HTMLInfo*> ClassFlowAnalog::GetHTMLInfo()
|
||||
for (int i = 0; i < ROI.size(); ++i)
|
||||
{
|
||||
HTMLInfo *zw = new HTMLInfo;
|
||||
zw->filename = ROI[i]->name + ".jpg";
|
||||
zw->filename = ROI[i]->name + ".bmp";
|
||||
zw->filename_org = ROI[i]->name + ".jpg";
|
||||
zw->val = ROI[i]->result;
|
||||
zw->image = ROI[i]->image;
|
||||
zw->image_org = ROI[i]->image_org;
|
||||
result.push_back(zw);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
#pragma once
|
||||
#include "ClassFlowImage.h"
|
||||
#include "ClassFlowAlignment.h"
|
||||
// #include "CTfLiteClass.h"
|
||||
|
||||
struct roianalog {
|
||||
int posx, posy, deltax, deltay;
|
||||
float result;
|
||||
CImageBasis *image, *image_org;
|
||||
string name;
|
||||
};
|
||||
|
||||
@@ -17,19 +19,29 @@ protected:
|
||||
string cnnmodelfile;
|
||||
int modelxsize, modelysize;
|
||||
int ZeigerEval(float zahl, int ziffer_vorgaenger);
|
||||
bool SaveAllFiles;
|
||||
|
||||
|
||||
ClassFlowAlignment* flowpostalignment;
|
||||
|
||||
void SetInitialParameter(void);
|
||||
|
||||
public:
|
||||
ClassFlowAnalog();
|
||||
bool extendedResolution;
|
||||
|
||||
ClassFlowAnalog(std::vector<ClassFlow*>* lfc);
|
||||
|
||||
bool ReadParameter(FILE* pfile, string& aktparamgraph);
|
||||
bool doFlow(string time);
|
||||
string getHTMLSingleStep(string host);
|
||||
string getReadout();
|
||||
|
||||
void DrawROI(CImageBasis *_zw);
|
||||
|
||||
bool doNeuralNetwork(string time);
|
||||
bool doAlignAndCut(string time);
|
||||
std::vector<HTMLInfo*> GetHTMLInfo();
|
||||
int AnzahlROIs(){return ROI.size();};
|
||||
int AnzahlROIs();
|
||||
|
||||
string name(){return "ClassFlowAnalog";};
|
||||
};
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "ClassFlowControll.h"
|
||||
|
||||
#include "connect_wlan.h"
|
||||
|
||||
#include "freertos/task.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
@@ -9,33 +11,35 @@
|
||||
#include "Helper.h"
|
||||
#include "server_ota.h"
|
||||
|
||||
#include "server_help.h"
|
||||
|
||||
//#define DEBUG_DETAIL_ON
|
||||
|
||||
static const char* TAG = "flow_controll";
|
||||
|
||||
|
||||
std::string ClassFlowControll::doSingleStep(std::string _stepname, std::string _host){
|
||||
std::string _classname = "";
|
||||
std::string result = "";
|
||||
if (_stepname.compare("[MakeImage]") == 0){
|
||||
if ((_stepname.compare("[MakeImage]") == 0) || (_stepname.compare(";[MakeImage]") == 0)){
|
||||
_classname = "ClassFlowMakeImage";
|
||||
}
|
||||
if (_stepname.compare("[Alignment]") == 0){
|
||||
if ((_stepname.compare("[Alignment]") == 0) || (_stepname.compare(";[Alignment]") == 0)){
|
||||
_classname = "ClassFlowAlignment";
|
||||
}
|
||||
if (_stepname.compare("[Digits]") == 0){
|
||||
if ((_stepname.compare("[Digits]") == 0) || (_stepname.compare(";[Digits]") == 0)){
|
||||
_classname = "ClassFlowDigit";
|
||||
}
|
||||
if (_stepname.compare("[Analog]") == 0){
|
||||
if ((_stepname.compare("[Analog]") == 0) || (_stepname.compare(";[Analog]") == 0)){
|
||||
_classname = "ClassFlowAnalog";
|
||||
}
|
||||
if (_stepname.compare("[MQTT]") == 0){
|
||||
if ((_stepname.compare("[MQTT]") == 0) || (_stepname.compare(";[MQTT]") == 0)){
|
||||
_classname = "ClassFlowMQTT";
|
||||
}
|
||||
// std::string zw = "Classname: " + _classname + "\n";
|
||||
// printf(zw.c_str());
|
||||
|
||||
for (int i = 0; i < FlowControll.size(); ++i)
|
||||
if (FlowControll[i]->name().compare(_classname) == 0){
|
||||
// printf(FlowControll[i]->name().c_str()); printf("\n");
|
||||
FlowControll[i]->doFlow("");
|
||||
FlowControll[i]->doFlow("");
|
||||
result = FlowControll[i]->getHTMLSingleStep(_host);
|
||||
}
|
||||
|
||||
@@ -66,7 +70,15 @@ std::vector<HTMLInfo*> ClassFlowControll::GetAllAnalog()
|
||||
void ClassFlowControll::SetInitialParameter(void)
|
||||
{
|
||||
AutoStart = false;
|
||||
SetupModeActive = false;
|
||||
AutoIntervall = 10;
|
||||
flowdigit = NULL;
|
||||
flowanalog = NULL;
|
||||
flowpostprocessing = NULL;
|
||||
disabled = false;
|
||||
aktRunNr = 0;
|
||||
aktstatus = "Startup";
|
||||
|
||||
}
|
||||
|
||||
bool ClassFlowControll::isAutoStart(long &_intervall)
|
||||
@@ -82,13 +94,25 @@ ClassFlow* ClassFlowControll::CreateClassFlow(std::string _type)
|
||||
_type = trim(_type);
|
||||
|
||||
if (toUpper(_type).compare("[MAKEIMAGE]") == 0)
|
||||
{
|
||||
cfc = new ClassFlowMakeImage(&FlowControll);
|
||||
flowmakeimage = (ClassFlowMakeImage*) cfc;
|
||||
}
|
||||
if (toUpper(_type).compare("[ALIGNMENT]") == 0)
|
||||
{
|
||||
cfc = new ClassFlowAlignment(&FlowControll);
|
||||
flowalignment = (ClassFlowAlignment*) cfc;
|
||||
}
|
||||
if (toUpper(_type).compare("[ANALOG]") == 0)
|
||||
{
|
||||
cfc = new ClassFlowAnalog(&FlowControll);
|
||||
flowanalog = (ClassFlowAnalog*) cfc;
|
||||
}
|
||||
if (toUpper(_type).compare("[DIGITS]") == 0)
|
||||
{
|
||||
cfc = new ClassFlowDigit(&FlowControll);
|
||||
flowdigit = (ClassFlowDigit*) cfc;
|
||||
}
|
||||
if (toUpper(_type).compare("[MQTT]") == 0)
|
||||
cfc = new ClassFlowMQTT(&FlowControll);
|
||||
if (toUpper(_type).compare("[POSTPROCESSING]") == 0)
|
||||
@@ -121,7 +145,7 @@ void ClassFlowControll::InitFlow(std::string config)
|
||||
ClassFlow* cfc;
|
||||
FILE* pFile;
|
||||
config = FormatFileName(config);
|
||||
pFile = fopen(config.c_str(), "r");
|
||||
pFile = OpenFileAndWait(config.c_str(), "r");
|
||||
|
||||
line = "";
|
||||
|
||||
@@ -138,6 +162,7 @@ void ClassFlowControll::InitFlow(std::string config)
|
||||
cfc = CreateClassFlow(line);
|
||||
if (cfc)
|
||||
{
|
||||
printf("Start ReadParameter\n");
|
||||
cfc->ReadParameter(pFile, line);
|
||||
}
|
||||
else
|
||||
@@ -156,6 +181,20 @@ std::string ClassFlowControll::getActStatus(){
|
||||
return aktstatus;
|
||||
}
|
||||
|
||||
void ClassFlowControll::doFlowMakeImageOnly(string time){
|
||||
std::string zw_time;
|
||||
|
||||
for (int i = 0; i < FlowControll.size(); ++i)
|
||||
{
|
||||
if (FlowControll[i]->name() == "ClassFlowMakeImage") {
|
||||
zw_time = gettimestring("%Y%m%d-%H%M%S");
|
||||
aktstatus = zw_time + ": " + FlowControll[i]->name();
|
||||
string zw = "FlowControll.doFlowMakeImageOnly - " + FlowControll[i]->name();
|
||||
FlowControll[i]->doFlow(time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ClassFlowControll::doFlow(string time)
|
||||
{
|
||||
// CleanTempFolder(); // dazu muss man noch eine Rolling einführen
|
||||
@@ -164,12 +203,19 @@ bool ClassFlowControll::doFlow(string time)
|
||||
std::string zw_time;
|
||||
int repeat = 0;
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("ClassFlowAnalog::doFlow - Start");
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < FlowControll.size(); ++i)
|
||||
{
|
||||
zw_time = gettimestring("%Y%m%d-%H%M%S");
|
||||
aktstatus = zw_time + ": " + FlowControll[i]->name();
|
||||
|
||||
|
||||
string zw = "FlowControll.doFlow - " + FlowControll[i]->name();
|
||||
LogFile.WriteToFile(zw);
|
||||
LogFile.WriteHeapInfo(zw);
|
||||
|
||||
if (!FlowControll[i]->doFlow(time)){
|
||||
repeat++;
|
||||
LogFile.WriteToFile("Fehler im vorheriger Schritt - wird zum " + to_string(repeat) + ". Mal wiederholt");
|
||||
@@ -185,12 +231,32 @@ bool ClassFlowControll::doFlow(string time)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("ClassFlowAnalog::doFlow");
|
||||
#endif
|
||||
|
||||
}
|
||||
zw_time = gettimestring("%Y%m%d-%H%M%S");
|
||||
aktstatus = zw_time + ": Flow is done";
|
||||
return result;
|
||||
}
|
||||
|
||||
void ClassFlowControll::UpdateAktStatus(std::string _flow)
|
||||
{
|
||||
aktstatus = gettimestring("%Y%m%d-%H%M%S");
|
||||
aktstatus = aktstatus + "\t" + std::to_string(aktRunNr) + "\t";
|
||||
|
||||
if (_flow == "ClassFlowMakeImage")
|
||||
aktstatus = aktstatus + "Taking Raw Image";
|
||||
else
|
||||
if (_flow == "ClassFlowAlignment")
|
||||
aktstatus = aktstatus + "Aligning Image";
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
string ClassFlowControll::getReadout(bool _rawvalue = false, bool _noerror = false)
|
||||
{
|
||||
if (flowpostprocessing)
|
||||
@@ -303,12 +369,34 @@ bool ClassFlowControll::ReadParameter(FILE* pfile, string& aktparamgraph)
|
||||
setTimeZone(zerlegt[1]);
|
||||
}
|
||||
|
||||
if ((toUpper(zerlegt[0]) == "TIMEUPDATEINTERVALL") && (zerlegt.size() > 1))
|
||||
if ((toUpper(zerlegt[0]) == "TIMESERVER") && (zerlegt.size() > 1))
|
||||
{
|
||||
TimeUpdateIntervall = stof(zerlegt[1]);
|
||||
xTaskCreate(&task_doTimeSync, "update_time", configMINIMAL_STACK_SIZE * 16, &TimeUpdateIntervall, tskIDLE_PRIORITY, NULL);
|
||||
string zw = "Set TimeZone: " + zerlegt[1];
|
||||
reset_servername(zerlegt[1]);
|
||||
}
|
||||
|
||||
if ((toUpper(zerlegt[0]) == "HOSTNAME") && (zerlegt.size() > 1))
|
||||
{
|
||||
if (ChangeHostName("/sdcard/wlan.ini", zerlegt[1]))
|
||||
{
|
||||
// reboot notwendig damit die neue wlan.ini auch benutzt wird !!!
|
||||
fclose(pfile);
|
||||
doReboot();
|
||||
}
|
||||
}
|
||||
|
||||
if ((toUpper(zerlegt[0]) == "SETUPMODE") && (zerlegt.size() > 1))
|
||||
{
|
||||
if (toUpper(zerlegt[1]) == "TRUE")
|
||||
{
|
||||
SetupModeActive = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ((toUpper(zerlegt[0]) == "LOGLEVEL") && (zerlegt.size() > 1))
|
||||
{
|
||||
LogFile.setLogLevel(stoi(zerlegt[1]));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -342,3 +430,84 @@ int ClassFlowControll::CleanTempFolder() {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
esp_err_t ClassFlowControll::SendRawJPG(httpd_req_t *req)
|
||||
{
|
||||
return flowmakeimage->SendRawJPG(req);
|
||||
}
|
||||
|
||||
|
||||
esp_err_t ClassFlowControll::GetJPGStream(std::string _fn, httpd_req_t *req)
|
||||
{
|
||||
printf("ClassFlowControll::GetJPGStream %s\n", _fn.c_str());
|
||||
|
||||
CImageBasis *_send = NULL;
|
||||
esp_err_t result = ESP_FAIL;
|
||||
bool Dodelete = false;
|
||||
|
||||
if (_fn == "alg.jpg")
|
||||
{
|
||||
_send = flowalignment->ImageBasis;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (_fn == "alg_roi.jpg")
|
||||
{
|
||||
CImageBasis* _imgzw = new CImageBasis(flowalignment->ImageBasis);
|
||||
flowalignment->DrawRef(_imgzw);
|
||||
if (flowdigit) flowdigit->DrawROI(_imgzw);
|
||||
if (flowanalog) flowanalog->DrawROI(_imgzw);
|
||||
_send = _imgzw;
|
||||
Dodelete = true;
|
||||
}
|
||||
|
||||
std::vector<HTMLInfo*> htmlinfo;
|
||||
htmlinfo = GetAllDigital();
|
||||
for (int i = 0; i < htmlinfo.size(); ++i)
|
||||
{
|
||||
if (_fn == htmlinfo[i]->filename)
|
||||
{
|
||||
if (htmlinfo[i]->image)
|
||||
_send = htmlinfo[i]->image;
|
||||
}
|
||||
if (_fn == htmlinfo[i]->filename_org)
|
||||
{
|
||||
if (htmlinfo[i]->image_org)
|
||||
_send = htmlinfo[i]->image_org;
|
||||
}
|
||||
}
|
||||
|
||||
htmlinfo = GetAllAnalog();
|
||||
for (int i = 0; i < htmlinfo.size(); ++i)
|
||||
{
|
||||
if (_fn == htmlinfo[i]->filename)
|
||||
{
|
||||
if (htmlinfo[i]->image)
|
||||
_send = htmlinfo[i]->image;
|
||||
}
|
||||
if (_fn == htmlinfo[i]->filename_org)
|
||||
{
|
||||
if (htmlinfo[i]->image_org)
|
||||
_send = htmlinfo[i]->image_org;
|
||||
}
|
||||
}
|
||||
|
||||
if (_send)
|
||||
{
|
||||
ESP_LOGI(TAG, "Sending file : %s ...", _fn.c_str());
|
||||
set_content_type_from_file(req, _fn.c_str());
|
||||
result = _send->SendJPGtoHTTP(req);
|
||||
ESP_LOGI(TAG, "File sending complete");
|
||||
/* Respond with an empty chunk to signal HTTP response completion */
|
||||
httpd_resp_send_chunk(req, NULL, 0);
|
||||
}
|
||||
|
||||
if (Dodelete)
|
||||
{
|
||||
delete _send;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -17,23 +17,34 @@ class ClassFlowControll :
|
||||
protected:
|
||||
std::vector<ClassFlow*> FlowControll;
|
||||
ClassFlowPostProcessing* flowpostprocessing;
|
||||
ClassFlowAlignment* flowalignment;
|
||||
ClassFlowAnalog* flowanalog;
|
||||
ClassFlowDigit* flowdigit;
|
||||
ClassFlowMakeImage* flowmakeimage;
|
||||
ClassFlow* CreateClassFlow(std::string _type);
|
||||
|
||||
bool AutoStart;
|
||||
float AutoIntervall;
|
||||
bool SetupModeActive;
|
||||
void SetInitialParameter(void);
|
||||
std::string aktstatus;
|
||||
int TimeUpdateIntervall;
|
||||
int aktRunNr;
|
||||
|
||||
void UpdateAktStatus(std::string _flow);
|
||||
|
||||
public:
|
||||
void InitFlow(std::string config);
|
||||
bool doFlow(string time);
|
||||
void doFlowMakeImageOnly(string time);
|
||||
bool getStatusSetupModus(){return SetupModeActive;};
|
||||
string getReadout(bool _rawvalue, bool _noerror);
|
||||
string UpdatePrevalue(std::string _newvalue);
|
||||
string GetPrevalue();
|
||||
bool ReadParameter(FILE* pfile, string& aktparamgraph);
|
||||
|
||||
esp_err_t GetJPGStream(std::string _fn, httpd_req_t *req);
|
||||
esp_err_t SendRawJPG(httpd_req_t *req);
|
||||
|
||||
std::string doSingleStep(std::string _stepname, std::string _host);
|
||||
|
||||
bool isAutoStart(long &_intervall);
|
||||
@@ -48,3 +59,4 @@ public:
|
||||
string name(){return "ClassFlowControll";};
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "ClassFlowDigit.h"
|
||||
|
||||
|
||||
//#include "CFindTemplate.h"
|
||||
//#include "CTfLiteClass.h"
|
||||
|
||||
@@ -15,19 +16,51 @@
|
||||
|
||||
static const char* TAG = "flow_digital";
|
||||
|
||||
ClassFlowDigit::ClassFlowDigit() : ClassFlowImage(TAG)
|
||||
|
||||
void ClassFlowDigit::SetInitialParameter(void)
|
||||
{
|
||||
string cnnmodelfile = "";
|
||||
modelxsize = 1;
|
||||
modelysize = 1;
|
||||
ListFlowControll = NULL;
|
||||
previousElement = NULL;
|
||||
SaveAllFiles = false;
|
||||
disabled = false;
|
||||
|
||||
}
|
||||
|
||||
ClassFlowDigit::ClassFlowDigit() : ClassFlowImage(TAG)
|
||||
{
|
||||
SetInitialParameter();
|
||||
}
|
||||
|
||||
ClassFlowDigit::ClassFlowDigit(std::vector<ClassFlow*>* lfc) : ClassFlowImage(lfc, TAG)
|
||||
{
|
||||
string cnnmodelfile = "";
|
||||
modelxsize = 1;
|
||||
modelysize = 1;
|
||||
SetInitialParameter();
|
||||
ListFlowControll = lfc;
|
||||
|
||||
for (int i = 0; i < ListFlowControll->size(); ++i)
|
||||
{
|
||||
if (((*ListFlowControll)[i])->name().compare("ClassFlowAlignment") == 0)
|
||||
{
|
||||
flowpostalignment = (ClassFlowAlignment*) (*ListFlowControll)[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ClassFlowDigit::ClassFlowDigit(std::vector<ClassFlow*>* lfc, ClassFlow *_prev) : ClassFlowImage(lfc, _prev, TAG)
|
||||
{
|
||||
SetInitialParameter();
|
||||
ListFlowControll = lfc;
|
||||
previousElement = _prev;
|
||||
|
||||
for (int i = 0; i < ListFlowControll->size(); ++i)
|
||||
{
|
||||
if (((*ListFlowControll)[i])->name().compare("ClassFlowAlignment") == 0)
|
||||
{
|
||||
flowpostalignment = (ClassFlowAlignment*) (*ListFlowControll)[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string ClassFlowDigit::getReadout()
|
||||
@@ -55,11 +88,19 @@ bool ClassFlowDigit::ReadParameter(FILE* pfile, string& aktparamgraph)
|
||||
if (!this->GetNextParagraph(pfile, aktparamgraph))
|
||||
return false;
|
||||
|
||||
|
||||
if (aktparamgraph.compare("[Digits]") != 0) // Paragraph passt nich zu MakeImage
|
||||
if ((aktparamgraph.compare("[Digits]") != 0) && (aktparamgraph.compare(";[Digits]") != 0)) // Paragraph passt nich zu MakeImage
|
||||
return false;
|
||||
|
||||
while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph))
|
||||
if (aktparamgraph[0] == ';')
|
||||
{
|
||||
disabled = true;
|
||||
while (getNextLine(pfile, &aktparamgraph) && !isNewParagraph(aktparamgraph));
|
||||
printf("[Digits] is disabled !!!\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
while (getNextLine(pfile, &aktparamgraph) && !isNewParagraph(aktparamgraph))
|
||||
{
|
||||
zerlegt = this->ZerlegeZeile(aktparamgraph);
|
||||
if ((zerlegt[0] == "LogImageLocation") && (zerlegt.size() > 1))
|
||||
@@ -85,9 +126,25 @@ bool ClassFlowDigit::ReadParameter(FILE* pfile, string& aktparamgraph)
|
||||
neuroi->deltax = std::stoi(zerlegt[3]);
|
||||
neuroi->deltay = std::stoi(zerlegt[4]);
|
||||
neuroi->resultklasse = -1;
|
||||
neuroi->image = NULL;
|
||||
neuroi->image_org = NULL;
|
||||
ROI.push_back(neuroi);
|
||||
}
|
||||
|
||||
if ((toUpper(zerlegt[0]) == "SAVEALLFILES") && (zerlegt.size() > 1))
|
||||
{
|
||||
if (toUpper(zerlegt[1]) == "TRUE")
|
||||
SaveAllFiles = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (int i = 0; i < ROI.size(); ++i)
|
||||
{
|
||||
ROI[i]->image = new CImageBasis(modelxsize, modelysize, 3);
|
||||
ROI[i]->image_org = new CImageBasis(ROI[i]->deltax, ROI[i]->deltay, 3);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -120,6 +177,9 @@ string ClassFlowDigit::getHTMLSingleStep(string host)
|
||||
|
||||
bool ClassFlowDigit::doFlow(string time)
|
||||
{
|
||||
if (disabled)
|
||||
return true;
|
||||
|
||||
if (!doAlignAndCut(time)){
|
||||
return false;
|
||||
};
|
||||
@@ -133,60 +193,20 @@ bool ClassFlowDigit::doFlow(string time)
|
||||
|
||||
bool ClassFlowDigit::doAlignAndCut(string time)
|
||||
{
|
||||
string input = "/sdcard/img_tmp/alg.jpg";
|
||||
string input_roi = "/sdcard/img_tmp/alg_roi.jpg";
|
||||
string ioresize = "/sdcard/img_tmp/resize.bmp";
|
||||
string output;
|
||||
string nm;
|
||||
input = FormatFileName(input);
|
||||
input_roi = FormatFileName(input_roi);
|
||||
|
||||
CResizeImage *rs;
|
||||
CImageBasis *img_roi = NULL;
|
||||
CAlignAndCutImage *caic = new CAlignAndCutImage(input);
|
||||
if (!caic->ImageOkay()){
|
||||
LogFile.WriteToFile("ClassFlowDigit::doAlignAndCut not okay!");
|
||||
delete caic;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (input_roi.length() > 0){
|
||||
img_roi = new CImageBasis(input_roi);
|
||||
if (!img_roi->ImageOkay()){
|
||||
LogFile.WriteToFile("ClassFlowDigit::doAlignAndCut ImageRoi not okay!");
|
||||
delete caic;
|
||||
delete img_roi;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (disabled)
|
||||
return true;
|
||||
|
||||
CAlignAndCutImage *caic = flowpostalignment->GetAlignAndCutImage();
|
||||
|
||||
for (int i = 0; i < ROI.size(); ++i)
|
||||
{
|
||||
printf("DigitalDigit %d - Align&Cut\n", i);
|
||||
output = "/sdcard/img_tmp/" + ROI[i]->name + ".jpg";
|
||||
output = FormatFileName(output);
|
||||
caic->CutAndSave(output, ROI[i]->posx, ROI[i]->posy, ROI[i]->deltax, ROI[i]->deltay);
|
||||
|
||||
rs = new CResizeImage(output);
|
||||
rs->Resize(modelxsize, modelysize);
|
||||
ioresize = "/sdcard/img_tmp/rd" + std::to_string(i) + ".bmp";
|
||||
ioresize = FormatFileName(ioresize);
|
||||
rs->SaveToFile(ioresize);
|
||||
delete rs;
|
||||
caic->CutAndSave(ROI[i]->posx, ROI[i]->posy, ROI[i]->deltax, ROI[i]->deltay, ROI[i]->image_org);
|
||||
if (SaveAllFiles) ROI[i]->image_org->SaveToFile(FormatFileName("/sdcard/img_tmp/" + ROI[i]->name + ".jpg"));
|
||||
|
||||
if (img_roi)
|
||||
{
|
||||
img_roi->drawRect(ROI[i]->posx, ROI[i]->posy, ROI[i]->deltax, ROI[i]->deltay, 0, 0, 255, 2);
|
||||
}
|
||||
}
|
||||
delete caic;
|
||||
|
||||
if (img_roi)
|
||||
{
|
||||
img_roi->SaveToFile(input_roi);
|
||||
delete img_roi;
|
||||
ROI[i]->image_org->Resize(modelxsize, modelysize, ROI[i]->image);
|
||||
if (SaveAllFiles) ROI[i]->image->SaveToFile(FormatFileName("/sdcard/img_tmp/" + ROI[i]->name + ".bmp"));
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -194,19 +214,14 @@ bool ClassFlowDigit::doAlignAndCut(string time)
|
||||
|
||||
bool ClassFlowDigit::doNeuralNetwork(string time)
|
||||
{
|
||||
if (disabled)
|
||||
return true;
|
||||
|
||||
string logPath = CreateLogFolder(time);
|
||||
|
||||
string input = "/sdcard/img_tmp/alg.jpg";
|
||||
string ioresize = "/sdcard/img_tmp/resize.bmp";
|
||||
string output;
|
||||
string nm;
|
||||
input = FormatFileName(input);
|
||||
|
||||
|
||||
#ifndef OHNETFLITE
|
||||
CTfLiteClass *tflite = new CTfLiteClass;
|
||||
string zwcnn = "/sdcard" + cnnmodelfile;
|
||||
zwcnn = FormatFileName(zwcnn);
|
||||
string zwcnn = FormatFileName("/sdcard" + cnnmodelfile);
|
||||
printf(zwcnn.c_str());printf("\n");
|
||||
tflite->LoadModel(zwcnn);
|
||||
tflite->MakeAllocate();
|
||||
@@ -215,17 +230,18 @@ bool ClassFlowDigit::doNeuralNetwork(string time)
|
||||
for (int i = 0; i < ROI.size(); ++i)
|
||||
{
|
||||
printf("DigitalDigit %d - TfLite\n", i);
|
||||
ioresize = "/sdcard/img_tmp/rd" + std::to_string(i) + ".bmp";
|
||||
ioresize = FormatFileName(ioresize);
|
||||
// printf("output: %s, ioresize: %s\n", output.c_str(), ioresize.c_str());
|
||||
|
||||
ROI[i]->resultklasse = 0;
|
||||
#ifndef OHNETFLITE
|
||||
ROI[i]->resultklasse = tflite->GetClassFromImage(ioresize);
|
||||
ROI[i]->resultklasse = tflite->GetClassFromImageBasis(ROI[i]->image);
|
||||
|
||||
#endif
|
||||
printf("Result Digit%i: %d\n", i, ROI[i]->resultklasse);
|
||||
|
||||
LogImage(logPath, ROI[i]->name, NULL, &ROI[i]->resultklasse, time);
|
||||
if (isLogImage)
|
||||
{
|
||||
LogImage(logPath, ROI[i]->name, NULL, &ROI[i]->resultklasse, time, ROI[i]->image_org);
|
||||
}
|
||||
}
|
||||
#ifndef OHNETFLITE
|
||||
delete tflite;
|
||||
@@ -233,6 +249,11 @@ bool ClassFlowDigit::doNeuralNetwork(string time)
|
||||
return true;
|
||||
}
|
||||
|
||||
void ClassFlowDigit::DrawROI(CImageBasis *_zw)
|
||||
{
|
||||
for (int i = 0; i < ROI.size(); ++i)
|
||||
_zw->drawRect(ROI[i]->posx, ROI[i]->posy, ROI[i]->deltax, ROI[i]->deltay, 0, 0, 255, 2);
|
||||
}
|
||||
|
||||
std::vector<HTMLInfo*> ClassFlowDigit::GetHTMLInfo()
|
||||
{
|
||||
@@ -241,10 +262,14 @@ std::vector<HTMLInfo*> ClassFlowDigit::GetHTMLInfo()
|
||||
for (int i = 0; i < ROI.size(); ++i)
|
||||
{
|
||||
HTMLInfo *zw = new HTMLInfo;
|
||||
zw->filename = ROI[i]->name + ".jpg";
|
||||
zw->filename = ROI[i]->name + ".bmp";
|
||||
zw->filename_org = ROI[i]->name + ".jpg";
|
||||
zw->val = ROI[i]->resultklasse;
|
||||
zw->image = ROI[i]->image;
|
||||
zw->image_org = ROI[i]->image_org;
|
||||
result.push_back(zw);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "ClassFlowImage.h"
|
||||
#include "ClassFlowAlignment.h"
|
||||
#include "Helper.h"
|
||||
|
||||
#include <string>
|
||||
@@ -8,6 +9,7 @@ struct roi {
|
||||
int posx, posy, deltax, deltay;
|
||||
int resultklasse;
|
||||
string name;
|
||||
CImageBasis *image, *image_org;
|
||||
roi* next;
|
||||
};
|
||||
|
||||
@@ -18,19 +20,27 @@ protected:
|
||||
std::vector<roi*> ROI;
|
||||
string cnnmodelfile;
|
||||
int modelxsize, modelysize;
|
||||
bool SaveAllFiles;
|
||||
|
||||
ClassFlowAlignment* flowpostalignment;
|
||||
|
||||
bool doNeuralNetwork(string time);
|
||||
bool doAlignAndCut(string time);
|
||||
|
||||
void SetInitialParameter(void);
|
||||
|
||||
public:
|
||||
ClassFlowDigit();
|
||||
ClassFlowDigit(std::vector<ClassFlow*>* lfc);
|
||||
ClassFlowDigit(std::vector<ClassFlow*>* lfc, ClassFlow *_prev);
|
||||
bool ReadParameter(FILE* pfile, string& aktparamgraph);
|
||||
bool doFlow(string time);
|
||||
string getHTMLSingleStep(string host);
|
||||
string getReadout();
|
||||
std::vector<HTMLInfo*> GetHTMLInfo();
|
||||
|
||||
void DrawROI(CImageBasis *_zw);
|
||||
|
||||
string name(){return "ClassFlowDigit";};
|
||||
};
|
||||
|
||||
|
||||
@@ -5,19 +5,31 @@
|
||||
#include <dirent.h>
|
||||
#include "time_sntp.h"
|
||||
#include "ClassLogFile.h"
|
||||
#include "CImageBasis.h"
|
||||
|
||||
ClassFlowImage::ClassFlowImage(const char* logTag)
|
||||
{
|
||||
this->logTag = logTag;
|
||||
isLogImage = false;
|
||||
disabled = false;
|
||||
|
||||
}
|
||||
|
||||
ClassFlowImage::ClassFlowImage(std::vector<ClassFlow*> * lfc, const char* logTag) : ClassFlow((std::vector<ClassFlow*>*)lfc)
|
||||
ClassFlowImage::ClassFlowImage(std::vector<ClassFlow*> * lfc, const char* logTag) : ClassFlow(lfc)
|
||||
{
|
||||
this->logTag = logTag;
|
||||
isLogImage = false;
|
||||
disabled = false;
|
||||
}
|
||||
|
||||
ClassFlowImage::ClassFlowImage(std::vector<ClassFlow*> * lfc, ClassFlow *_prev, const char* logTag) : ClassFlow(lfc, _prev)
|
||||
{
|
||||
this->logTag = logTag;
|
||||
isLogImage = false;
|
||||
disabled = false;
|
||||
}
|
||||
|
||||
|
||||
string ClassFlowImage::CreateLogFolder(string time) {
|
||||
if (!isLogImage)
|
||||
return "";
|
||||
@@ -32,7 +44,7 @@ string ClassFlowImage::CreateLogFolder(string time) {
|
||||
return logPath;
|
||||
}
|
||||
|
||||
void ClassFlowImage::LogImage(string logPath, string name, float *resultFloat, int *resultInt, string time) {
|
||||
void ClassFlowImage::LogImage(string logPath, string name, float *resultFloat, int *resultInt, string time, CImageBasis *_img) {
|
||||
if (!isLogImage)
|
||||
return;
|
||||
|
||||
@@ -50,7 +62,8 @@ void ClassFlowImage::LogImage(string logPath, string name, float *resultFloat, i
|
||||
string output = "/sdcard/img_tmp/" + name + ".jpg";
|
||||
output = FormatFileName(output);
|
||||
printf("save to file: %s\n", nm.c_str());
|
||||
CopyFile(output, nm);
|
||||
_img->SaveToFile(nm);
|
||||
// CopyFile(output, nm);
|
||||
}
|
||||
|
||||
void ClassFlowImage::RemoveOldLogs()
|
||||
|
||||
@@ -12,11 +12,13 @@ protected:
|
||||
const char* logTag;
|
||||
|
||||
string CreateLogFolder(string time);
|
||||
void LogImage(string logPath, string name, float *resultFloat, int *resultInt, string time);
|
||||
void LogImage(string logPath, string name, float *resultFloat, int *resultInt, string time, CImageBasis *_img);
|
||||
|
||||
|
||||
public:
|
||||
ClassFlowImage(const char* logTag);
|
||||
ClassFlowImage(std::vector<ClassFlow*> * lfc, const char* logTag);
|
||||
ClassFlowImage(std::vector<ClassFlow*> * lfc, ClassFlow *_prev, const char* logTag);
|
||||
|
||||
void RemoveOldLogs();
|
||||
};
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#include <time.h>
|
||||
|
||||
ClassFlowMQTT::ClassFlowMQTT()
|
||||
void ClassFlowMQTT::SetInitialParameter(void)
|
||||
{
|
||||
uri = "";
|
||||
topic = "";
|
||||
@@ -16,19 +16,36 @@ ClassFlowMQTT::ClassFlowMQTT()
|
||||
flowpostprocessing = NULL;
|
||||
user = "";
|
||||
password = "";
|
||||
previousElement = NULL;
|
||||
ListFlowControll = NULL;
|
||||
disabled = false;
|
||||
|
||||
}
|
||||
|
||||
ClassFlowMQTT::ClassFlowMQTT()
|
||||
{
|
||||
SetInitialParameter();
|
||||
}
|
||||
|
||||
ClassFlowMQTT::ClassFlowMQTT(std::vector<ClassFlow*>* lfc)
|
||||
{
|
||||
uri = "";
|
||||
topic = "";
|
||||
topicError = "";
|
||||
clientname = "watermeter";
|
||||
OldValue = "";
|
||||
flowpostprocessing = NULL;
|
||||
user = "";
|
||||
password = "";
|
||||
SetInitialParameter();
|
||||
|
||||
ListFlowControll = lfc;
|
||||
for (int i = 0; i < ListFlowControll->size(); ++i)
|
||||
{
|
||||
if (((*ListFlowControll)[i])->name().compare("ClassFlowPostProcessing") == 0)
|
||||
{
|
||||
flowpostprocessing = (ClassFlowPostProcessing*) (*ListFlowControll)[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ClassFlowMQTT::ClassFlowMQTT(std::vector<ClassFlow*>* lfc, ClassFlow *_prev)
|
||||
{
|
||||
SetInitialParameter();
|
||||
|
||||
previousElement = _prev;
|
||||
ListFlowControll = lfc;
|
||||
|
||||
for (int i = 0; i < ListFlowControll->size(); ++i)
|
||||
@@ -38,9 +55,9 @@ ClassFlowMQTT::ClassFlowMQTT(std::vector<ClassFlow*>* lfc)
|
||||
flowpostprocessing = (ClassFlowPostProcessing*) (*ListFlowControll)[i];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool ClassFlowMQTT::ReadParameter(FILE* pfile, string& aktparamgraph)
|
||||
{
|
||||
std::vector<string> zerlegt;
|
||||
@@ -86,7 +103,7 @@ bool ClassFlowMQTT::ReadParameter(FILE* pfile, string& aktparamgraph)
|
||||
|
||||
if ((uri.length() > 0) && (topic.length() > 0))
|
||||
{
|
||||
MQTTInit(uri, clientname, user, password);
|
||||
MQTTInit(uri, clientname, user, password, topicError, 60);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -13,11 +13,13 @@ protected:
|
||||
std::string OldValue;
|
||||
ClassFlowPostProcessing* flowpostprocessing;
|
||||
std::string user, password;
|
||||
|
||||
void SetInitialParameter(void);
|
||||
|
||||
public:
|
||||
ClassFlowMQTT();
|
||||
ClassFlowMQTT(std::vector<ClassFlow*>* lfc);
|
||||
ClassFlowMQTT(std::vector<ClassFlow*>* lfc, ClassFlow *_prev);
|
||||
|
||||
bool ReadParameter(FILE* pfile, string& aktparamgraph);
|
||||
bool doFlow(string time);
|
||||
string name(){return "ClassFlowMQTT";};
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
#include "ClassFlowMakeImage.h"
|
||||
#include "Helper.h"
|
||||
#include "ClassLogFile.h"
|
||||
|
||||
#include "CFindTemplate.h"
|
||||
#include "CImageBasis.h"
|
||||
#include "ClassControllCamera.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
// #define DEBUG_DETAIL_ON
|
||||
|
||||
static const char* TAG = "flow_make_image";
|
||||
|
||||
esp_err_t ClassFlowMakeImage::camera_capture(){
|
||||
@@ -16,30 +19,28 @@ esp_err_t ClassFlowMakeImage::camera_capture(){
|
||||
|
||||
void ClassFlowMakeImage::takePictureWithFlash(int flashdauer)
|
||||
{
|
||||
string nm = namerawimage;
|
||||
if (isImageSize && (ImageQuality > 0))
|
||||
Camera.SetQualitySize(ImageQuality, ImageSize);
|
||||
printf("Start CaptureFile\n");
|
||||
Camera.CaptureToFile(nm, flashdauer);
|
||||
Camera.CaptureToBasisImage(rawImage, flashdauer);
|
||||
if (SaveAllFiles) rawImage->SaveToFile(namerawimage);
|
||||
}
|
||||
|
||||
|
||||
ClassFlowMakeImage::ClassFlowMakeImage() : ClassFlowImage(TAG)
|
||||
void ClassFlowMakeImage::SetInitialParameter(void)
|
||||
{
|
||||
waitbeforepicture = 5;
|
||||
isImageSize = false;
|
||||
ImageQuality = -1;
|
||||
TimeImageTaken = 0;
|
||||
ImageQuality = 5;
|
||||
rawImage = NULL;
|
||||
ImageSize = FRAMESIZE_VGA;
|
||||
SaveAllFiles = false;
|
||||
disabled = false;
|
||||
namerawimage = "/sdcard/img_tmp/raw.jpg";
|
||||
}
|
||||
|
||||
|
||||
ClassFlowMakeImage::ClassFlowMakeImage(std::vector<ClassFlow*>* lfc) : ClassFlowImage(lfc, TAG)
|
||||
{
|
||||
waitbeforepicture = 5;
|
||||
isImageSize = false;
|
||||
ImageQuality = -1;
|
||||
TimeImageTaken = 0;
|
||||
namerawimage = "/sdcard/img_tmp/raw.jpg";
|
||||
SetInitialParameter();
|
||||
}
|
||||
|
||||
bool ClassFlowMakeImage::ReadParameter(FILE* pfile, string& aktparamgraph)
|
||||
@@ -64,14 +65,28 @@ bool ClassFlowMakeImage::ReadParameter(FILE* pfile, string& aktparamgraph)
|
||||
isLogImage = true;
|
||||
}
|
||||
if ((zerlegt[0] == "ImageQuality") && (zerlegt.size() > 1))
|
||||
this->ImageQuality = std::stod(zerlegt[1]);
|
||||
ImageQuality = std::stod(zerlegt[1]);
|
||||
|
||||
if ((zerlegt[0] == "ImageSize") && (zerlegt.size() > 1))
|
||||
{
|
||||
ImageSize = Camera.TextToFramesize(zerlegt[1].c_str());
|
||||
isImageSize = true;
|
||||
}
|
||||
|
||||
if ((toUpper(zerlegt[0]) == "SAVEALLFILES") && (zerlegt.size() > 1))
|
||||
{
|
||||
if (toUpper(zerlegt[1]) == "TRUE")
|
||||
SaveAllFiles = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Camera.SetQualitySize(ImageQuality, ImageSize);
|
||||
image_width = Camera.image_width;
|
||||
image_height = Camera.image_height;
|
||||
rawImage = new CImageBasis();
|
||||
rawImage->CreateEmptyImage(image_width, image_height, 3);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -84,27 +99,56 @@ string ClassFlowMakeImage::getHTMLSingleStep(string host)
|
||||
|
||||
bool ClassFlowMakeImage::doFlow(string zwtime)
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// TakeImage and Store into /image_tmp/raw.jpg TO BE DONE
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
string logPath = CreateLogFolder(zwtime);
|
||||
|
||||
int flashdauer = (int) waitbeforepicture * 1000;
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("ClassFlowMakeImage::doFlow - Before takePictureWithFlash");
|
||||
#endif
|
||||
|
||||
takePictureWithFlash(flashdauer);
|
||||
time(&TimeImageTaken);
|
||||
localtime(&TimeImageTaken);
|
||||
|
||||
LogImage(logPath, "raw", NULL, NULL, zwtime);
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("ClassFlowMakeImage::doFlow - After takePictureWithFlash");
|
||||
#endif
|
||||
|
||||
LogImage(logPath, "raw", NULL, NULL, zwtime, rawImage);
|
||||
|
||||
RemoveOldLogs();
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("ClassFlowMakeImage::doFlow - After RemoveOldLogs");
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
esp_err_t ClassFlowMakeImage::SendRawJPG(httpd_req_t *req)
|
||||
{
|
||||
int flashdauer = (int) waitbeforepicture * 1000;
|
||||
return Camera.CaptureToHTTP(req, flashdauer);
|
||||
}
|
||||
|
||||
|
||||
ImageData* ClassFlowMakeImage::SendRawImage()
|
||||
{
|
||||
CImageBasis *zw = new CImageBasis(rawImage);
|
||||
ImageData *id;
|
||||
int flashdauer = (int) waitbeforepicture * 1000;
|
||||
Camera.CaptureToBasisImage(zw, flashdauer);
|
||||
id = zw->writeToMemoryAsJPG();
|
||||
delete zw;
|
||||
return id;
|
||||
}
|
||||
|
||||
time_t ClassFlowMakeImage::getTimeImageTaken()
|
||||
{
|
||||
return TimeImageTaken;
|
||||
}
|
||||
|
||||
ClassFlowMakeImage::~ClassFlowMakeImage(void)
|
||||
{
|
||||
delete rawImage;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,19 +20,32 @@ protected:
|
||||
int ImageQuality;
|
||||
time_t TimeImageTaken;
|
||||
string namerawimage;
|
||||
int image_height, image_width;
|
||||
bool SaveAllFiles;
|
||||
|
||||
|
||||
void CopyFile(string input, string output);
|
||||
|
||||
esp_err_t camera_capture();
|
||||
void takePictureWithFlash(int flashdauer);
|
||||
|
||||
void SetInitialParameter(void);
|
||||
|
||||
public:
|
||||
ClassFlowMakeImage();
|
||||
CImageBasis *rawImage;
|
||||
|
||||
ClassFlowMakeImage(std::vector<ClassFlow*>* lfc);
|
||||
|
||||
bool ReadParameter(FILE* pfile, string& aktparamgraph);
|
||||
bool doFlow(string time);
|
||||
string getHTMLSingleStep(string host);
|
||||
time_t getTimeImageTaken();
|
||||
string name(){return "ClassFlowMakeImage";};
|
||||
|
||||
ImageData* SendRawImage();
|
||||
esp_err_t SendRawJPG(httpd_req_t *req);
|
||||
|
||||
~ClassFlowMakeImage(void);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -14,17 +14,28 @@
|
||||
string ClassFlowPostProcessing::GetPreValue()
|
||||
{
|
||||
std::string result;
|
||||
bool isAnalog = false;
|
||||
bool isDigit = false;
|
||||
|
||||
int AnzahlAnalog = 0;
|
||||
result = RundeOutput(PreValue, -DecimalShift);
|
||||
|
||||
for (int i = 0; i < ListFlowControll->size(); ++i)
|
||||
{
|
||||
if (((*ListFlowControll)[i])->name().compare("ClassFlowAnalog") == 0)
|
||||
{
|
||||
int AnzahlAnalog = ((ClassFlowAnalog*)(*ListFlowControll)[i])->AnzahlROIs();
|
||||
result = RundeOutput(PreValue, AnzahlAnalog - DecimalShift);
|
||||
isAnalog = true;
|
||||
AnzahlAnalog = ((ClassFlowAnalog*)(*ListFlowControll)[i])->AnzahlROIs();
|
||||
}
|
||||
if (((*ListFlowControll)[i])->name().compare("ClassFlowDigit") == 0)
|
||||
{
|
||||
isDigit = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (isDigit && isAnalog)
|
||||
result = RundeOutput(PreValue, AnzahlAnalog - DecimalShift);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -75,15 +86,22 @@ bool ClassFlowPostProcessing::LoadPreValue(void)
|
||||
ReturnValue = to_string(Value);
|
||||
ReturnValueNoError = ReturnValue;
|
||||
|
||||
// falls es Analog gibt, dann die Anzahl der Nachkommastellen feststellen und entsprechend runden:
|
||||
bool isAnalog = false;
|
||||
bool isDigit = false;
|
||||
int AnzahlAnalog = 0;
|
||||
|
||||
for (int i = 0; i < ListFlowControll->size(); ++i)
|
||||
{
|
||||
if (((*ListFlowControll)[i])->name().compare("ClassFlowAnalog") == 0)
|
||||
{
|
||||
int AnzahlAnalog = ((ClassFlowAnalog*)(*ListFlowControll)[i])->AnzahlROIs();
|
||||
ReturnValue = RundeOutput(Value, AnzahlAnalog - DecimalShift);
|
||||
ReturnValueNoError = ReturnValue;
|
||||
}
|
||||
isAnalog = true;
|
||||
if (((*ListFlowControll)[i])->name().compare("ClassFlowDigit") == 0)
|
||||
isDigit = true;
|
||||
}
|
||||
|
||||
if (isDigit || isAnalog)
|
||||
{
|
||||
ReturnValue = RundeOutput(Value, AnzahlAnalog - DecimalShift);
|
||||
ReturnValueNoError = ReturnValue;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -108,6 +126,8 @@ void ClassFlowPostProcessing::SavePreValue(float value, string zwtime)
|
||||
zwtime = std::string(buffer);
|
||||
}
|
||||
|
||||
PreValue = value;
|
||||
|
||||
fputs(zwtime.c_str(), pFile);
|
||||
fputs("\n", pFile);
|
||||
fputs(to_string(value).c_str(), pFile);
|
||||
@@ -117,23 +137,6 @@ void ClassFlowPostProcessing::SavePreValue(float value, string zwtime)
|
||||
}
|
||||
|
||||
|
||||
|
||||
ClassFlowPostProcessing::ClassFlowPostProcessing()
|
||||
{
|
||||
PreValueUse = false;
|
||||
PreValueAgeStartup = 30;
|
||||
AllowNegativeRates = false;
|
||||
MaxRateValue = 0.1;
|
||||
ErrorMessage = false;
|
||||
ListFlowControll = NULL;
|
||||
PreValueOkay = false;
|
||||
useMaxRateValue = false;
|
||||
checkDigitIncreaseConsistency = false;
|
||||
DecimalShift = 0;
|
||||
ErrorMessageText = "";
|
||||
FilePreValue = FormatFileName("/sdcard/config/prevalue.ini");
|
||||
}
|
||||
|
||||
ClassFlowPostProcessing::ClassFlowPostProcessing(std::vector<ClassFlow*>* lfc)
|
||||
{
|
||||
PreValueUse = false;
|
||||
@@ -266,6 +269,7 @@ bool ClassFlowPostProcessing::doFlow(string zwtime)
|
||||
int AnzahlAnalog = 0;
|
||||
string zw;
|
||||
time_t imagetime = 0;
|
||||
string rohwert;
|
||||
|
||||
ErrorMessageText = "";
|
||||
|
||||
@@ -304,6 +308,8 @@ bool ClassFlowPostProcessing::doFlow(string zwtime)
|
||||
// isdigit = true; digit = "12N";
|
||||
// isanalog = true; analog = "456";
|
||||
|
||||
ReturnRawValue = "";
|
||||
|
||||
if (isdigit)
|
||||
ReturnRawValue = digit;
|
||||
if (isdigit && isanalog)
|
||||
@@ -311,8 +317,15 @@ bool ClassFlowPostProcessing::doFlow(string zwtime)
|
||||
if (isanalog)
|
||||
ReturnRawValue = ReturnRawValue + analog;
|
||||
|
||||
|
||||
if (!isdigit)
|
||||
{
|
||||
AnzahlAnalog = 0;
|
||||
}
|
||||
|
||||
ReturnRawValue = ShiftDecimal(ReturnRawValue, DecimalShift);
|
||||
|
||||
rohwert = ReturnRawValue;
|
||||
|
||||
if (!PreValueUse || !PreValueOkay)
|
||||
{
|
||||
@@ -348,7 +361,7 @@ bool ClassFlowPostProcessing::doFlow(string zwtime)
|
||||
|
||||
if ((!AllowNegativeRates) && (Value < PreValue))
|
||||
{
|
||||
ErrorMessageText = ErrorMessageText + "Negative Rate - Returned old value - read value: " + zwvalue + " ";
|
||||
ErrorMessageText = ErrorMessageText + "Negative Rate - Returned old value - read value: " + zwvalue + " - raw value: " + ReturnRawValue;
|
||||
Value = PreValue;
|
||||
zwvalue = RundeOutput(Value, AnzahlAnalog - DecimalShift);
|
||||
}
|
||||
@@ -391,7 +404,24 @@ string ClassFlowPostProcessing::getReadoutParam(bool _rawValue, bool _noerror)
|
||||
|
||||
string ClassFlowPostProcessing::RundeOutput(float _in, int _anzNachkomma){
|
||||
std::stringstream stream;
|
||||
stream << std::fixed << std::setprecision(_anzNachkomma) << _in;
|
||||
int _zw = _in;
|
||||
// printf("AnzNachkomma: %d\n", _anzNachkomma);
|
||||
|
||||
if (_anzNachkomma < 0) {
|
||||
_anzNachkomma = 0;
|
||||
}
|
||||
|
||||
if (_anzNachkomma > 0)
|
||||
{
|
||||
stream << std::fixed << std::setprecision(_anzNachkomma) << _in;
|
||||
return stream.str();
|
||||
}
|
||||
else
|
||||
{
|
||||
stream << _zw;
|
||||
}
|
||||
|
||||
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,6 @@ protected:
|
||||
string RundeOutput(float _in, int _anzNachkomma);
|
||||
|
||||
public:
|
||||
ClassFlowPostProcessing();
|
||||
ClassFlowPostProcessing(std::vector<ClassFlow*>* lfc);
|
||||
bool ReadParameter(FILE* pfile, string& aktparamgraph);
|
||||
bool doFlow(string time);
|
||||
|
||||
@@ -2,6 +2,6 @@ FILE(GLOB_RECURSE app_sources ${CMAKE_CURRENT_SOURCE_DIR}/*.*)
|
||||
|
||||
idf_component_register(SRCS ${app_sources}
|
||||
INCLUDE_DIRS "."
|
||||
REQUIRES tfmicro)
|
||||
REQUIRES tfmicro jomjol_logfile)
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
//#pragma warning(disable : 4996)
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
#include "Helper.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -7,11 +10,91 @@
|
||||
#include <string.h>
|
||||
#include <esp_log.h>
|
||||
|
||||
#include "ClassLogFile.h"
|
||||
//#include "ClassLogFile.h"
|
||||
|
||||
//#define ISWINDOWS_TRUE
|
||||
#define PATH_MAX_STRING_SIZE 256
|
||||
|
||||
using namespace std;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
string getESPHeapInfo(){
|
||||
string espInfoResultStr = "";
|
||||
char aMsgBuf[80];
|
||||
|
||||
multi_heap_info_t aMultiHead_info ;
|
||||
heap_caps_get_info (&aMultiHead_info,MALLOC_CAP_8BIT);
|
||||
size_t aFreeHeapSize = heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
size_t aMinFreeHeadSize = heap_caps_get_minimum_free_size(MALLOC_CAP_8BIT);
|
||||
size_t aMinFreeHeapSize = heap_caps_get_minimum_free_size(MALLOC_CAP_8BIT);
|
||||
size_t aHeapLargestFreeBlockSize = heap_caps_get_largest_free_block(MALLOC_CAP_8BIT);
|
||||
sprintf(aMsgBuf," Free Heap Size: %ld", (long) aFreeHeapSize);
|
||||
size_t aFreeSPIHeapSize = heap_caps_get_free_size(MALLOC_CAP_8BIT| MALLOC_CAP_SPIRAM);
|
||||
size_t aFreeInternalHeapSize = heap_caps_get_free_size(MALLOC_CAP_8BIT| MALLOC_CAP_INTERNAL);
|
||||
size_t aMinFreeInternalHeapSize = heap_caps_get_minimum_free_size(MALLOC_CAP_8BIT| MALLOC_CAP_INTERNAL);
|
||||
|
||||
sprintf(aMsgBuf," Heap: %ld", (long) aFreeHeapSize);
|
||||
espInfoResultStr += string(aMsgBuf);
|
||||
sprintf(aMsgBuf," Min Free: %ld", (long) aMinFreeHeapSize);
|
||||
espInfoResultStr += string(aMsgBuf);
|
||||
sprintf(aMsgBuf," larg. Block: %ld", (long) aHeapLargestFreeBlockSize);
|
||||
espInfoResultStr += string(aMsgBuf);
|
||||
sprintf(aMsgBuf," SPI Heap: %ld", (long) aFreeSPIHeapSize);
|
||||
espInfoResultStr += string(aMsgBuf);
|
||||
sprintf(aMsgBuf," Min Free Heap Size: %ld", (long) aMinFreeHeadSize);
|
||||
sprintf(aMsgBuf," NOT_SPI Heap: %ld", (long) (aFreeHeapSize - aFreeSPIHeapSize));
|
||||
espInfoResultStr += string(aMsgBuf);
|
||||
sprintf(aMsgBuf," largest Block Size: %ld", (long) aHeapLargestFreeBlockSize);
|
||||
sprintf(aMsgBuf," Internal Heap: %ld", (long) (aFreeInternalHeapSize));
|
||||
espInfoResultStr += string(aMsgBuf);
|
||||
sprintf(aMsgBuf," Internal Min Heap free: %ld", (long) (aMinFreeInternalHeapSize));
|
||||
espInfoResultStr += string(aMsgBuf);
|
||||
return espInfoResultStr;
|
||||
}
|
||||
|
||||
|
||||
size_t getESPHeapSize(){
|
||||
size_t aFreeHeapSize = heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
return aFreeHeapSize;
|
||||
}
|
||||
|
||||
size_t getInternalESPHeapSize() {
|
||||
size_t aFreeInternalHeapSize = heap_caps_get_free_size(MALLOC_CAP_8BIT| MALLOC_CAP_INTERNAL);
|
||||
return aFreeInternalHeapSize;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void memCopyGen(uint8_t* _source, uint8_t* _target, int _size)
|
||||
{
|
||||
for (int i = 0; i < _size; ++i)
|
||||
*(_target + i) = *(_source + i);
|
||||
}
|
||||
|
||||
|
||||
|
||||
FILE* OpenFileAndWait(const char* nm, char* _mode, int _waitsec)
|
||||
{
|
||||
FILE *pfile = fopen(nm, _mode);
|
||||
|
||||
if (pfile == NULL)
|
||||
{
|
||||
TickType_t xDelay;
|
||||
xDelay = _waitsec * 1000 / portTICK_PERIOD_MS;
|
||||
std::string zw = "File is locked: " + std::string(nm) + " - wait for " + std::to_string(_waitsec);
|
||||
printf(zw.c_str());
|
||||
printf("\n");
|
||||
LogFile.WriteToFile(zw);
|
||||
vTaskDelay( xDelay );
|
||||
pfile = fopen(nm, _mode);
|
||||
}
|
||||
return pfile;
|
||||
}
|
||||
|
||||
std::string FormatFileName(std::string input)
|
||||
{
|
||||
#ifdef ISWINDOWS_TRUE
|
||||
@@ -126,14 +209,14 @@ void CopyFile(string input, string output)
|
||||
}
|
||||
|
||||
char cTemp;
|
||||
FILE* fpSourceFile = fopen(input.c_str(), "rb");
|
||||
FILE* fpSourceFile = OpenFileAndWait(input.c_str(), "rb");
|
||||
if (!fpSourceFile) // Sourcefile existiert nicht sonst gibt es einen Fehler beim Kopierversuch!
|
||||
{
|
||||
printf("File %s existiert nicht!\n", input.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
FILE* fpTargetFile = fopen(output.c_str(), "wb");
|
||||
FILE* fpTargetFile = OpenFileAndWait(output.c_str(), "wb");
|
||||
|
||||
// Code Section
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@ void FindReplace(std::string& line, std::string& oldString, std::string& newStri
|
||||
|
||||
void CopyFile(string input, string output);
|
||||
|
||||
FILE* OpenFileAndWait(const char* nm, char* _mode, int _waitsec = 1);
|
||||
|
||||
size_t findDelimiterPos(string input, string delimiter);
|
||||
//string trim(string istring);
|
||||
string trim(string istring, string adddelimiter = "");
|
||||
@@ -25,3 +27,12 @@ string toUpper(string in);
|
||||
float temperatureRead();
|
||||
|
||||
time_t addDays(time_t startTime, int days);
|
||||
|
||||
void memCopyGen(uint8_t* _source, uint8_t* _target, int _size);
|
||||
|
||||
///////////////////////////
|
||||
size_t getInternalESPHeapSize();
|
||||
size_t getESPHeapSize();
|
||||
string getESPHeapInfo();
|
||||
|
||||
/////////////////////////////
|
||||
|
||||
207
code/components/jomjol_image_proc/CAlignAndCutImage.cpp
Normal file
207
code/components/jomjol_image_proc/CAlignAndCutImage.cpp
Normal file
@@ -0,0 +1,207 @@
|
||||
#include "CAlignAndCutImage.h"
|
||||
#include "CRotateImage.h"
|
||||
#include "ClassLogFile.h"
|
||||
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <math.h>
|
||||
#include <algorithm>
|
||||
|
||||
//#define GET_MEMORY malloc
|
||||
#define GET_MEMORY(X) heap_caps_malloc(X, MALLOC_CAP_SPIRAM)
|
||||
|
||||
|
||||
|
||||
CAlignAndCutImage::CAlignAndCutImage(CImageBasis *_org, CImageBasis *_temp)
|
||||
{
|
||||
rgb_image = _org->rgb_image;
|
||||
channels = _org->channels;
|
||||
width = _org->width;
|
||||
height = _org->height;
|
||||
bpp = _org->bpp;
|
||||
externalImage = true;
|
||||
|
||||
islocked = false;
|
||||
|
||||
ImageTMP = _temp;
|
||||
}
|
||||
|
||||
void CAlignAndCutImage::GetRefSize(int *ref_dx, int *ref_dy)
|
||||
{
|
||||
ref_dx[0] = t0_dx;
|
||||
ref_dy[0] = t0_dy;
|
||||
ref_dx[1] = t1_dx;
|
||||
ref_dy[1] = t1_dy;
|
||||
}
|
||||
|
||||
bool CAlignAndCutImage::Align(RefInfo *_temp1, RefInfo *_temp2)
|
||||
{
|
||||
int dx, dy;
|
||||
int r0_x, r0_y, r1_x, r1_y;
|
||||
bool isSimilar1, isSimilar2;
|
||||
|
||||
CFindTemplate* ft = new CFindTemplate(rgb_image, channels, width, height, bpp);
|
||||
|
||||
r0_x = _temp1->target_x;
|
||||
r0_y = _temp1->target_y;
|
||||
printf("Vor ft->FindTemplate(_temp1); %s\n", _temp1->image_file.c_str());
|
||||
isSimilar1 = ft->FindTemplate(_temp1);
|
||||
_temp1->width = ft->tpl_width;
|
||||
_temp1->height = ft->tpl_height;
|
||||
|
||||
r1_x = _temp2->target_x;
|
||||
r1_y = _temp2->target_y;
|
||||
printf("Vor ft->FindTemplate(_temp2); %s\n", _temp2->image_file.c_str());
|
||||
isSimilar2 = ft->FindTemplate(_temp2);
|
||||
_temp2->width = ft->tpl_width;
|
||||
_temp2->height = ft->tpl_height;
|
||||
|
||||
delete ft;
|
||||
|
||||
|
||||
dx = _temp1->target_x - _temp1->found_x;
|
||||
dy = _temp1->target_y - _temp1->found_y;
|
||||
|
||||
r0_x += dx;
|
||||
r0_y += dy;
|
||||
|
||||
r1_x += dx;
|
||||
r1_y += dy;
|
||||
|
||||
float w_org, w_ist, d_winkel;
|
||||
|
||||
w_org = atan2(_temp2->found_y - _temp1->found_y, _temp2->found_x - _temp1->found_x);
|
||||
w_ist = atan2(r1_y - r0_y, r1_x - r0_x);
|
||||
|
||||
d_winkel = (w_ist - w_org) * 180 / M_PI;
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
std::string zw = "\tdx:\t" + std::to_string(dx) + "\tdy:\t" + std::to_string(dy) + "\td_winkel:\t" + std::to_string(d_winkel);
|
||||
zw = zw + "\tt1_x_y:\t" + std::to_string(_temp1->found_x) + "\t" + std::to_string(_temp1->found_y);
|
||||
zw = zw + "\tpara1_found_min_avg_max_SAD:\t" + std::to_string(_temp1->fastalg_min) + "\t" + std::to_string(_temp1->fastalg_avg) + "\t" + std::to_string(_temp1->fastalg_max) + "\t"+ std::to_string(_temp1->fastalg_SAD);
|
||||
zw = zw + "\tt2_x_y:\t" + std::to_string(_temp2->found_x) + "\t" + std::to_string(_temp2->found_y);
|
||||
zw = zw + "\tpara2_found_min_avg_max:\t" + std::to_string(_temp2->fastalg_min) + "\t" + std::to_string(_temp2->fastalg_avg) + "\t" + std::to_string(_temp2->fastalg_max) + "\t"+ std::to_string(_temp2->fastalg_SAD);
|
||||
LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", zw);
|
||||
#endif
|
||||
|
||||
CRotateImage rt(this, ImageTMP);
|
||||
rt.Translate(dx, dy);
|
||||
rt.Rotate(d_winkel, _temp1->target_x, _temp1->target_y);
|
||||
printf("Alignment: dx %d - dy %d - rot %f\n", dx, dy, d_winkel);
|
||||
|
||||
return (isSimilar1 && isSimilar2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void CAlignAndCutImage::CutAndSave(std::string _template1, int x1, int y1, int dx, int dy)
|
||||
{
|
||||
|
||||
int x2, y2;
|
||||
|
||||
x2 = x1 + dx;
|
||||
y2 = y1 + dy;
|
||||
x2 = std::min(x2, width - 1);
|
||||
y2 = std::min(y2, height - 1);
|
||||
|
||||
dx = x2 - x1;
|
||||
dy = y2 - y1;
|
||||
|
||||
int memsize = dx * dy * channels;
|
||||
uint8_t* odata = (unsigned char*) GET_MEMORY(memsize);
|
||||
|
||||
stbi_uc* p_target;
|
||||
stbi_uc* p_source;
|
||||
|
||||
RGBImageLock();
|
||||
|
||||
for (int x = x1; x < x2; ++x)
|
||||
for (int y = y1; y < y2; ++y)
|
||||
{
|
||||
p_target = odata + (channels * ((y - y1) * dx + (x - x1)));
|
||||
p_source = rgb_image + (channels * (y * width + x));
|
||||
for (int _channels = 0; _channels < channels; ++_channels)
|
||||
p_target[_channels] = p_source[_channels];
|
||||
}
|
||||
|
||||
// stbi_write_jpg(_template1.c_str(), dx, dy, channels, odata, 0);
|
||||
stbi_write_bmp(_template1.c_str(), dx, dy, channels, odata);
|
||||
|
||||
RGBImageRelease();
|
||||
|
||||
stbi_image_free(odata);
|
||||
}
|
||||
|
||||
void CAlignAndCutImage::CutAndSave(int x1, int y1, int dx, int dy, CImageBasis *_target)
|
||||
{
|
||||
int x2, y2;
|
||||
|
||||
x2 = x1 + dx;
|
||||
y2 = y1 + dy;
|
||||
x2 = std::min(x2, width - 1);
|
||||
y2 = std::min(y2, height - 1);
|
||||
|
||||
dx = x2 - x1;
|
||||
dy = y2 - y1;
|
||||
|
||||
if ((_target->height != dy) || (_target->width != dx) || (_target->channels != channels))
|
||||
{
|
||||
printf("CAlignAndCutImage::CutAndSave - Bildgröße passt nicht !!!!!!!!!");
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t* odata = _target->RGBImageLock();
|
||||
RGBImageLock();
|
||||
|
||||
stbi_uc* p_target;
|
||||
stbi_uc* p_source;
|
||||
|
||||
for (int x = x1; x < x2; ++x)
|
||||
for (int y = y1; y < y2; ++y)
|
||||
{
|
||||
p_target = odata + (channels * ((y - y1) * dx + (x - x1)));
|
||||
p_source = rgb_image + (channels * (y * width + x));
|
||||
for (int _channels = 0; _channels < channels; ++_channels)
|
||||
p_target[_channels] = p_source[_channels];
|
||||
}
|
||||
|
||||
RGBImageRelease();
|
||||
_target->RGBImageRelease();
|
||||
}
|
||||
|
||||
|
||||
CImageBasis* CAlignAndCutImage::CutAndSave(int x1, int y1, int dx, int dy)
|
||||
{
|
||||
int x2, y2;
|
||||
|
||||
x2 = x1 + dx;
|
||||
y2 = y1 + dy;
|
||||
x2 = std::min(x2, width - 1);
|
||||
y2 = std::min(y2, height - 1);
|
||||
|
||||
dx = x2 - x1;
|
||||
dy = y2 - y1;
|
||||
|
||||
int memsize = dx * dy * channels;
|
||||
uint8_t* odata = (unsigned char*)GET_MEMORY(memsize);
|
||||
|
||||
stbi_uc* p_target;
|
||||
stbi_uc* p_source;
|
||||
|
||||
RGBImageLock();
|
||||
|
||||
for (int x = x1; x < x2; ++x)
|
||||
for (int y = y1; y < y2; ++y)
|
||||
{
|
||||
p_target = odata + (channels * ((y - y1) * dx + (x - x1)));
|
||||
p_source = rgb_image + (channels * (y * width + x));
|
||||
for (int _channels = 0; _channels < channels; ++_channels)
|
||||
p_target[_channels] = p_source[_channels];
|
||||
}
|
||||
|
||||
CImageBasis* rs = new CImageBasis(odata, channels, dx, dy, bpp);
|
||||
RGBImageRelease();
|
||||
rs->SetIndepended();
|
||||
return rs;
|
||||
}
|
||||
21
code/components/jomjol_image_proc/CAlignAndCutImage.h
Normal file
21
code/components/jomjol_image_proc/CAlignAndCutImage.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#include "CImageBasis.h"
|
||||
#include "CFindTemplate.h"
|
||||
|
||||
|
||||
class CAlignAndCutImage : public CImageBasis
|
||||
{
|
||||
public:
|
||||
int t0_dx, t0_dy, t1_dx, t1_dy;
|
||||
CImageBasis *ImageTMP;
|
||||
CAlignAndCutImage(std::string _image) : CImageBasis(_image) {ImageTMP = NULL;};
|
||||
CAlignAndCutImage(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp) : CImageBasis(_rgb_image, _channels, _width, _height, _bpp) {ImageTMP = NULL;};
|
||||
CAlignAndCutImage(CImageBasis *_org, CImageBasis *_temp);
|
||||
|
||||
bool Align(RefInfo *_temp1, RefInfo *_temp2);
|
||||
// void Align(std::string _template1, int x1, int y1, std::string _template2, int x2, int y2, int deltax = 40, int deltay = 40, std::string imageROI = "");
|
||||
void CutAndSave(std::string _template1, int x1, int y1, int dx, int dy);
|
||||
CImageBasis* CutAndSave(int x1, int y1, int dx, int dy);
|
||||
void CutAndSave(int x1, int y1, int dx, int dy, CImageBasis *_target);
|
||||
void GetRefSize(int *ref_dx, int *ref_dy);
|
||||
};
|
||||
|
||||
@@ -1,547 +1,185 @@
|
||||
#include "CFindTemplate.h"
|
||||
#include "Helper.h"
|
||||
|
||||
#include "ClassLogFile.h"
|
||||
|
||||
#include "esp_system.h"
|
||||
// #define DEBUG_DETAIL_ON
|
||||
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <math.h>
|
||||
#include <algorithm>
|
||||
|
||||
#define _ESP32_PSRAM
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define GET_MEMORY malloc
|
||||
|
||||
/*
|
||||
CResizeImage::CResizeImage(std::string _image, int _new_dx, int _new_dy)
|
||||
bool CFindTemplate::FindTemplate(RefInfo *_ref)
|
||||
{
|
||||
CImageBasis::CImageBasis(_image);
|
||||
}
|
||||
*/
|
||||
uint8_t* rgb_template = stbi_load(_ref->image_file.c_str(), &tpl_width, &tpl_height, &tpl_bpp, channels);
|
||||
|
||||
uint8_t CImageBasis::GetPixelColor(int x, int y, int ch)
|
||||
{
|
||||
stbi_uc* p_source;
|
||||
p_source = this->rgb_image + (this->channels * (y * this->width + x));
|
||||
return p_source[ch];
|
||||
}
|
||||
|
||||
void CResizeImage::Resize(int _new_dx, int _new_dy)
|
||||
{
|
||||
int memsize = _new_dx * _new_dy * this->channels;
|
||||
uint8_t* odata = (unsigned char*)GET_MEMORY(memsize);
|
||||
|
||||
stbir_resize_uint8(this->rgb_image, this->width, this->height, 0, odata, _new_dx, _new_dy, 0, this->channels);
|
||||
|
||||
stbi_image_free(this->rgb_image);
|
||||
this->rgb_image = (unsigned char*)GET_MEMORY(memsize);
|
||||
|
||||
this->memCopy(odata, this->rgb_image, memsize);
|
||||
this->width = _new_dx;
|
||||
this->height = _new_dy;
|
||||
stbi_image_free(odata);
|
||||
}
|
||||
|
||||
void CRotate::Mirror(){
|
||||
int memsize = this->width * this->height * this->channels;
|
||||
uint8_t* odata = (unsigned char*)GET_MEMORY(memsize);
|
||||
|
||||
int x_source, y_source;
|
||||
stbi_uc* p_target;
|
||||
stbi_uc* p_source;
|
||||
|
||||
for (int x = 0; x < this->width; ++x)
|
||||
for (int y = 0; y < this->height; ++y)
|
||||
{
|
||||
p_target = odata + (this->channels * (y * this->width + x));
|
||||
|
||||
x_source = this->width - x;
|
||||
y_source = y;
|
||||
|
||||
p_source = this->rgb_image + (this->channels * (y_source * this->width + x_source));
|
||||
for (int channels = 0; channels < this->channels; ++channels)
|
||||
p_target[channels] = p_source[channels];
|
||||
}
|
||||
|
||||
// memcpy(this->rgb_image, odata, memsize);
|
||||
this->memCopy(odata, this->rgb_image, memsize);
|
||||
stbi_image_free(odata);
|
||||
}
|
||||
|
||||
void CRotate::Rotate(float _angle, int _centerx, int _centery)
|
||||
{
|
||||
float m[2][3];
|
||||
|
||||
float x_center = _centerx;
|
||||
float y_center = _centery;
|
||||
_angle = _angle / 180 * M_PI;
|
||||
|
||||
m[0][0] = cos(_angle);
|
||||
m[0][1] = sin(_angle);
|
||||
m[0][2] = (1 - m[0][0]) * x_center - m[0][1] * y_center;
|
||||
|
||||
m[1][0] = -m[0][1];
|
||||
m[1][1] = m[0][0];
|
||||
m[1][2] = m[0][1] * x_center + (1 - m[0][0]) * y_center;
|
||||
|
||||
int memsize = this->width * this->height * this->channels;
|
||||
uint8_t* odata = (unsigned char*)GET_MEMORY(memsize);
|
||||
|
||||
int x_source, y_source;
|
||||
stbi_uc* p_target;
|
||||
stbi_uc* p_source;
|
||||
|
||||
for (int x = 0; x < this->width; ++x)
|
||||
for (int y = 0; y < this->height; ++y)
|
||||
{
|
||||
p_target = odata + (this->channels * (y * this->width + x));
|
||||
|
||||
x_source = int(m[0][0] * x + m[0][1] * y);
|
||||
y_source = int(m[1][0] * x + m[1][1] * y);
|
||||
|
||||
x_source += int(m[0][2]);
|
||||
y_source += int(m[1][2]);
|
||||
|
||||
if ((x_source >= 0) && (x_source < this->width) && (y_source >= 0) && (y_source < this->height))
|
||||
{
|
||||
p_source = this->rgb_image + (this->channels * (y_source * this->width + x_source));
|
||||
for (int channels = 0; channels < this->channels; ++channels)
|
||||
p_target[channels] = p_source[channels];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int channels = 0; channels < this->channels; ++channels)
|
||||
p_target[channels] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
// memcpy(this->rgb_image, odata, memsize);
|
||||
this->memCopy(odata, this->rgb_image, memsize);
|
||||
stbi_image_free(odata);
|
||||
}
|
||||
|
||||
void CRotate::Rotate(float _angle)
|
||||
{
|
||||
this->Rotate(_angle, this->width / 2, this->height / 2);
|
||||
}
|
||||
|
||||
void CRotate::Translate(int _dx, int _dy)
|
||||
{
|
||||
int memsize = this->width * this->height * this->channels;
|
||||
uint8_t* odata = (unsigned char*)GET_MEMORY(memsize);
|
||||
|
||||
|
||||
int x_source, y_source;
|
||||
stbi_uc* p_target;
|
||||
stbi_uc* p_source;
|
||||
|
||||
for (int x = 0; x < this->width; ++x)
|
||||
for (int y = 0; y < this->height; ++y)
|
||||
{
|
||||
p_target = odata + (this->channels * (y * this->width + x));
|
||||
|
||||
x_source = x - _dx;
|
||||
y_source = y - _dy;
|
||||
|
||||
if ((x_source >= 0) && (x_source < this->width) && (y_source >= 0) && (y_source < this->height))
|
||||
{
|
||||
p_source = this->rgb_image + (this->channels * (y_source * this->width + x_source));
|
||||
for (int channels = 0; channels < this->channels; ++channels)
|
||||
p_target[channels] = p_source[channels];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int channels = 0; channels < this->channels; ++channels)
|
||||
p_target[channels] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
// memcpy(this->rgb_image, odata, memsize);
|
||||
this->memCopy(odata, this->rgb_image, memsize);
|
||||
stbi_image_free(odata);
|
||||
}
|
||||
|
||||
|
||||
|
||||
CFindTemplate::CFindTemplate(std::string _image)
|
||||
{
|
||||
this->channels = 1;
|
||||
this->rgb_image = stbi_load(_image.c_str(), &(this->width), &(this->height), &(this->bpp), this->channels);
|
||||
}
|
||||
|
||||
void CFindTemplate::FindTemplate(std::string _template, int* found_x, int* found_y)
|
||||
{
|
||||
this->FindTemplate(_template, found_x, found_y, 0, 0);
|
||||
}
|
||||
|
||||
void CFindTemplate::FindTemplate(std::string _template, int* found_x, int* found_y, int _dx, int _dy)
|
||||
{
|
||||
uint8_t* rgb_template = stbi_load(_template.c_str(), &tpl_width, &tpl_height, &tpl_bpp, this->channels);
|
||||
// printf("FindTemplate 01\n");
|
||||
|
||||
int ow, ow_start, ow_stop;
|
||||
int oh, oh_start, oh_stop;
|
||||
|
||||
if (_dx == 0)
|
||||
if (_ref->search_x == 0)
|
||||
{
|
||||
_dx = this->width;
|
||||
*found_x = 0;
|
||||
_ref->search_x = width;
|
||||
_ref->found_x = 0;
|
||||
}
|
||||
|
||||
if (_dy == 0)
|
||||
if (_ref->search_y == 0)
|
||||
{
|
||||
_dy = this->height;
|
||||
*found_y = 0;
|
||||
_ref->search_y = height;
|
||||
_ref->found_y = 0;
|
||||
}
|
||||
|
||||
|
||||
ow_start = *found_x - _dx;
|
||||
ow_start = _ref->target_x - _ref->search_x;
|
||||
ow_start = std::max(ow_start, 0);
|
||||
ow_stop = *found_x + _dx;
|
||||
if ((ow_stop + tpl_width) > this->width)
|
||||
ow_stop = this->width - tpl_width;
|
||||
ow_stop = _ref->target_x + _ref->search_x;
|
||||
if ((ow_stop + tpl_width) > width)
|
||||
ow_stop = width - tpl_width;
|
||||
ow = ow_stop - ow_start + 1;
|
||||
|
||||
oh_start = *found_y - _dy;
|
||||
oh_start = _ref->target_y - _ref->search_y;
|
||||
oh_start = std::max(oh_start, 0);
|
||||
oh_stop = *found_y + _dy;
|
||||
if ((oh_stop + tpl_height) > this->height)
|
||||
oh_stop = this->height - tpl_height;
|
||||
oh_stop = _ref->target_y + _ref->search_y;
|
||||
if ((oh_stop + tpl_height) > height)
|
||||
oh_stop = height - tpl_height;
|
||||
oh = oh_stop - oh_start + 1;
|
||||
|
||||
uint8_t* odata = (unsigned char*)GET_MEMORY(ow * oh * this->channels);
|
||||
float avg, SAD;
|
||||
int min, max;
|
||||
bool isSimilar = false;
|
||||
|
||||
// printf("FindTemplate 02\n");
|
||||
|
||||
if ((_ref->alignment_algo == 2) && (_ref->fastalg_x > -1) && (_ref->fastalg_y > -1)) // für Testzwecke immer Berechnen
|
||||
{
|
||||
isSimilar = CalculateSimularities(rgb_template, _ref->fastalg_x, _ref->fastalg_y, ow, oh, min, avg, max, SAD, _ref->fastalg_SAD, _ref->fastalg_SAD_criteria);
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
std::string zw = "\t" + _ref->image_file + "\tt1_x_y:\t" + std::to_string(_ref->fastalg_x) + "\t" + std::to_string(_ref->fastalg_y);
|
||||
zw = zw + "\tpara1_found_min_avg_max_SAD:\t" + std::to_string(min) + "\t" + std::to_string(avg) + "\t" + std::to_string(max) + "\t"+ std::to_string(SAD);
|
||||
LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", zw);
|
||||
#endif
|
||||
}
|
||||
|
||||
// printf("FindTemplate 03\n");
|
||||
|
||||
|
||||
if (isSimilar)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteToFile("Use FastAlignment sucessfull");
|
||||
#endif
|
||||
_ref->found_x = _ref->fastalg_x;
|
||||
_ref->found_y = _ref->fastalg_y;
|
||||
return true;
|
||||
}
|
||||
|
||||
// printf("FindTemplate 04\n");
|
||||
|
||||
|
||||
double aktSAD;
|
||||
double minSAD = pow(tpl_width * tpl_height * 255, 2);
|
||||
|
||||
for (int xouter = ow_start; xouter <= ow_stop; xouter++)
|
||||
for (int youter = oh_start; youter <= oh_stop; ++youter)
|
||||
RGBImageLock();
|
||||
|
||||
// printf("FindTemplate 05\n");
|
||||
int xouter, youter, tpl_x, tpl_y, _ch;
|
||||
int _anzchannels = channels;
|
||||
if (_ref->alignment_algo == 0) // 0 = "Default" (nur R-Kanal)
|
||||
_anzchannels = 1;
|
||||
|
||||
for (xouter = ow_start; xouter <= ow_stop; xouter++)
|
||||
for (youter = oh_start; youter <= oh_stop; ++youter)
|
||||
{
|
||||
aktSAD = 0;
|
||||
for (int tpl_x = 0; tpl_x < tpl_width; tpl_x++)
|
||||
for (int tpl_y = 0; tpl_y < tpl_height; tpl_y++)
|
||||
for (tpl_x = 0; tpl_x < tpl_width; tpl_x++)
|
||||
for (tpl_y = 0; tpl_y < tpl_height; tpl_y++)
|
||||
{
|
||||
stbi_uc* p_org = this->rgb_image + (this->channels * ((youter + tpl_y) * this->width + (xouter + tpl_x)));
|
||||
stbi_uc* p_tpl = rgb_template + (this->channels * (tpl_y * tpl_width + tpl_x));
|
||||
aktSAD += pow(p_tpl[0] - p_org[0], 2);
|
||||
stbi_uc* p_org = rgb_image + (channels * ((youter + tpl_y) * width + (xouter + tpl_x)));
|
||||
stbi_uc* p_tpl = rgb_template + (channels * (tpl_y * tpl_width + tpl_x));
|
||||
for (_ch = 0; _ch < _anzchannels; ++_ch)
|
||||
{
|
||||
aktSAD += pow(p_tpl[_ch] - p_org[_ch], 2);
|
||||
}
|
||||
}
|
||||
stbi_uc* p_out = odata + (this->channels * ((youter - oh_start) * ow + (xouter - ow_start)));
|
||||
|
||||
p_out[0] = int(sqrt(aktSAD / (tpl_width * tpl_height)));
|
||||
if (aktSAD < minSAD)
|
||||
{
|
||||
minSAD = aktSAD;
|
||||
*found_x = xouter;
|
||||
*found_y = youter;
|
||||
_ref->found_x = xouter;
|
||||
_ref->found_y = youter;
|
||||
}
|
||||
}
|
||||
|
||||
stbi_write_bmp("sdcard\\find.bmp", ow, oh, this->channels, odata);
|
||||
|
||||
stbi_image_free(odata);
|
||||
stbi_image_free(rgb_template);
|
||||
}
|
||||
|
||||
void CFindTemplate::FindTemplate(std::string _template, int* found_x, int* found_y, std::string _imageout)
|
||||
{
|
||||
this->FindTemplate(_template, found_x, found_y);
|
||||
this->SaveToFile(_imageout);
|
||||
}
|
||||
|
||||
void CFindTemplate::FindTemplate(std::string _template, int* found_x, int* found_y, int _dx, int _dy, std::string _imageout)
|
||||
{
|
||||
this->FindTemplate(_template, found_x, found_y, _dx, _dy);
|
||||
this->SaveToFile(_imageout);
|
||||
}
|
||||
// printf("FindTemplate 06\n");
|
||||
|
||||
|
||||
|
||||
void CImageBasis::memCopy(uint8_t* _source, uint8_t* _target, int _size)
|
||||
{
|
||||
#ifdef _ESP32_PSRAM
|
||||
for (int i = 0; i < _size; ++i)
|
||||
*(_target + i) = *(_source + i);
|
||||
#else
|
||||
memcpy(_target, _source, _size);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool CImageBasis::isInImage(int x, int y)
|
||||
{
|
||||
if ((x < 0) || (x > this->width - 1))
|
||||
return false;
|
||||
|
||||
if ((y < 0) || (y > this->height- 1))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CImageBasis::setPixelColor(int x, int y, int r, int g, int b)
|
||||
{
|
||||
stbi_uc* p_source;
|
||||
|
||||
p_source = this->rgb_image + (this->channels * (y * this->width + x));
|
||||
p_source[0] = r;
|
||||
if (this-> channels > 2)
|
||||
{
|
||||
p_source[1] = g;
|
||||
p_source[2] = b;
|
||||
}
|
||||
}
|
||||
|
||||
void CImageBasis::drawRect(int x, int y, int dx, int dy, int r, int g, int b, int thickness)
|
||||
{
|
||||
int zwx1, zwx2, zwy1, zwy2;
|
||||
int _x, _y, _thick;
|
||||
|
||||
zwx1 = x - thickness + 1;
|
||||
zwx2 = x + dx + thickness - 1;
|
||||
zwy1 = y;
|
||||
zwy2 = y;
|
||||
for (_thick = 0; _thick < thickness; _thick++)
|
||||
for (_x = zwx1; _x <= zwx2; ++_x)
|
||||
for (_y = zwy1; _y <= zwy2; _y++)
|
||||
if (isInImage(_x, _y))
|
||||
setPixelColor(_x, _y - _thick, r, g, b);
|
||||
|
||||
zwx1 = x - thickness + 1;
|
||||
zwx2 = x + dx + thickness - 1;
|
||||
zwy1 = y + dy;
|
||||
zwy2 = y + dy;
|
||||
for (_thick = 0; _thick < thickness; _thick++)
|
||||
for (_x = zwx1; _x <= zwx2; ++_x)
|
||||
for (_y = zwy1; _y <= zwy2; _y++)
|
||||
if (isInImage(_x, _y))
|
||||
setPixelColor(_x, _y + _thick, r, g, b);
|
||||
|
||||
zwx1 = x;
|
||||
zwx2 = x;
|
||||
zwy1 = y;
|
||||
zwy2 = y + dy;
|
||||
for (_thick = 0; _thick < thickness; _thick++)
|
||||
for (_x = zwx1; _x <= zwx2; ++_x)
|
||||
for (_y = zwy1; _y <= zwy2; _y++)
|
||||
if (isInImage(_x, _y))
|
||||
setPixelColor(_x - _thick, _y, r, g, b);
|
||||
|
||||
zwx1 = x + dx;
|
||||
zwx2 = x + dx;
|
||||
zwy1 = y;
|
||||
zwy2 = y + dy;
|
||||
for (_thick = 0; _thick < thickness; _thick++)
|
||||
for (_x = zwx1; _x <= zwx2; ++_x)
|
||||
for (_y = zwy1; _y <= zwy2; _y++)
|
||||
if (isInImage(_x, _y))
|
||||
setPixelColor(_x + _thick, _y, r, g, b);
|
||||
|
||||
}
|
||||
|
||||
void CImageBasis::drawLine(int x1, int y1, int x2, int y2, int r, int g, int b, int thickness)
|
||||
{
|
||||
int _x, _y, _thick;
|
||||
int _zwy1, _zwy2;
|
||||
thickness = (thickness-1) / 2;
|
||||
|
||||
for (_thick = 0; _thick <= thickness; ++_thick)
|
||||
for (_x = x1 - _thick; _x <= x2 + _thick; ++_x)
|
||||
{
|
||||
if (x2 == x1)
|
||||
{
|
||||
_zwy1 = y1;
|
||||
_zwy2 = y2;
|
||||
}
|
||||
else
|
||||
{
|
||||
_zwy1 = (y2 - y1) * (float)(_x - x1) / (float)(x2 - x1) + y1;
|
||||
_zwy2 = (y2 - y1) * (float)(_x + 1 - x1) / (float)(x2 - x1) + y1;
|
||||
}
|
||||
|
||||
for (_y = _zwy1 - _thick; _y <= _zwy2 + _thick; _y++)
|
||||
if (isInImage(_x, _y))
|
||||
setPixelColor(_x, _y, r, g, b);
|
||||
}
|
||||
}
|
||||
|
||||
void CImageBasis::drawCircle(int x1, int y1, int rad, int r, int g, int b, int thickness)
|
||||
{
|
||||
float deltarad, aktrad;
|
||||
int _thick, _x, _y;
|
||||
|
||||
deltarad = 1 / (4 * M_PI * (rad + thickness - 1));
|
||||
|
||||
for (aktrad = 0; aktrad <= (2 * M_PI); aktrad += deltarad)
|
||||
for (_thick = 0; _thick < thickness; ++_thick)
|
||||
{
|
||||
_x = sin(aktrad) * (rad + _thick) + x1;
|
||||
_y = cos(aktrad) * (rad + _thick) + y1;
|
||||
if (isInImage(_x, _y))
|
||||
setPixelColor(_x, _y, r, g, b);
|
||||
}
|
||||
}
|
||||
|
||||
CImageBasis::CImageBasis()
|
||||
{
|
||||
this->externalImage = false;
|
||||
}
|
||||
|
||||
CImageBasis::CImageBasis(std::string _image)
|
||||
{
|
||||
channels = 3;
|
||||
externalImage = false;
|
||||
filename = _image;
|
||||
// long freebefore = esp_get_free_heap_size();
|
||||
|
||||
rgb_image = stbi_load(_image.c_str(), &width, &height, &bpp, channels);
|
||||
// if (rgb_image == NULL)
|
||||
// LogFile.WriteToFile("Image Load failed:" + _image + " FreeHeapSize before: " + to_string(freebefore) + " after: " + to_string(esp_get_free_heap_size()));
|
||||
// printf("CImageBasis after load\n");
|
||||
// printf("w %d, h %d, b %d, c %d", this->width, this->height, this->bpp, this->channels);
|
||||
}
|
||||
|
||||
bool CImageBasis::ImageOkay(){
|
||||
return rgb_image != NULL;
|
||||
}
|
||||
|
||||
CImageBasis::CImageBasis(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp)
|
||||
{
|
||||
this->rgb_image = _rgb_image;
|
||||
this->channels = _channels;
|
||||
this->width = _width;
|
||||
this->height = _height;
|
||||
this->bpp = _bpp;
|
||||
this->externalImage = true;
|
||||
}
|
||||
|
||||
void CImageBasis::Contrast(float _contrast) //input range [-100..100]
|
||||
{
|
||||
stbi_uc* p_source;
|
||||
|
||||
float contrast = (_contrast/100) + 1; //convert to decimal & shift range: [0..2]
|
||||
float intercept = 128 * (1 - contrast);
|
||||
|
||||
for (int x = 0; x < width; ++x)
|
||||
for (int y = 0; y < height; ++y)
|
||||
{
|
||||
p_source = this->rgb_image + (this->channels * (y * this->width + x));
|
||||
for (int channels = 0; channels < this->channels; ++channels)
|
||||
p_source[channels] = (uint8_t) std::min(255, std::max(0, (int) (p_source[channels] * contrast + intercept)));
|
||||
}
|
||||
}
|
||||
|
||||
CImageBasis::~CImageBasis()
|
||||
{
|
||||
if (!this->externalImage)
|
||||
stbi_image_free(this->rgb_image);
|
||||
}
|
||||
|
||||
void CImageBasis::SaveToFile(std::string _imageout)
|
||||
{
|
||||
string typ = getFileType(_imageout);
|
||||
|
||||
if ((typ == "jpg") || (typ == "JPG")) // ACHTUNG PROBLEMATISCH IM ESP32
|
||||
{
|
||||
stbi_write_jpg(_imageout.c_str(), this->width, this->height, this->channels, this->rgb_image, 0);
|
||||
}
|
||||
|
||||
if ((typ == "bmp") || (typ == "BMP"))
|
||||
{
|
||||
stbi_write_bmp(_imageout.c_str(), this->width, this->height, this->channels, this->rgb_image);
|
||||
}
|
||||
// stbi_write_jpg(_imageout.c_str(), this->width, this->height, this->channels, this->rgb_image, 0);
|
||||
// stbi_write_bmp(_imageout.c_str(), this->width, this->height, this->channels, this->rgb_image);
|
||||
}
|
||||
if (_ref->alignment_algo == 2)
|
||||
CalculateSimularities(rgb_template, _ref->found_x, _ref->found_y, ow, oh, min, avg, max, SAD, _ref->fastalg_SAD, _ref->fastalg_SAD_criteria);
|
||||
|
||||
|
||||
// printf("FindTemplate 07\n");
|
||||
|
||||
void CAlignAndCutImage::Align(std::string _template0, int ref0_x, int ref0_y, std::string _template1, int ref1_x, int ref1_y, int deltax, int deltay, std::string imageROI)
|
||||
{
|
||||
int dx, dy;
|
||||
int r0_x, r0_y, r1_x, r1_y;
|
||||
|
||||
CFindTemplate* ft = new CFindTemplate(this->filename);
|
||||
|
||||
r0_x = ref0_x;
|
||||
r0_y = ref0_y;
|
||||
ft->FindTemplate(_template0, &r0_x, &r0_y, deltax, deltay);
|
||||
t0_dx = ft->tpl_width;
|
||||
t0_dy = ft->tpl_height;
|
||||
|
||||
r1_x = ref1_x;
|
||||
r1_y = ref1_y;
|
||||
ft->FindTemplate(_template1, &r1_x, &r1_y, deltax, deltay);
|
||||
t1_dx = ft->tpl_width;
|
||||
t1_dy = ft->tpl_height;
|
||||
|
||||
delete ft;
|
||||
_ref->fastalg_x = _ref->found_x;
|
||||
_ref->fastalg_y = _ref->found_y;
|
||||
_ref->fastalg_min = min;
|
||||
_ref->fastalg_avg = avg;
|
||||
_ref->fastalg_max = max;
|
||||
_ref->fastalg_SAD = SAD;
|
||||
|
||||
|
||||
dx = ref0_x - r0_x;
|
||||
dy = ref0_y - r0_y;
|
||||
|
||||
r0_x += dx;
|
||||
r0_y += dy;
|
||||
|
||||
r1_x += dx;
|
||||
r1_y += dy;
|
||||
|
||||
float w_org, w_ist, d_winkel;
|
||||
|
||||
w_org = atan2(ref1_y - ref0_y, ref1_x - ref0_x);
|
||||
w_ist = atan2(r1_y - r0_y, r1_x - r0_x);
|
||||
|
||||
d_winkel = (w_org - w_ist) * 180 / M_PI;
|
||||
|
||||
if (imageROI.length() > 0)
|
||||
{
|
||||
CImageBasis* imgzw = new CImageBasis(this->filename);
|
||||
imgzw->drawRect(r0_x, r0_y, t0_dx, t0_dy, 255, 0, 0, 2);
|
||||
imgzw->drawRect(r1_x, r1_y, t1_dx, t1_dy, 255, 0, 0, 2);
|
||||
imgzw->SaveToFile(imageROI);
|
||||
printf("Alignment: alignment ROI created: %s\n", imageROI.c_str());
|
||||
delete imgzw;
|
||||
}
|
||||
|
||||
string zw = "\tdx:\t" + to_string(dx) + "\tdy:\t" + to_string(dy) + "\td_winkel:\t" + to_string(d_winkel);
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
std::string zw = "\t" + _ref->image_file + "\tt1_x_y:\t" + std::to_string(_ref->fastalg_x) + "\t" + std::to_string(_ref->fastalg_y);
|
||||
zw = zw + "\tpara1_found_min_avg_max_SAD:\t" + std::to_string(min) + "\t" + std::to_string(avg) + "\t" + std::to_string(max) + "\t"+ std::to_string(SAD);
|
||||
LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", zw);
|
||||
#endif
|
||||
|
||||
CRotate rt(this->rgb_image, this->channels, this->width, this->height, this->bpp);
|
||||
rt.Translate(dx, dy);
|
||||
rt.Rotate(d_winkel, ref0_x, ref0_y);
|
||||
printf("Alignment: dx %d - dy %d - rot %f\n", dx, dy, d_winkel);
|
||||
RGBImageRelease();
|
||||
stbi_image_free(rgb_template);
|
||||
|
||||
// printf("FindTemplate 08\n");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CAlignAndCutImage::CutAndSave(std::string _template1, int x1, int y1, int dx, int dy)
|
||||
|
||||
|
||||
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;
|
||||
int minDif = 255;
|
||||
int maxDif = -255;
|
||||
double avgDifSum = 0;
|
||||
long int anz = 0;
|
||||
double aktSAD = 0;
|
||||
|
||||
int x2, y2;
|
||||
int xouter, youter, _ch;
|
||||
|
||||
x2 = x1 + dx;
|
||||
y2 = y1 + dy;
|
||||
x2 = min(x2, this->width - 1);
|
||||
y2 = min(y2, this->height - 1);
|
||||
|
||||
dx = x2 - x1;
|
||||
dy = y2 - y1;
|
||||
|
||||
int memsize = dx * dy * this->channels;
|
||||
uint8_t* odata = (unsigned char*)GET_MEMORY(memsize);
|
||||
|
||||
stbi_uc* p_target;
|
||||
stbi_uc* p_source;
|
||||
|
||||
for (int x = x1; x < x2; ++x)
|
||||
for (int y = y1; y < y2; ++y)
|
||||
for (xouter = 0; xouter <= _sizex; xouter++)
|
||||
for (youter = 0; youter <= _sizey; ++youter)
|
||||
{
|
||||
p_target = odata + (this->channels * ((y - y1) * dx + (x - x1)));
|
||||
p_source = this->rgb_image + (this->channels * (y * this->width + x));
|
||||
for (int channels = 0; channels < this->channels; ++channels)
|
||||
p_target[channels] = p_source[channels];
|
||||
stbi_uc* p_org = rgb_image + (channels * ((youter + _starty) * width + (xouter + _startx)));
|
||||
stbi_uc* p_tpl = _rgb_tmpl + (channels * (youter * tpl_width + xouter));
|
||||
for (_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++;
|
||||
}
|
||||
}
|
||||
|
||||
// stbi_write_jpg(_template1.c_str(), dx, dy, this->channels, odata, 0);
|
||||
stbi_write_bmp(_template1.c_str(), dx, dy, this->channels, odata);
|
||||
avg = avgDifSum / anz;
|
||||
min = minDif;
|
||||
max = maxDif;
|
||||
SAD = sqrt(aktSAD) / anz;
|
||||
|
||||
stbi_image_free(odata);
|
||||
float _SADdif = abs(SAD - _SADold);
|
||||
|
||||
printf("Anzahl %ld, avgDifSum %fd, avg %f, SAD_neu: %fd, _SAD_old: %f, _SAD_crit:%f\n", anz, avgDifSum, avg, SAD, _SADold, _SADdif);
|
||||
|
||||
if (_SADdif <= _SADcrit)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,98 +1,40 @@
|
||||
#pragma once
|
||||
#ifndef __CFINDTEMPLATE_CLASS
|
||||
#define __CFINDTEMPLATE_CLASS
|
||||
|
||||
#include "CImageBasis.h"
|
||||
|
||||
#ifndef __CFINDTEMPLATE
|
||||
#define __CFINGTEMPLATE
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <math.h>
|
||||
|
||||
#include "stb_image.h"
|
||||
#include "stb_image_write.h"
|
||||
#include "stb_image_resize.h"
|
||||
|
||||
|
||||
class CImageBasis
|
||||
{
|
||||
protected:
|
||||
uint8_t* rgb_image;
|
||||
int channels;
|
||||
int width, height, bpp;
|
||||
bool externalImage;
|
||||
std::string filename;
|
||||
|
||||
void memCopy(uint8_t* _source, uint8_t* _target, int _size);
|
||||
bool isInImage(int x, int y);
|
||||
|
||||
public:
|
||||
int getWidth(){return this->width;};
|
||||
int getHeight(){return this->height;};
|
||||
int getChannels(){return this->channels;};
|
||||
void drawRect(int x, int y, int dx, int dy, int r = 255, int g = 255, int b = 255, int thickness = 1);
|
||||
void drawLine(int x1, int y1, int x2, int y2, int r, int g, int b, int thickness = 1);
|
||||
void drawCircle(int x1, int y1, int rad, int r, int g, int b, int thickness = 1);
|
||||
void setPixelColor(int x, int y, int r, int g, int b);
|
||||
void Contrast(float _contrast);
|
||||
bool ImageOkay();
|
||||
|
||||
|
||||
CImageBasis();
|
||||
CImageBasis(std::string _image);
|
||||
CImageBasis(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp);
|
||||
uint8_t GetPixelColor(int x, int y, int ch);
|
||||
|
||||
~CImageBasis();
|
||||
|
||||
void SaveToFile(std::string _imageout);
|
||||
struct RefInfo {
|
||||
std::string image_file;
|
||||
int target_x = 0;
|
||||
int target_y = 0;
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
int found_x;
|
||||
int found_y;
|
||||
int search_x;
|
||||
int search_y;
|
||||
int fastalg_x = -1;
|
||||
int fastalg_y = -1;
|
||||
int fastalg_min = -256;
|
||||
float fastalg_avg = -1;
|
||||
int fastalg_max = -1;
|
||||
float fastalg_SAD = -1;
|
||||
float fastalg_SAD_criteria = -1;
|
||||
int alignment_algo = 0; // 0 = "Default" (nur R-Kanal), 1 = "HighAccurity" (RGB-Kanal), 2 = "Fast" (1.x RGB, dann isSimilar)
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class CFindTemplate : public CImageBasis
|
||||
{
|
||||
public:
|
||||
int tpl_width, tpl_height, tpl_bpp;
|
||||
CFindTemplate(std::string _image);
|
||||
CFindTemplate(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp) : CImageBasis(_rgb_image, _channels, _width, _height, _bpp) {};
|
||||
|
||||
void FindTemplate(std::string _template, int* found_x, int* found_y, std::string _imageout);
|
||||
void FindTemplate(std::string _template, int* found_x, int* found_y, int _dx, int _dy, std::string _imageout);
|
||||
void FindTemplate(std::string _template, int* found_x, int* found_y);
|
||||
void FindTemplate(std::string _template, int* found_x, int* found_y, int _dx, int _dy);
|
||||
bool FindTemplate(RefInfo *_ref);
|
||||
|
||||
bool 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);
|
||||
};
|
||||
|
||||
class CRotate: public CImageBasis
|
||||
{
|
||||
public:
|
||||
CRotate(std::string _image) : CImageBasis(_image) {};
|
||||
CRotate(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp) : CImageBasis(_rgb_image, _channels, _width, _height, _bpp) {};
|
||||
|
||||
void Rotate(float _angle);
|
||||
void Rotate(float _angle, int _centerx, int _centery);
|
||||
void Translate(int _dx, int _dy);
|
||||
void Mirror();
|
||||
};
|
||||
|
||||
|
||||
class CAlignAndCutImage : public CImageBasis
|
||||
{
|
||||
public:
|
||||
int t0_dx, t0_dy, t1_dx, t1_dy;
|
||||
CAlignAndCutImage(std::string _image) : CImageBasis(_image) {};
|
||||
|
||||
void Align(std::string _template1, int x1, int y1, std::string _template2, int x2, int y2, int deltax = 40, int deltay = 40, std::string imageROI = "");
|
||||
void CutAndSave(std::string _template1, int x1, int y1, int dx, int dy);
|
||||
};
|
||||
|
||||
|
||||
class CResizeImage : public CImageBasis
|
||||
{
|
||||
public:
|
||||
CResizeImage(std::string _image) : CImageBasis(_image) {};
|
||||
// CResizeImage(std::string _image, int _new_dx, int _new_dy);
|
||||
void Resize(int _new_dx, int _new_dy);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
523
code/components/jomjol_image_proc/CImageBasis.cpp
Normal file
523
code/components/jomjol_image_proc/CImageBasis.cpp
Normal file
@@ -0,0 +1,523 @@
|
||||
#include "CImageBasis.h"
|
||||
#include "Helper.h"
|
||||
#include "ClassLogFile.h"
|
||||
|
||||
#include <esp_log.h>
|
||||
|
||||
#include "esp_system.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <math.h>
|
||||
#include <algorithm>
|
||||
|
||||
#define _ESP32_PSRAM
|
||||
|
||||
using namespace std;
|
||||
|
||||
static const char *TAG = "CImageBasis";
|
||||
|
||||
//#define DEBUG_DETAIL_ON
|
||||
|
||||
|
||||
|
||||
uint8_t * CImageBasis::RGBImageLock(int _waitmaxsec)
|
||||
{
|
||||
if (islocked)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
printf("Image is locked: sleep for : %ds\n", _waitmaxsec);
|
||||
#endif
|
||||
TickType_t xDelay;
|
||||
xDelay = 1000 / portTICK_PERIOD_MS;
|
||||
for (int i = 0; i <= _waitmaxsec; ++i)
|
||||
{
|
||||
vTaskDelay( xDelay );
|
||||
if (!islocked)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (islocked)
|
||||
return NULL;
|
||||
|
||||
return rgb_image;
|
||||
}
|
||||
|
||||
void CImageBasis::RGBImageRelease()
|
||||
{
|
||||
islocked = false;
|
||||
}
|
||||
|
||||
uint8_t * CImageBasis::RGBImageGet()
|
||||
{
|
||||
return rgb_image;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void writejpghelp(void *context, void *data, int size)
|
||||
{
|
||||
// printf("Size all: %d, size %d\n", ((ImageData*)context)->size, size);
|
||||
ImageData* _zw = (ImageData*) context;
|
||||
uint8_t *voidstart = _zw->data;
|
||||
uint8_t *datastart = (uint8_t*) data;
|
||||
voidstart += _zw->size;
|
||||
|
||||
for (int i = 0; i < size; ++i)
|
||||
*(voidstart + i) = *(datastart + i);
|
||||
|
||||
_zw->size += size;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
ImageData* CImageBasis::writeToMemoryAsJPG(const int quality)
|
||||
{
|
||||
ImageData* ii = new ImageData;
|
||||
|
||||
RGBImageLock();
|
||||
stbi_write_jpg_to_func(writejpghelp, ii, width, height, channels, rgb_image, quality);
|
||||
RGBImageRelease();
|
||||
|
||||
return ii;
|
||||
}
|
||||
|
||||
#define HTTP_BUFFER_SENT 1024
|
||||
|
||||
struct SendJPGHTTP
|
||||
{
|
||||
httpd_req_t *req;
|
||||
esp_err_t res;
|
||||
char buf[HTTP_BUFFER_SENT];
|
||||
int size = 0;
|
||||
};
|
||||
|
||||
inline void writejpgtohttphelp(void *context, void *data, int size)
|
||||
{
|
||||
SendJPGHTTP* _send = (SendJPGHTTP*) context;
|
||||
if ((_send->size + size) >= HTTP_BUFFER_SENT) // data passt nich mehr in buffer
|
||||
{
|
||||
httpd_req_t *_req = _send->req;
|
||||
if (httpd_resp_send_chunk(_req, _send->buf, _send->size) != ESP_OK)
|
||||
{
|
||||
ESP_LOGE(TAG, "File sending failed!");
|
||||
_send->res = ESP_FAIL;
|
||||
}
|
||||
_send->size = 0;
|
||||
}
|
||||
std::memcpy((void*) (&(_send->buf[0]) + _send->size), data, size);
|
||||
_send->size+= size;
|
||||
}
|
||||
|
||||
|
||||
|
||||
esp_err_t CImageBasis::SendJPGtoHTTP(httpd_req_t *_req, const int quality)
|
||||
{
|
||||
SendJPGHTTP ii;
|
||||
ii.req = _req;
|
||||
ii.res = ESP_OK;
|
||||
ii.size = 0;
|
||||
|
||||
RGBImageLock();
|
||||
stbi_write_jpg_to_func(writejpgtohttphelp, &ii, width, height, channels, rgb_image, quality);
|
||||
RGBImageRelease();
|
||||
|
||||
if (ii.size > 0)
|
||||
{
|
||||
if (httpd_resp_send_chunk(_req, (char*) ii.buf, ii.size) != ESP_OK) // verschicke noch den Rest
|
||||
{
|
||||
ESP_LOGE(TAG, "File sending failed!");
|
||||
ii.res = ESP_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
return ii.res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool CImageBasis::CopyFromMemory(uint8_t* _source, int _size)
|
||||
{
|
||||
int gr = height * width * channels;
|
||||
if (gr != _size) // Größe passt nicht
|
||||
{
|
||||
printf("Kann Bild nicht von Speicher kopierte - Größen passen nicht zusammen: soll %d, ist %d\n", _size, gr);
|
||||
return false;
|
||||
}
|
||||
|
||||
RGBImageLock();
|
||||
memCopy(_source, rgb_image, _size);
|
||||
RGBImageRelease();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t CImageBasis::GetPixelColor(int x, int y, int ch)
|
||||
{
|
||||
stbi_uc* p_source;
|
||||
p_source = rgb_image + (channels * (y * width + x));
|
||||
return p_source[ch];
|
||||
}
|
||||
|
||||
|
||||
void CImageBasis::memCopy(uint8_t* _source, uint8_t* _target, int _size)
|
||||
{
|
||||
#ifdef _ESP32_PSRAM
|
||||
for (int i = 0; i < _size; ++i)
|
||||
*(_target + i) = *(_source + i);
|
||||
#else
|
||||
memcpy(_target, _source, _size);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool CImageBasis::isInImage(int x, int y)
|
||||
{
|
||||
if ((x < 0) || (x > width - 1))
|
||||
return false;
|
||||
|
||||
if ((y < 0) || (y > height- 1))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CImageBasis::setPixelColor(int x, int y, int r, int g, int b)
|
||||
{
|
||||
stbi_uc* p_source;
|
||||
|
||||
RGBImageLock();
|
||||
p_source = rgb_image + (channels * (y * width + x));
|
||||
p_source[0] = r;
|
||||
if ( channels > 2)
|
||||
{
|
||||
p_source[1] = g;
|
||||
p_source[2] = b;
|
||||
}
|
||||
RGBImageRelease();
|
||||
}
|
||||
|
||||
void CImageBasis::drawRect(int x, int y, int dx, int dy, int r, int g, int b, int thickness)
|
||||
{
|
||||
int zwx1, zwx2, zwy1, zwy2;
|
||||
int _x, _y, _thick;
|
||||
|
||||
zwx1 = x - thickness + 1;
|
||||
zwx2 = x + dx + thickness - 1;
|
||||
zwy1 = y;
|
||||
zwy2 = y;
|
||||
for (_thick = 0; _thick < thickness; _thick++)
|
||||
for (_x = zwx1; _x <= zwx2; ++_x)
|
||||
for (_y = zwy1; _y <= zwy2; _y++)
|
||||
if (isInImage(_x, _y))
|
||||
setPixelColor(_x, _y - _thick, r, g, b);
|
||||
|
||||
zwx1 = x - thickness + 1;
|
||||
zwx2 = x + dx + thickness - 1;
|
||||
zwy1 = y + dy;
|
||||
zwy2 = y + dy;
|
||||
for (_thick = 0; _thick < thickness; _thick++)
|
||||
for (_x = zwx1; _x <= zwx2; ++_x)
|
||||
for (_y = zwy1; _y <= zwy2; _y++)
|
||||
if (isInImage(_x, _y))
|
||||
setPixelColor(_x, _y + _thick, r, g, b);
|
||||
|
||||
zwx1 = x;
|
||||
zwx2 = x;
|
||||
zwy1 = y;
|
||||
zwy2 = y + dy;
|
||||
for (_thick = 0; _thick < thickness; _thick++)
|
||||
for (_x = zwx1; _x <= zwx2; ++_x)
|
||||
for (_y = zwy1; _y <= zwy2; _y++)
|
||||
if (isInImage(_x, _y))
|
||||
setPixelColor(_x - _thick, _y, r, g, b);
|
||||
|
||||
zwx1 = x + dx;
|
||||
zwx2 = x + dx;
|
||||
zwy1 = y;
|
||||
zwy2 = y + dy;
|
||||
for (_thick = 0; _thick < thickness; _thick++)
|
||||
for (_x = zwx1; _x <= zwx2; ++_x)
|
||||
for (_y = zwy1; _y <= zwy2; _y++)
|
||||
if (isInImage(_x, _y))
|
||||
setPixelColor(_x + _thick, _y, r, g, b);
|
||||
|
||||
}
|
||||
|
||||
void CImageBasis::drawLine(int x1, int y1, int x2, int y2, int r, int g, int b, int thickness)
|
||||
{
|
||||
int _x, _y, _thick;
|
||||
int _zwy1, _zwy2;
|
||||
thickness = (thickness-1) / 2;
|
||||
|
||||
for (_thick = 0; _thick <= thickness; ++_thick)
|
||||
for (_x = x1 - _thick; _x <= x2 + _thick; ++_x)
|
||||
{
|
||||
if (x2 == x1)
|
||||
{
|
||||
_zwy1 = y1;
|
||||
_zwy2 = y2;
|
||||
}
|
||||
else
|
||||
{
|
||||
_zwy1 = (y2 - y1) * (float)(_x - x1) / (float)(x2 - x1) + y1;
|
||||
_zwy2 = (y2 - y1) * (float)(_x + 1 - x1) / (float)(x2 - x1) + y1;
|
||||
}
|
||||
|
||||
for (_y = _zwy1 - _thick; _y <= _zwy2 + _thick; _y++)
|
||||
if (isInImage(_x, _y))
|
||||
setPixelColor(_x, _y, r, g, b);
|
||||
}
|
||||
}
|
||||
|
||||
void CImageBasis::drawCircle(int x1, int y1, int rad, int r, int g, int b, int thickness)
|
||||
{
|
||||
float deltarad, aktrad;
|
||||
int _thick, _x, _y;
|
||||
|
||||
deltarad = 1 / (4 * M_PI * (rad + thickness - 1));
|
||||
|
||||
for (aktrad = 0; aktrad <= (2 * M_PI); aktrad += deltarad)
|
||||
for (_thick = 0; _thick < thickness; ++_thick)
|
||||
{
|
||||
_x = sin(aktrad) * (rad + _thick) + x1;
|
||||
_y = cos(aktrad) * (rad + _thick) + y1;
|
||||
if (isInImage(_x, _y))
|
||||
setPixelColor(_x, _y, r, g, b);
|
||||
}
|
||||
}
|
||||
|
||||
CImageBasis::CImageBasis()
|
||||
{
|
||||
externalImage = false;
|
||||
rgb_image = NULL;
|
||||
width = 0;
|
||||
height = 0;
|
||||
channels = 0;
|
||||
islocked = false;
|
||||
}
|
||||
|
||||
void CImageBasis::CreateEmptyImage(int _width, int _height, int _channels)
|
||||
{
|
||||
bpp = _channels;
|
||||
width = _width;
|
||||
height = _height;
|
||||
channels = _channels;
|
||||
|
||||
RGBImageLock();
|
||||
|
||||
|
||||
int memsize = width * height * channels;
|
||||
rgb_image = (unsigned char*)GET_MEMORY(memsize);
|
||||
|
||||
|
||||
stbi_uc* p_source;
|
||||
|
||||
for (int x = 0; x < width; ++x)
|
||||
for (int y = 0; y < height; ++y)
|
||||
{
|
||||
p_source = rgb_image + (channels * (y * width + x));
|
||||
for (int _channels = 0; _channels < channels; ++_channels)
|
||||
p_source[_channels] = (uint8_t) 0;
|
||||
}
|
||||
|
||||
RGBImageRelease();
|
||||
|
||||
|
||||
}
|
||||
|
||||
void CImageBasis::LoadFromMemory(stbi_uc *_buffer, int len)
|
||||
{
|
||||
RGBImageLock();
|
||||
if (rgb_image)
|
||||
stbi_image_free(rgb_image);
|
||||
rgb_image = stbi_load_from_memory(_buffer, len, &width, &height, &channels, 3);
|
||||
bpp = channels;
|
||||
printf("Image loaded from memory: %d, %d, %d\n", width, height, channels);
|
||||
RGBImageRelease();
|
||||
}
|
||||
|
||||
CImageBasis::CImageBasis(CImageBasis *_copyfrom, int _anzrepeat)
|
||||
{
|
||||
islocked = false;
|
||||
externalImage = false;
|
||||
channels = _copyfrom->channels;
|
||||
width = _copyfrom->width;
|
||||
height = _copyfrom->height;
|
||||
bpp = _copyfrom->bpp;
|
||||
|
||||
RGBImageLock();
|
||||
|
||||
int memsize = width * height * channels;
|
||||
rgb_image = (unsigned char*)GET_MEMORY(memsize);
|
||||
|
||||
TickType_t xDelay;
|
||||
int anz = 1;
|
||||
while (!rgb_image && (anz < _anzrepeat))
|
||||
{
|
||||
printf("Create Image from Copy - Speicher ist voll - Versuche es erneut: %d.\n", anz);
|
||||
xDelay = 1000 / portTICK_PERIOD_MS;
|
||||
rgb_image = (unsigned char*) malloc(memsize);
|
||||
anz++;
|
||||
}
|
||||
|
||||
|
||||
if (!rgb_image)
|
||||
{
|
||||
printf(getESPHeapInfo().c_str());
|
||||
printf("\nKein freier Speicher mehr!!!! Benötigt: %d %d %d %d\n", width, height, channels, memsize);
|
||||
RGBImageRelease();
|
||||
return;
|
||||
}
|
||||
|
||||
memCopy(_copyfrom->rgb_image, rgb_image, memsize);
|
||||
RGBImageRelease();
|
||||
}
|
||||
|
||||
CImageBasis::CImageBasis(int _width, int _height, int _channels)
|
||||
{
|
||||
islocked = false;
|
||||
externalImage = false;
|
||||
channels = _channels;
|
||||
width = _width;
|
||||
height = _height;
|
||||
bpp = _channels;
|
||||
|
||||
int memsize = width * height * channels;
|
||||
|
||||
rgb_image = (unsigned char*)GET_MEMORY(memsize);
|
||||
if (!rgb_image)
|
||||
{
|
||||
printf(getESPHeapInfo().c_str());
|
||||
printf("\nKein freier Speicher mehr!!!! Benötigt: %d %d %d %d\n", width, height, channels, memsize);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CImageBasis::CImageBasis(std::string _image)
|
||||
{
|
||||
islocked = false;
|
||||
channels = 3;
|
||||
externalImage = false;
|
||||
filename = _image;
|
||||
long zwld = esp_get_free_heap_size();
|
||||
printf("freeheapsize before: %ld\n", zwld);
|
||||
|
||||
RGBImageLock();
|
||||
rgb_image = stbi_load(_image.c_str(), &width, &height, &bpp, channels);
|
||||
RGBImageRelease();
|
||||
|
||||
zwld = esp_get_free_heap_size();
|
||||
printf("freeheapsize after : %ld\n", zwld);
|
||||
|
||||
std::string zw = "Image Load failed:" + _image + "\n";
|
||||
if (rgb_image == NULL)
|
||||
printf(zw.c_str());
|
||||
zw = "CImageBasis after load " + _image + "\n";
|
||||
printf(zw.c_str());
|
||||
printf("w %d, h %d, b %d, c %d\n", width, height, bpp, channels);
|
||||
|
||||
}
|
||||
|
||||
bool CImageBasis::ImageOkay(){
|
||||
return rgb_image != NULL;
|
||||
}
|
||||
|
||||
CImageBasis::CImageBasis(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp)
|
||||
{
|
||||
islocked = false;
|
||||
rgb_image = _rgb_image;
|
||||
channels = _channels;
|
||||
width = _width;
|
||||
height = _height;
|
||||
bpp = _bpp;
|
||||
externalImage = true;
|
||||
}
|
||||
|
||||
void CImageBasis::Contrast(float _contrast) //input range [-100..100]
|
||||
{
|
||||
stbi_uc* p_source;
|
||||
|
||||
float contrast = (_contrast/100) + 1; //convert to decimal & shift range: [0..2]
|
||||
float intercept = 128 * (1 - contrast);
|
||||
|
||||
RGBImageLock();
|
||||
|
||||
|
||||
for (int x = 0; x < width; ++x)
|
||||
for (int y = 0; y < height; ++y)
|
||||
{
|
||||
p_source = rgb_image + (channels * (y * width + x));
|
||||
for (int _channels = 0; _channels < channels; ++_channels)
|
||||
p_source[_channels] = (uint8_t) std::min(255, std::max(0, (int) (p_source[_channels] * contrast + intercept)));
|
||||
}
|
||||
|
||||
RGBImageRelease();
|
||||
}
|
||||
|
||||
CImageBasis::~CImageBasis()
|
||||
{
|
||||
RGBImageLock();
|
||||
if (!externalImage)
|
||||
stbi_image_free(rgb_image);
|
||||
}
|
||||
|
||||
void CImageBasis::SaveToFile(std::string _imageout)
|
||||
{
|
||||
string typ = getFileType(_imageout);
|
||||
|
||||
RGBImageLock();
|
||||
|
||||
if ((typ == "jpg") || (typ == "JPG")) // ACHTUNG PROBLEMATISCH IM ESP32
|
||||
{
|
||||
stbi_write_jpg(_imageout.c_str(), width, height, channels, rgb_image, 0);
|
||||
}
|
||||
|
||||
if ((typ == "bmp") || (typ == "BMP"))
|
||||
{
|
||||
stbi_write_bmp(_imageout.c_str(), width, height, channels, rgb_image);
|
||||
}
|
||||
RGBImageRelease();
|
||||
}
|
||||
|
||||
|
||||
void CImageBasis::Resize(int _new_dx, int _new_dy)
|
||||
{
|
||||
int memsize = _new_dx * _new_dy * channels;
|
||||
uint8_t* odata = (unsigned char*)GET_MEMORY(memsize);
|
||||
|
||||
RGBImageLock();
|
||||
|
||||
|
||||
stbir_resize_uint8(rgb_image, width, height, 0, odata, _new_dx, _new_dy, 0, channels);
|
||||
|
||||
stbi_image_free(rgb_image);
|
||||
rgb_image = (unsigned char*)GET_MEMORY(memsize);
|
||||
|
||||
memCopy(odata, rgb_image, memsize);
|
||||
RGBImageRelease();
|
||||
|
||||
width = _new_dx;
|
||||
height = _new_dy;
|
||||
stbi_image_free(odata);
|
||||
}
|
||||
|
||||
void CImageBasis::Resize(int _new_dx, int _new_dy, CImageBasis *_target)
|
||||
{
|
||||
if ((_target->height != _new_dy) || (_target->width != _new_dx) || (_target->channels != channels))
|
||||
{
|
||||
printf("CImageBasis::Resize - Targetbildgröße passt nicht !!!!!!!!!");
|
||||
return;
|
||||
}
|
||||
|
||||
RGBImageLock();
|
||||
|
||||
uint8_t* odata = _target->rgb_image;
|
||||
stbir_resize_uint8(rgb_image, width, height, 0, odata, _new_dx, _new_dy, 0, channels);
|
||||
RGBImageRelease();
|
||||
}
|
||||
|
||||
94
code/components/jomjol_image_proc/CImageBasis.h
Normal file
94
code/components/jomjol_image_proc/CImageBasis.h
Normal file
@@ -0,0 +1,94 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef __CIMAGEBASIS
|
||||
#define __CIMAGEBASIS
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include <esp_http_server.h>
|
||||
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <math.h>
|
||||
|
||||
#include "stb_image.h"
|
||||
#include "stb_image_write.h"
|
||||
#include "stb_image_resize.h"
|
||||
|
||||
#include "esp_heap_caps.h"
|
||||
|
||||
//#define GET_MEMORY malloc
|
||||
#define GET_MEMORY(X) heap_caps_malloc(X, MALLOC_CAP_SPIRAM)
|
||||
|
||||
|
||||
#define MAX_JPG_SIZE 128000
|
||||
|
||||
|
||||
struct ImageData
|
||||
{
|
||||
uint8_t data[MAX_JPG_SIZE];
|
||||
size_t size = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class CImageBasis
|
||||
{
|
||||
protected:
|
||||
bool externalImage;
|
||||
std::string filename;
|
||||
|
||||
void memCopy(uint8_t* _source, uint8_t* _target, int _size);
|
||||
bool isInImage(int x, int y);
|
||||
|
||||
bool islocked;
|
||||
|
||||
public:
|
||||
uint8_t* rgb_image;
|
||||
int channels;
|
||||
int width, height, bpp;
|
||||
|
||||
uint8_t * RGBImageLock(int _waitmaxsec = 60);
|
||||
void RGBImageRelease();
|
||||
uint8_t * RGBImageGet();
|
||||
|
||||
int getWidth(){return this->width;};
|
||||
int getHeight(){return this->height;};
|
||||
int getChannels(){return this->channels;};
|
||||
void drawRect(int x, int y, int dx, int dy, int r = 255, int g = 255, int b = 255, int thickness = 1);
|
||||
void drawLine(int x1, int y1, int x2, int y2, int r, int g, int b, int thickness = 1);
|
||||
void drawCircle(int x1, int y1, int rad, int r, int g, int b, int thickness = 1);
|
||||
void setPixelColor(int x, int y, int r, int g, int b);
|
||||
void Contrast(float _contrast);
|
||||
bool ImageOkay();
|
||||
bool CopyFromMemory(uint8_t* _source, int _size);
|
||||
|
||||
void SetIndepended(){externalImage = false;};
|
||||
|
||||
void CreateEmptyImage(int _width, int _height, int _channels);
|
||||
|
||||
|
||||
CImageBasis();
|
||||
CImageBasis(std::string _image);
|
||||
CImageBasis(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp);
|
||||
CImageBasis(int _width, int _height, int _channels);
|
||||
CImageBasis(CImageBasis *_copyfrom, int _anzrepeat = 0);
|
||||
|
||||
void Resize(int _new_dx, int _new_dy);
|
||||
void Resize(int _new_dx, int _new_dy, CImageBasis *_target);
|
||||
|
||||
void LoadFromMemory(stbi_uc *_buffer, int len);
|
||||
|
||||
ImageData* writeToMemoryAsJPG(const int quality = 90);
|
||||
|
||||
esp_err_t SendJPGtoHTTP(httpd_req_t *req, const int quality = 90);
|
||||
|
||||
uint8_t GetPixelColor(int x, int y, int ch);
|
||||
|
||||
~CImageBasis();
|
||||
|
||||
void SaveToFile(std::string _imageout);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -2,6 +2,6 @@ FILE(GLOB_RECURSE app_sources ${CMAKE_CURRENT_SOURCE_DIR}/*.*)
|
||||
|
||||
idf_component_register(SRCS ${app_sources}
|
||||
INCLUDE_DIRS "."
|
||||
REQUIRES jomjol_helper jomjol_logfile)
|
||||
REQUIRES jomjol_helper jomjol_logfile esp_http_server)
|
||||
|
||||
|
||||
|
||||
192
code/components/jomjol_image_proc/CRotateImage.cpp
Normal file
192
code/components/jomjol_image_proc/CRotateImage.cpp
Normal file
@@ -0,0 +1,192 @@
|
||||
#include "CRotateImage.h"
|
||||
|
||||
|
||||
CRotateImage::CRotateImage(CImageBasis *_org, CImageBasis *_temp)
|
||||
{
|
||||
rgb_image = _org->rgb_image;
|
||||
channels = _org->channels;
|
||||
width = _org->width;
|
||||
height = _org->height;
|
||||
bpp = _org->bpp;
|
||||
externalImage = true;
|
||||
ImageTMP = _temp;
|
||||
islocked = false;
|
||||
}
|
||||
|
||||
void CRotateImage::Mirror(){
|
||||
int memsize = width * height * channels;
|
||||
uint8_t* odata;
|
||||
if (ImageTMP)
|
||||
{
|
||||
odata = ImageTMP->RGBImageLock();
|
||||
}
|
||||
else
|
||||
{
|
||||
odata = (unsigned char*)GET_MEMORY(memsize);
|
||||
}
|
||||
|
||||
|
||||
int x_source, y_source;
|
||||
stbi_uc* p_target;
|
||||
stbi_uc* p_source;
|
||||
|
||||
RGBImageLock();
|
||||
|
||||
for (int x = 0; x < width; ++x)
|
||||
for (int y = 0; y < height; ++y)
|
||||
{
|
||||
p_target = odata + (channels * (y * width + x));
|
||||
|
||||
x_source = width - x;
|
||||
y_source = y;
|
||||
|
||||
p_source = rgb_image + (channels * (y_source * width + x_source));
|
||||
for (int _channels = 0; _channels < channels; ++_channels)
|
||||
p_target[_channels] = p_source[_channels];
|
||||
}
|
||||
|
||||
// memcpy(rgb_image, odata, memsize);
|
||||
memCopy(odata, rgb_image, memsize);
|
||||
if (!ImageTMP)
|
||||
stbi_image_free(odata);
|
||||
|
||||
if (ImageTMP)
|
||||
ImageTMP->RGBImageRelease();
|
||||
|
||||
RGBImageRelease();
|
||||
}
|
||||
|
||||
void CRotateImage::Rotate(float _angle, int _centerx, int _centery)
|
||||
{
|
||||
float m[2][3];
|
||||
|
||||
float x_center = _centerx;
|
||||
float y_center = _centery;
|
||||
_angle = _angle / 180 * M_PI;
|
||||
|
||||
m[0][0] = cos(_angle);
|
||||
m[0][1] = sin(_angle);
|
||||
m[0][2] = (1 - m[0][0]) * x_center - m[0][1] * y_center;
|
||||
|
||||
m[1][0] = -m[0][1];
|
||||
m[1][1] = m[0][0];
|
||||
m[1][2] = m[0][1] * x_center + (1 - m[0][0]) * y_center;
|
||||
|
||||
int memsize = width * height * channels;
|
||||
uint8_t* odata;
|
||||
if (ImageTMP)
|
||||
{
|
||||
odata = ImageTMP->RGBImageLock();
|
||||
}
|
||||
else
|
||||
{
|
||||
odata = (unsigned char*)GET_MEMORY(memsize);
|
||||
}
|
||||
|
||||
|
||||
int x_source, y_source;
|
||||
stbi_uc* p_target;
|
||||
stbi_uc* p_source;
|
||||
|
||||
RGBImageLock();
|
||||
|
||||
for (int x = 0; x < width; ++x)
|
||||
for (int y = 0; y < height; ++y)
|
||||
{
|
||||
p_target = odata + (channels * (y * width + x));
|
||||
|
||||
x_source = int(m[0][0] * x + m[0][1] * y);
|
||||
y_source = int(m[1][0] * x + m[1][1] * y);
|
||||
|
||||
x_source += int(m[0][2]);
|
||||
y_source += int(m[1][2]);
|
||||
|
||||
if ((x_source >= 0) && (x_source < width) && (y_source >= 0) && (y_source < height))
|
||||
{
|
||||
p_source = rgb_image + (channels * (y_source * width + x_source));
|
||||
for (int _channels = 0; _channels < channels; ++_channels)
|
||||
p_target[_channels] = p_source[_channels];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int _channels = 0; _channels < channels; ++_channels)
|
||||
p_target[_channels] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
// memcpy(rgb_image, odata, memsize);
|
||||
memCopy(odata, rgb_image, memsize);
|
||||
|
||||
if (!ImageTMP)
|
||||
{
|
||||
stbi_image_free(odata);
|
||||
}
|
||||
if (ImageTMP)
|
||||
ImageTMP->RGBImageRelease();
|
||||
|
||||
RGBImageRelease();
|
||||
}
|
||||
|
||||
void CRotateImage::Rotate(float _angle)
|
||||
{
|
||||
// printf("width %d, height %d\n", width, height);
|
||||
Rotate(_angle, width / 2, height / 2);
|
||||
}
|
||||
|
||||
void CRotateImage::Translate(int _dx, int _dy)
|
||||
{
|
||||
int memsize = width * height * channels;
|
||||
uint8_t* odata;
|
||||
if (ImageTMP)
|
||||
{
|
||||
odata = ImageTMP->RGBImageLock();
|
||||
}
|
||||
else
|
||||
{
|
||||
odata = (unsigned char*)GET_MEMORY(memsize);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int x_source, y_source;
|
||||
stbi_uc* p_target;
|
||||
stbi_uc* p_source;
|
||||
|
||||
RGBImageLock();
|
||||
|
||||
for (int x = 0; x < width; ++x)
|
||||
for (int y = 0; y < height; ++y)
|
||||
{
|
||||
p_target = odata + (channels * (y * width + x));
|
||||
|
||||
x_source = x - _dx;
|
||||
y_source = y - _dy;
|
||||
|
||||
if ((x_source >= 0) && (x_source < width) && (y_source >= 0) && (y_source < height))
|
||||
{
|
||||
p_source = rgb_image + (channels * (y_source * width + x_source));
|
||||
for (int _channels = 0; _channels < channels; ++_channels)
|
||||
p_target[_channels] = p_source[_channels];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int _channels = 0; _channels < channels; ++_channels)
|
||||
p_target[_channels] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
// memcpy(rgb_image, odata, memsize);
|
||||
memCopy(odata, rgb_image, memsize);
|
||||
if (!ImageTMP)
|
||||
{
|
||||
stbi_image_free(odata);
|
||||
}
|
||||
|
||||
if (ImageTMP)
|
||||
{
|
||||
ImageTMP->RGBImageRelease();
|
||||
}
|
||||
RGBImageRelease();
|
||||
|
||||
}
|
||||
|
||||
16
code/components/jomjol_image_proc/CRotateImage.h
Normal file
16
code/components/jomjol_image_proc/CRotateImage.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#include "CImageBasis.h"
|
||||
|
||||
|
||||
class CRotateImage: public CImageBasis
|
||||
{
|
||||
public:
|
||||
CImageBasis *ImageTMP;
|
||||
CRotateImage(std::string _image) : CImageBasis(_image) {ImageTMP = NULL;};
|
||||
CRotateImage(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp) : CImageBasis(_rgb_image, _channels, _width, _height, _bpp) {ImageTMP = NULL;};
|
||||
CRotateImage(CImageBasis *_org, CImageBasis *_temp);
|
||||
|
||||
void Rotate(float _angle);
|
||||
void Rotate(float _angle, int _centerx, int _centery);
|
||||
void Translate(int _dx, int _dy);
|
||||
void Mirror();
|
||||
};
|
||||
@@ -10,6 +10,50 @@ static const char *TAG = "log";
|
||||
|
||||
ClassLogFile LogFile("/sdcard/log/message", "log_%Y-%m-%d.txt");
|
||||
|
||||
void ClassLogFile::WriteHeapInfo(std::string _id)
|
||||
{
|
||||
std::string _zw = "\t" + _id;
|
||||
if (loglevel > 0)
|
||||
_zw = _zw + "\t" + getESPHeapInfo();
|
||||
|
||||
WriteToFile(_zw);
|
||||
}
|
||||
|
||||
|
||||
std::string ClassLogFile::getESPHeapInfo(){
|
||||
string espInfoResultStr = "";
|
||||
char aMsgBuf[80];
|
||||
|
||||
multi_heap_info_t aMultiHead_info ;
|
||||
heap_caps_get_info (&aMultiHead_info,MALLOC_CAP_8BIT);
|
||||
size_t aFreeHeapSize = heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
size_t aMinFreeHeadSize = heap_caps_get_minimum_free_size(MALLOC_CAP_8BIT);
|
||||
size_t aMinFreeHeapSize = heap_caps_get_minimum_free_size(MALLOC_CAP_8BIT);
|
||||
size_t aHeapLargestFreeBlockSize = heap_caps_get_largest_free_block(MALLOC_CAP_8BIT);
|
||||
sprintf(aMsgBuf,"Free Heap Size: \t%ld", (long) aFreeHeapSize);
|
||||
size_t aFreeSPIHeapSize = heap_caps_get_free_size(MALLOC_CAP_8BIT| MALLOC_CAP_SPIRAM);
|
||||
size_t aFreeInternalHeapSize = heap_caps_get_free_size(MALLOC_CAP_8BIT| MALLOC_CAP_INTERNAL);
|
||||
size_t aMinFreeInternalHeapSize = heap_caps_get_minimum_free_size(MALLOC_CAP_8BIT| MALLOC_CAP_INTERNAL);
|
||||
|
||||
sprintf(aMsgBuf,"\tHeap:\t%ld", (long) aFreeHeapSize);
|
||||
espInfoResultStr += string(aMsgBuf);
|
||||
sprintf(aMsgBuf,"\tMin Free:\t%ld", (long) aMinFreeHeapSize);
|
||||
espInfoResultStr += string(aMsgBuf);
|
||||
sprintf(aMsgBuf,"\tlarg. Block: \t%ld", (long) aHeapLargestFreeBlockSize);
|
||||
espInfoResultStr += string(aMsgBuf);
|
||||
sprintf(aMsgBuf,"\tSPI Heap:\t%ld", (long) aFreeSPIHeapSize);
|
||||
espInfoResultStr += string(aMsgBuf);
|
||||
sprintf(aMsgBuf,"\tMin Free Heap Size:\t%ld", (long) aMinFreeHeadSize);
|
||||
sprintf(aMsgBuf,"\tNOT_SPI Heap:\t%ld", (long) (aFreeHeapSize - aFreeSPIHeapSize));
|
||||
espInfoResultStr += string(aMsgBuf);
|
||||
sprintf(aMsgBuf,"\tlargest Block Size: \t%ld", (long) aHeapLargestFreeBlockSize);
|
||||
sprintf(aMsgBuf,"\tInternal Heap:\t%ld", (long) (aFreeInternalHeapSize));
|
||||
espInfoResultStr += string(aMsgBuf);
|
||||
sprintf(aMsgBuf,"\tInternal Min Heap free:\t%ld", (long) (aMinFreeInternalHeapSize));
|
||||
espInfoResultStr += string(aMsgBuf);
|
||||
return espInfoResultStr;
|
||||
}
|
||||
|
||||
void ClassLogFile::WriteToDedicatedFile(std::string _fn, std::string info, bool _time)
|
||||
{
|
||||
FILE* pFile;
|
||||
@@ -19,7 +63,10 @@ void ClassLogFile::WriteToDedicatedFile(std::string _fn, std::string info, bool
|
||||
return;
|
||||
}
|
||||
|
||||
// pFile = OpenFileAndWait(_fn.c_str(), "a");
|
||||
pFile = fopen(_fn.c_str(), "a+");
|
||||
printf("Logfile opened: %s\n", _fn.c_str());
|
||||
|
||||
if (pFile!=NULL) {
|
||||
if (_time)
|
||||
{
|
||||
@@ -54,6 +101,7 @@ void ClassLogFile::SetRetention(unsigned short _retentionInDays){
|
||||
|
||||
void ClassLogFile::WriteToFile(std::string info, bool _time)
|
||||
{
|
||||
/*
|
||||
struct stat path_stat;
|
||||
if (stat(logroot.c_str(), &path_stat) != 0) {
|
||||
ESP_LOGI(TAG, "Create log folder: %s", logroot.c_str());
|
||||
@@ -61,7 +109,7 @@ void ClassLogFile::WriteToFile(std::string info, bool _time)
|
||||
ESP_LOGI(TAG, "Can't create log foolder");
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
time_t rawtime;
|
||||
struct tm* timeinfo;
|
||||
char buffer[30];
|
||||
@@ -79,12 +127,12 @@ std::string ClassLogFile::GetCurrentFileName()
|
||||
{
|
||||
time_t rawtime;
|
||||
struct tm* timeinfo;
|
||||
char buffer[30];
|
||||
char buffer[60];
|
||||
|
||||
time(&rawtime);
|
||||
timeinfo = localtime(&rawtime);
|
||||
|
||||
strftime(buffer, 30, logfile.c_str(), timeinfo);
|
||||
strftime(buffer, 60, logfile.c_str(), timeinfo);
|
||||
std::string logpath = logroot + "/" + buffer;
|
||||
|
||||
return logpath;
|
||||
@@ -142,4 +190,5 @@ ClassLogFile::ClassLogFile(std::string _logroot, std::string _logfile)
|
||||
logfile = _logfile;
|
||||
doLogFile = true;
|
||||
retentionInDays = 10;
|
||||
loglevel = 0;
|
||||
}
|
||||
|
||||
@@ -9,9 +9,16 @@ private:
|
||||
std::string logfile;
|
||||
bool doLogFile;
|
||||
unsigned short retentionInDays;
|
||||
int loglevel;
|
||||
public:
|
||||
ClassLogFile(std::string _logpath, std::string _logfile);
|
||||
|
||||
std::string getESPHeapInfo();
|
||||
|
||||
void setLogLevel(int i){loglevel = i;};
|
||||
|
||||
void WriteHeapInfo(std::string _id);
|
||||
|
||||
void SwitchOnOff(bool _doLogFile);
|
||||
void SetRetention(unsigned short _retentionInDays);
|
||||
|
||||
|
||||
@@ -64,10 +64,18 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_
|
||||
mqtt_event_handler_cb((esp_mqtt_event_handle_t) event_data);
|
||||
}
|
||||
|
||||
void MQTTInit(std::string _mqttURI, std::string _clientid, std::string _user, std::string _password){
|
||||
void MQTTInit(std::string _mqttURI, std::string _clientid, std::string _user, std::string _password, std::string _LWTContext, int _keepalive){
|
||||
std::string _zwmessage = "connection lost";
|
||||
|
||||
int _lzw = _zwmessage.length();
|
||||
|
||||
esp_mqtt_client_config_t mqtt_cfg = {
|
||||
.uri = _mqttURI.c_str(),
|
||||
.client_id = _clientid.c_str(),
|
||||
.lwt_topic = _LWTContext.c_str(),
|
||||
.lwt_msg = _zwmessage.c_str(),
|
||||
.lwt_msg_len = _lzw,
|
||||
.keepalive = _keepalive
|
||||
};
|
||||
|
||||
if (_user.length() && _password.length()){
|
||||
@@ -79,4 +87,6 @@ void MQTTInit(std::string _mqttURI, std::string _clientid, std::string _user, st
|
||||
client = esp_mqtt_client_init(&mqtt_cfg);
|
||||
esp_mqtt_client_register_event(client, esp_mmqtt_ID, mqtt_event_handler, client);
|
||||
esp_mqtt_client_start(client);
|
||||
|
||||
MQTTPublish(_LWTContext, "");
|
||||
}
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
#include <string>
|
||||
|
||||
void MQTTInit(std::string _mqttURI, std::string _clientid, std::string _user = "", std::string _password = "");
|
||||
void MQTTInit(std::string _mqttURI, std::string _clientid, std::string _user, std::string _password, std::string _LWTContext, int _keepalive);
|
||||
|
||||
//void MQTTInit(std::string _mqttURI, std::string _clientid, std::string _user = "", std::string _password = "");
|
||||
|
||||
void MQTTPublish(std::string _key, std::string _content);
|
||||
@@ -2,6 +2,6 @@ FILE(GLOB_RECURSE app_sources ${CMAKE_CURRENT_SOURCE_DIR}/*.*)
|
||||
|
||||
idf_component_register(SRCS ${app_sources}
|
||||
INCLUDE_DIRS "."
|
||||
REQUIRES jomjol_image_proc jomjol_logfile esp_http_server esp32-camera-master jomjol_controlcamera jomjol_flowcontroll)
|
||||
REQUIRES jomjol_image_proc jomjol_logfile esp_http_server esp32-camera-master jomjol_controlcamera jomjol_flowcontroll jomjol_helper)
|
||||
|
||||
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
#include "CTfLiteClass.h"
|
||||
|
||||
#include "bitmap_image.hpp"
|
||||
|
||||
#include "ClassLogFile.h"
|
||||
#include "Helper.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
bool debugdetailtflite = false;
|
||||
// #define DEBUG_DETAIL_ON
|
||||
|
||||
float CTfLiteClass::GetOutputValue(int nr)
|
||||
{
|
||||
@@ -19,19 +17,14 @@ float CTfLiteClass::GetOutputValue(int nr)
|
||||
return output2->data.f[nr];
|
||||
}
|
||||
|
||||
|
||||
int CTfLiteClass::GetClassFromImage(std::string _fn)
|
||||
int CTfLiteClass::GetClassFromImageBasis(CImageBasis *rs)
|
||||
{
|
||||
// printf("Before Load image %s\n", _fn.c_str());
|
||||
if (!LoadInputImage(_fn))
|
||||
if (!LoadInputImageBasis(rs))
|
||||
return -1000;
|
||||
// printf("After Load image %s\n", _fn.c_str());
|
||||
|
||||
Invoke();
|
||||
printf("After Invoke %s\n", _fn.c_str());
|
||||
|
||||
return GetOutClassification();
|
||||
// return 0;
|
||||
}
|
||||
|
||||
int CTfLiteClass::GetOutClassification()
|
||||
@@ -55,7 +48,6 @@ int CTfLiteClass::GetOutClassification()
|
||||
zw_class = i;
|
||||
}
|
||||
}
|
||||
// printf("Result Ziffer: %d\n", zw_class);
|
||||
return zw_class;
|
||||
}
|
||||
|
||||
@@ -107,21 +99,17 @@ void CTfLiteClass::GetOutPut()
|
||||
void CTfLiteClass::Invoke()
|
||||
{
|
||||
interpreter->Invoke();
|
||||
// printf("Invoke Done.\n");
|
||||
}
|
||||
|
||||
|
||||
bool CTfLiteClass::LoadInputImage(std::string _fn)
|
||||
|
||||
bool CTfLiteClass::LoadInputImageBasis(CImageBasis *rs)
|
||||
{
|
||||
std::string zw = "ClassFlowAnalog::doNeuralNetwork nach Load Image: " + _fn;
|
||||
// LogFile.WriteToFile(zw);
|
||||
bitmap_image image(_fn);
|
||||
if (debugdetailtflite) LogFile.WriteToFile(zw);
|
||||
std::string zw = "ClassFlowAnalog::doNeuralNetwork nach LoadInputResizeImage: ";
|
||||
|
||||
unsigned int w = image.width();
|
||||
unsigned int h = image.height();
|
||||
unsigned int w = rs->width;
|
||||
unsigned int h = rs->height;
|
||||
unsigned char red, green, blue;
|
||||
|
||||
// printf("Image: %s size: %d x %d\n", _fn.c_str(), w, h);
|
||||
|
||||
input_i = 0;
|
||||
@@ -130,21 +118,20 @@ bool CTfLiteClass::LoadInputImage(std::string _fn)
|
||||
for (int y = 0; y < h; ++y)
|
||||
for (int x = 0; x < w; ++x)
|
||||
{
|
||||
red = image.red_channel(x, y);
|
||||
green = image.green_channel(x, y);
|
||||
blue = image.blue_channel(x, y);
|
||||
red = rs->GetPixelColor(x, y, 0);
|
||||
green = rs->GetPixelColor(x, y, 1);
|
||||
blue = rs->GetPixelColor(x, y, 2);
|
||||
*(input_data_ptr) = (float) red;
|
||||
input_data_ptr++;
|
||||
*(input_data_ptr) = (float) green;
|
||||
input_data_ptr++;
|
||||
*(input_data_ptr) = (float) blue;
|
||||
input_data_ptr++;
|
||||
|
||||
// printf("BMP: %f %f %f\n", (float) red, (float) green, (float) blue);
|
||||
|
||||
}
|
||||
|
||||
if (debugdetailtflite) LogFile.WriteToFile("Nach dem Laden in input");
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteToFile("Nach dem Laden in input");
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -152,7 +139,6 @@ bool CTfLiteClass::LoadInputImage(std::string _fn)
|
||||
|
||||
void CTfLiteClass::MakeAllocate()
|
||||
{
|
||||
// static tflite::ops::micro::AllOpsResolver resolver;
|
||||
static tflite::AllOpsResolver resolver;
|
||||
this->interpreter = new tflite::MicroInterpreter(this->model, resolver, this->tensor_arena, this->kTensorArenaSize, this->error_reporter);
|
||||
|
||||
@@ -162,16 +148,15 @@ void CTfLiteClass::MakeAllocate()
|
||||
this->GetInputDimension();
|
||||
return;
|
||||
}
|
||||
|
||||
// printf("Allocate Done.\n");
|
||||
}
|
||||
|
||||
void CTfLiteClass::GetInputTensorSize(){
|
||||
float *zw = this->input;
|
||||
int test = sizeof(zw);
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
printf("Input Tensor Dimension: %d\n", test);
|
||||
|
||||
printf("Input Tensor Dimension: %d\n", test);
|
||||
#endif
|
||||
}
|
||||
|
||||
long CTfLiteClass::GetFileSize(std::string filename)
|
||||
@@ -186,24 +171,34 @@ unsigned char* CTfLiteClass::ReadFileToCharArray(std::string _fn)
|
||||
{
|
||||
long size;
|
||||
|
||||
size = this->GetFileSize(_fn);
|
||||
size = GetFileSize(_fn);
|
||||
|
||||
if (size == -1)
|
||||
{
|
||||
printf("\nFile existiert nicht.\n");
|
||||
return NULL;
|
||||
printf("\nFile existiert nicht.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
unsigned char *result = (unsigned char*) malloc(size);
|
||||
int anz = 1;
|
||||
TickType_t xDelay;
|
||||
while (!result && (anz < 6)) // maximal 5x versuchen (= 5s)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
printf("Speicher ist voll - Versuche es erneut: %d.\n", anz);
|
||||
#endif
|
||||
xDelay = 1000 / portTICK_PERIOD_MS;
|
||||
result = (unsigned char*) malloc(size);
|
||||
anz++;
|
||||
}
|
||||
|
||||
|
||||
unsigned char *result = (unsigned char*) malloc(size);
|
||||
|
||||
if(result != NULL) {
|
||||
// printf("\nSpeicher ist reserviert\n");
|
||||
FILE* f = fopen(_fn.c_str(), "rb"); // vorher nur "r"
|
||||
if(result != NULL) {
|
||||
FILE* f = OpenFileAndWait(_fn.c_str(), "rb"); // vorher nur "r"
|
||||
fread(result, 1, size, f);
|
||||
fclose(f);
|
||||
}else {
|
||||
printf("\nKein freier Speicher vorhanden.\n");
|
||||
}else {
|
||||
printf("\nKein freier Speicher vorhanden.\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -219,14 +214,11 @@ void CTfLiteClass::LoadModel(std::string _fn){
|
||||
#endif
|
||||
|
||||
unsigned char *rd;
|
||||
rd = this->ReadFileToCharArray(_fn.c_str());
|
||||
// printf("loadedfile: %d", (int) rd);
|
||||
rd = ReadFileToCharArray(_fn.c_str());
|
||||
|
||||
this->model = tflite::GetModel(rd);
|
||||
free(rd);
|
||||
TFLITE_MINIMAL_CHECK(model != nullptr);
|
||||
// printf("tfile Loaded.\n");
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -237,7 +229,7 @@ CTfLiteClass::CTfLiteClass()
|
||||
this->interpreter = nullptr;
|
||||
this->input = nullptr;
|
||||
this->output = nullptr;
|
||||
this->kTensorArenaSize = 600 * 1024;
|
||||
this->kTensorArenaSize = 150 * 1024; /// laut testfile: 108000 - bisher 600
|
||||
this->tensor_arena = new uint8_t[kTensorArenaSize];
|
||||
}
|
||||
|
||||
@@ -255,6 +247,6 @@ namespace tflite {
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace tflite
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "CImageBasis.h"
|
||||
|
||||
|
||||
|
||||
#define SUPRESS_TFLITE_ERRORS // use, to avoid error messages from TFLITE
|
||||
@@ -39,7 +41,6 @@ class CTfLiteClass
|
||||
const tflite::Model* model;
|
||||
tflite::MicroInterpreter* interpreter;
|
||||
TfLiteTensor* output = nullptr;
|
||||
// static tflite::ops::micro::AllOpsResolver *resolver;
|
||||
static tflite::AllOpsResolver resolver;
|
||||
|
||||
int kTensorArenaSize;
|
||||
@@ -58,11 +59,11 @@ class CTfLiteClass
|
||||
void LoadModel(std::string _fn);
|
||||
void MakeAllocate();
|
||||
void GetInputTensorSize();
|
||||
bool LoadInputImage(std::string _fn);
|
||||
bool LoadInputImageBasis(CImageBasis *rs);
|
||||
void Invoke();
|
||||
void GetOutPut();
|
||||
int GetOutClassification();
|
||||
int GetClassFromImage(std::string _fn);
|
||||
int GetClassFromImageBasis(CImageBasis *rs);
|
||||
|
||||
float GetOutputValue(int nr);
|
||||
void GetInputDimension(bool silent);
|
||||
|
||||
@@ -18,31 +18,69 @@
|
||||
|
||||
#include "ClassLogFile.h"
|
||||
|
||||
//#define DEBUG_DETAIL_ON
|
||||
|
||||
|
||||
ClassFlowControll tfliteflow;
|
||||
|
||||
TaskHandle_t xHandleblink_task_doFlow = NULL;
|
||||
TaskHandle_t xHandletask_autodoFlow = NULL;
|
||||
|
||||
|
||||
|
||||
|
||||
bool flowisrunning = false;
|
||||
|
||||
long auto_intervall = 0;
|
||||
bool auto_isrunning = false;
|
||||
|
||||
|
||||
int countRounds = 0;
|
||||
|
||||
int getCountFlowRounds() {
|
||||
return countRounds;
|
||||
}
|
||||
|
||||
|
||||
|
||||
esp_err_t GetJPG(std::string _filename, httpd_req_t *req)
|
||||
{
|
||||
return tfliteflow.GetJPGStream(_filename, req);
|
||||
}
|
||||
|
||||
esp_err_t GetRawJPG(httpd_req_t *req)
|
||||
{
|
||||
return tfliteflow.SendRawJPG(req);
|
||||
}
|
||||
|
||||
bool isSetupModusActive() {
|
||||
return tfliteflow.getStatusSetupModus();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void KillTFliteTasks()
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
printf("Handle: xHandleblink_task_doFlow: %ld\n", (long) xHandleblink_task_doFlow);
|
||||
#endif
|
||||
if (xHandleblink_task_doFlow)
|
||||
{
|
||||
vTaskDelete(xHandleblink_task_doFlow);
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
printf("Killed: xHandleblink_task_doFlow\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
printf("Handle: xHandletask_autodoFlow: %ld\n", (long) xHandletask_autodoFlow);
|
||||
#endif
|
||||
if (xHandletask_autodoFlow)
|
||||
{
|
||||
vTaskDelete(xHandletask_autodoFlow);
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
printf("Killed: xHandletask_autodoFlow\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
@@ -50,9 +88,13 @@ void KillTFliteTasks()
|
||||
void doInit(void)
|
||||
{
|
||||
string config = "/sdcard/config/config.ini";
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
printf("Start tfliteflow.InitFlow(config);\n");
|
||||
#endif
|
||||
tfliteflow.InitFlow(config);
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
printf("Finished tfliteflow.InitFlow(config);\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -65,13 +107,17 @@ bool doflow(void)
|
||||
tfliteflow.doFlow(zw_time);
|
||||
flowisrunning = false;
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
printf("doflow - end %s\n", zw_time.c_str());
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
void blink_task_doFlow(void *pvParameter)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
printf("blink_task_doFlow\n");
|
||||
#endif
|
||||
if (!flowisrunning)
|
||||
{
|
||||
flowisrunning = true;
|
||||
@@ -85,8 +131,10 @@ void blink_task_doFlow(void *pvParameter)
|
||||
|
||||
esp_err_t handler_init(httpd_req_t *req)
|
||||
{
|
||||
LogFile.WriteToFile("handler_init");
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_init - Start");
|
||||
printf("handler_doinit uri:\n"); printf(req->uri); printf("\n");
|
||||
#endif
|
||||
|
||||
char* resp_str = "Init started<br>";
|
||||
httpd_resp_send(req, resp_str, strlen(resp_str));
|
||||
@@ -98,12 +146,19 @@ esp_err_t handler_init(httpd_req_t *req)
|
||||
/* Respond with an empty chunk to signal HTTP response completion */
|
||||
httpd_resp_send_chunk(req, NULL, 0);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_init - Done");
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
};
|
||||
|
||||
esp_err_t handler_doflow(httpd_req_t *req)
|
||||
{
|
||||
LogFile.WriteToFile("handler_doflow");
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_doflow - Start");
|
||||
#endif
|
||||
|
||||
char* resp_str;
|
||||
|
||||
printf("handler_doFlow uri: "); printf(req->uri); printf("\n");
|
||||
@@ -122,6 +177,11 @@ esp_err_t handler_doflow(httpd_req_t *req)
|
||||
httpd_resp_send(req, resp_str, strlen(resp_str));
|
||||
/* Respond with an empty chunk to signal HTTP response completion */
|
||||
httpd_resp_send_chunk(req, NULL, 0);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_doflow - Done");
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
};
|
||||
|
||||
@@ -130,7 +190,10 @@ esp_err_t handler_doflow(httpd_req_t *req)
|
||||
|
||||
esp_err_t handler_wasserzaehler(httpd_req_t *req)
|
||||
{
|
||||
LogFile.WriteToFile("handler_wasserzaehler");
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_wasserzaehler - Start");
|
||||
#endif
|
||||
|
||||
bool _rawValue = false;
|
||||
bool _noerror = false;
|
||||
string zw;
|
||||
@@ -145,12 +208,16 @@ esp_err_t handler_wasserzaehler(httpd_req_t *req)
|
||||
// printf("Query: "); printf(_query); printf("\n");
|
||||
if (httpd_query_key_value(_query, "rawvalue", _size, 10) == ESP_OK)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
printf("rawvalue is found"); printf(_size); printf("\n");
|
||||
#endif
|
||||
_rawValue = true;
|
||||
}
|
||||
if (httpd_query_key_value(_query, "noerror", _size, 10) == ESP_OK)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
printf("noerror is found"); printf(_size); printf("\n");
|
||||
#endif
|
||||
_noerror = true;
|
||||
}
|
||||
}
|
||||
@@ -165,7 +232,7 @@ esp_err_t handler_wasserzaehler(httpd_req_t *req)
|
||||
{
|
||||
string txt, zw;
|
||||
|
||||
txt = "<p>Aligned Image: <p><img src=\"/img_tmp/alg.jpg\"> <p>\n";
|
||||
txt = "<p>Aligned Image: <p><img src=\"/img_tmp/alg_roi.jpg\"> <p>\n";
|
||||
txt = txt + "Digital Counter: <p> ";
|
||||
httpd_resp_sendstr_chunk(req, txt.c_str());
|
||||
|
||||
@@ -211,13 +278,18 @@ esp_err_t handler_wasserzaehler(httpd_req_t *req)
|
||||
/* Respond with an empty chunk to signal HTTP response completion */
|
||||
httpd_resp_sendstr_chunk(req, NULL);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_wasserzaehler - Done");
|
||||
#endif
|
||||
return ESP_OK;
|
||||
};
|
||||
|
||||
|
||||
esp_err_t handler_editflow(httpd_req_t *req)
|
||||
{
|
||||
LogFile.WriteToFile("handler_editflow");
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_editflow - Start");
|
||||
#endif
|
||||
|
||||
printf("handler_editflow uri: "); printf(req->uri); printf("\n");
|
||||
|
||||
@@ -229,7 +301,9 @@ esp_err_t handler_editflow(httpd_req_t *req)
|
||||
{
|
||||
if (httpd_query_key_value(_query, "task", _valuechar, 30) == ESP_OK)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
printf("task is found: %s\n", _valuechar);
|
||||
#endif
|
||||
_task = string(_valuechar);
|
||||
}
|
||||
}
|
||||
@@ -240,11 +314,13 @@ esp_err_t handler_editflow(httpd_req_t *req)
|
||||
|
||||
httpd_query_key_value(_query, "in", _valuechar, 30);
|
||||
in = string(_valuechar);
|
||||
printf("in: "); printf(in.c_str()); printf("\n");
|
||||
|
||||
httpd_query_key_value(_query, "out", _valuechar, 30);
|
||||
out = string(_valuechar);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
printf("in: "); printf(in.c_str()); printf("\n");
|
||||
printf("out: "); printf(out.c_str()); printf("\n");
|
||||
#endif
|
||||
|
||||
in = "/sdcard" + in;
|
||||
out = "/sdcard" + out;
|
||||
@@ -263,31 +339,34 @@ esp_err_t handler_editflow(httpd_req_t *req)
|
||||
|
||||
httpd_query_key_value(_query, "in", _valuechar, 30);
|
||||
in = string(_valuechar);
|
||||
printf("in: "); printf(in.c_str()); printf("\n");
|
||||
|
||||
httpd_query_key_value(_query, "out", _valuechar, 30);
|
||||
out = string(_valuechar);
|
||||
printf("out: "); printf(out.c_str()); printf("\n");
|
||||
|
||||
httpd_query_key_value(_query, "x", _valuechar, 30);
|
||||
zw = string(_valuechar);
|
||||
x = stoi(zw);
|
||||
printf("x: "); printf(zw.c_str()); printf("\n");
|
||||
|
||||
httpd_query_key_value(_query, "y", _valuechar, 30);
|
||||
zw = string(_valuechar);
|
||||
y = stoi(zw);
|
||||
printf("y: "); printf(zw.c_str()); printf("\n");
|
||||
|
||||
httpd_query_key_value(_query, "dx", _valuechar, 30);
|
||||
zw = string(_valuechar);
|
||||
dx = stoi(zw);
|
||||
printf("dx: "); printf(zw.c_str()); printf("\n");
|
||||
|
||||
httpd_query_key_value(_query, "dy", _valuechar, 30);
|
||||
zw = string(_valuechar);
|
||||
dy = stoi(zw);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
printf("in: "); printf(in.c_str()); printf("\n");
|
||||
printf("out: "); printf(out.c_str()); printf("\n");
|
||||
printf("x: "); printf(zw.c_str()); printf("\n");
|
||||
printf("y: "); printf(zw.c_str()); printf("\n");
|
||||
printf("dx: "); printf(zw.c_str()); printf("\n");
|
||||
printf("dy: "); printf(zw.c_str()); printf("\n");
|
||||
#endif
|
||||
|
||||
if (httpd_query_key_value(_query, "enhance", _valuechar, 10) == ESP_OK)
|
||||
{
|
||||
@@ -318,6 +397,7 @@ esp_err_t handler_editflow(httpd_req_t *req)
|
||||
|
||||
zw = "CutImage Done";
|
||||
httpd_resp_sendstr_chunk(req, zw.c_str());
|
||||
|
||||
}
|
||||
|
||||
if (_task.compare("test_take") == 0)
|
||||
@@ -373,27 +453,41 @@ esp_err_t handler_editflow(httpd_req_t *req)
|
||||
/* Respond with an empty chunk to signal HTTP response completion */
|
||||
httpd_resp_sendstr_chunk(req, NULL);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_editflow - Done");
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
};
|
||||
|
||||
|
||||
esp_err_t handler_prevalue(httpd_req_t *req)
|
||||
{
|
||||
LogFile.WriteToFile("handler_prevalue");
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_prevalue - Start");
|
||||
#endif
|
||||
|
||||
const char* resp_str;
|
||||
string zw;
|
||||
|
||||
// printf("handler_prevalue:\n"); printf(req->uri); printf("\n");
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
printf("handler_prevalue:\n"); printf(req->uri); printf("\n");
|
||||
#endif
|
||||
|
||||
char _query[100];
|
||||
char _size[10] = "";
|
||||
|
||||
if (httpd_req_get_url_query_str(req, _query, 100) == ESP_OK)
|
||||
{
|
||||
// printf("Query: "); printf(_query); printf("\n");
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
printf("Query: "); printf(_query); printf("\n");
|
||||
#endif
|
||||
|
||||
if (httpd_query_key_value(_query, "value", _size, 10) == ESP_OK)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
printf("Value: "); printf(_size); printf("\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -408,6 +502,10 @@ esp_err_t handler_prevalue(httpd_req_t *req)
|
||||
/* Respond with an empty chunk to signal HTTP response completion */
|
||||
httpd_resp_send_chunk(req, NULL, 0);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_prevalue - Start");
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
};
|
||||
|
||||
@@ -419,22 +517,36 @@ void task_autodoFlow(void *pvParameter)
|
||||
|
||||
auto_isrunning = tfliteflow.isAutoStart(auto_intervall);
|
||||
|
||||
if (isSetupModusActive()) {
|
||||
auto_isrunning = false;
|
||||
std::string zw_time = gettimestring(LOGFILE_TIME_FORMAT);
|
||||
tfliteflow.doFlowMakeImageOnly(zw_time);
|
||||
|
||||
}
|
||||
|
||||
while (auto_isrunning)
|
||||
{
|
||||
LogFile.WriteToFile("task_autodoFlow - next round");
|
||||
std::string _zw = "task_autodoFlow - next round - Round #" + std::to_string(++countRounds);
|
||||
LogFile.WriteToFile(_zw);
|
||||
printf("Autoflow: start\n");
|
||||
fr_start = esp_timer_get_time();
|
||||
|
||||
if (flowisrunning)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
printf("Autoflow: doFLow laeuft bereits!\n");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
printf("Autoflow: doFLow wird gestartet\n");
|
||||
#endif
|
||||
flowisrunning = true;
|
||||
doflow();
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
printf("Remove older log files\n");
|
||||
#endif
|
||||
LogFile.RemoveOld();
|
||||
}
|
||||
|
||||
@@ -494,5 +606,4 @@ void register_server_tflite_uri(httpd_handle_t server)
|
||||
camuri.handler = handler_wasserzaehler;
|
||||
camuri.user_ctx = (void*) "Wasserzaehler";
|
||||
httpd_register_uri_handler(server, &camuri);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <esp_log.h>
|
||||
|
||||
#include <esp_http_server.h>
|
||||
#include "CImageBasis.h"
|
||||
|
||||
//#include "ClassControllCamera.h"
|
||||
|
||||
@@ -11,3 +12,9 @@ void register_server_tflite_uri(httpd_handle_t server);
|
||||
void KillTFliteTasks();
|
||||
|
||||
void TFliteDoAutoStart();
|
||||
|
||||
bool isSetupModusActive();
|
||||
|
||||
esp_err_t GetJPG(std::string _filename, httpd_req_t *req);
|
||||
|
||||
esp_err_t GetRawJPG(httpd_req_t *req);
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
#include "time_sntp.h"
|
||||
|
||||
/* LwIP SNTP example
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
#include <string>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
@@ -17,27 +11,17 @@
|
||||
#include "esp_log.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_sleep.h"
|
||||
// #include "nvs_flash.h"
|
||||
// #include "protocol_examples_common.h"
|
||||
#include "esp_sntp.h"
|
||||
|
||||
#include "ClassLogFile.h"
|
||||
|
||||
static const char *TAG = "sntp";
|
||||
|
||||
RTC_DATA_ATTR int boot_count = 0;
|
||||
|
||||
bool setTimeAlwaysOnReboot = true;
|
||||
|
||||
/* Variable holding number of times ESP32 restarted since first boot.
|
||||
* It is placed into RTC memory using RTC_DATA_ATTR and
|
||||
* maintains its value when ESP32 wakes from deep sleep.
|
||||
*/
|
||||
|
||||
static void obtain_time(void);
|
||||
static void initialize_sntp(void);
|
||||
|
||||
|
||||
void time_sync_notification_cb(struct timeval *tv)
|
||||
{
|
||||
ESP_LOGI(TAG, "Notification of a time synchronization event");
|
||||
@@ -58,9 +42,6 @@ std::string gettimestring(const char * frm)
|
||||
|
||||
void setup_time()
|
||||
{
|
||||
++boot_count;
|
||||
ESP_LOGI(TAG, "Boot count: %d", boot_count);
|
||||
|
||||
time_t now;
|
||||
struct tm timeinfo;
|
||||
time(&now);
|
||||
@@ -76,8 +57,6 @@ void setup_time()
|
||||
char strftime_buf[64];
|
||||
|
||||
setTimeZone("CET-1CEST,M3.5.0,M10.5.0/3");
|
||||
// setTimeZone("Europe/Berlin");
|
||||
// setTimeZone("Asia/Tokyo");
|
||||
|
||||
localtime_r(&now, &timeinfo);
|
||||
strftime(strftime_buf, sizeof(strftime_buf), "%c", &timeinfo);
|
||||
@@ -101,9 +80,6 @@ void setTimeZone(std::string _tzstring)
|
||||
|
||||
static void obtain_time(void)
|
||||
{
|
||||
// initialize_sntp();
|
||||
|
||||
// wait for time to be set
|
||||
time_t now = 0;
|
||||
struct tm timeinfo = {};
|
||||
int retry = 0;
|
||||
@@ -114,52 +90,28 @@ static void obtain_time(void)
|
||||
ESP_LOGI(TAG, "Waiting for system time to be set... (%d/%d)", retry, retry_count);
|
||||
vTaskDelay(2000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
if (retry == retry_count) {
|
||||
LogFile.WriteToFile("Time Synchzronisation nicht erfolgreich ...");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogFile.WriteToFile("Time erfolgreich ...");
|
||||
}
|
||||
|
||||
time(&now);
|
||||
localtime_r(&now, &timeinfo);
|
||||
}
|
||||
|
||||
void reset_servername(std::string _servername)
|
||||
{
|
||||
printf("Set SNTP-Server: %s\n", _servername.c_str());
|
||||
sntp_stop();
|
||||
sntp_setoperatingmode(SNTP_OPMODE_POLL);
|
||||
sntp_setservername(0, _servername.c_str());
|
||||
sntp_init();
|
||||
obtain_time();
|
||||
std::string zw = gettimestring("%Y%m%d-%H%M%S");
|
||||
printf("Time ist %s\n", zw.c_str());
|
||||
}
|
||||
|
||||
static void initialize_sntp(void)
|
||||
{
|
||||
ESP_LOGI(TAG, "Initializing SNTP");
|
||||
sntp_setoperatingmode(SNTP_OPMODE_POLL);
|
||||
sntp_setservername(0, "pool.ntp.org");
|
||||
sntp_set_time_sync_notification_cb(time_sync_notification_cb);
|
||||
// sntp_set_time_sync_notification_cb(time_sync_notification_cb);
|
||||
sntp_init();
|
||||
}
|
||||
|
||||
|
||||
void task_doTimeSync(void *pvParameter)
|
||||
{
|
||||
time_t now;
|
||||
struct tm timeinfo;
|
||||
char strftime_buf[64];
|
||||
int *zw_int = (int*) pvParameter;
|
||||
|
||||
printf("Start Autoupdate Time every: %d Stunden\n", *zw_int );
|
||||
TickType_t xDelay = ((*zw_int) * 60 * 60 * 1000) / portTICK_PERIOD_MS;
|
||||
|
||||
while (1)
|
||||
{
|
||||
obtain_time();
|
||||
localtime_r(&now, &timeinfo);
|
||||
strftime(strftime_buf, sizeof(strftime_buf), "%c", &timeinfo);
|
||||
ESP_LOGI(TAG, "The current date/time in Berlin is: %s", strftime_buf);
|
||||
|
||||
strftime(strftime_buf, sizeof(strftime_buf), "%Y-%m-%d_%H:%M", &timeinfo);
|
||||
ESP_LOGI(TAG, "The current date/time in Berlin is: %s", strftime_buf);
|
||||
|
||||
std::string zw = gettimestring("%Y%m%d-%H%M%S");
|
||||
printf("time %s\n", zw.c_str());
|
||||
|
||||
vTaskDelay( xDelay );
|
||||
}
|
||||
vTaskDelete(NULL); //Delete this task if it exits from the loop above
|
||||
}
|
||||
@@ -12,11 +12,8 @@
|
||||
// #include "nvs_flash.h"
|
||||
#include "esp_sntp.h"
|
||||
|
||||
|
||||
extern int boot_count;
|
||||
|
||||
void setup_time(void);
|
||||
|
||||
std::string gettimestring(const char * frm);
|
||||
void task_doTimeSync(void *pvParameter);
|
||||
void setTimeZone(std::string _tzstring);
|
||||
void reset_servername(std::string _servername);
|
||||
@@ -53,7 +53,7 @@ endif()
|
||||
#######################################################################
|
||||
|
||||
|
||||
FILE(GLOB_RECURSE app_sources ${CMAKE_SOURCE_DIR}/src/*.*)
|
||||
FILE(GLOB_RECURSE app_sources ${CMAKE_SOURCE_DIR}/main/*.*)
|
||||
|
||||
# idf_component_register(SRCS ${app_sources})
|
||||
|
||||
|
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 6.3 KiB |
@@ -25,7 +25,7 @@
|
||||
#include "ClassControllCamera.h"
|
||||
#include "server_main.h"
|
||||
#include "server_camera.h"
|
||||
|
||||
#include "server_GPIO.h"
|
||||
static const char *TAGMAIN = "connect_wlan_main";
|
||||
|
||||
#define FLASH_GPIO GPIO_NUM_4
|
||||
@@ -44,10 +44,15 @@ void Init_NVS_SDCard()
|
||||
// sdmmc_host_t host = SDMMC_HOST_SLOT_1();
|
||||
// host.flags = SDMMC_HOST_FLAG_1BIT;
|
||||
sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
|
||||
slot_config.width = 1; // 1 line SD mode
|
||||
|
||||
esp_vfs_fat_sdmmc_mount_config_t mount_config = { };
|
||||
mount_config.format_if_mount_failed = false;
|
||||
mount_config.max_files = 5;
|
||||
|
||||
gpio_set_pull_mode((gpio_num_t) 15, GPIO_PULLUP_ONLY); // CMD, needed in 4- and 1- line modes
|
||||
gpio_set_pull_mode((gpio_num_t) 2, GPIO_PULLUP_ONLY); // D0, needed in 4- and 1-line modes
|
||||
|
||||
sdmmc_card_t* card;
|
||||
ret = esp_vfs_fat_sdmmc_mount("/sdcard", &host, &slot_config, &mount_config, &card);
|
||||
if (ret != ESP_OK) {
|
||||
@@ -81,13 +86,32 @@ extern "C" void app_main(void)
|
||||
std::string ssid = "";
|
||||
std::string password = "";
|
||||
std::string hostname = "";
|
||||
std::string ip = "";
|
||||
std::string gw = "";
|
||||
std::string netmask = "";
|
||||
std::string dns = "";
|
||||
|
||||
// LoadWlanFromFile("/sdcard/wlan.ini", ssid, password, hostname, ip, gw, netmask, dns);
|
||||
LoadWlanFromFile("/sdcard/wlan.ini", ssid, password, hostname);
|
||||
LoadNetConfigFromFile("/sdcard/wlan.ini", ip, gw, netmask, dns);
|
||||
|
||||
// LogFile.WriteToFile("Startsequence 04");
|
||||
printf("To use WLan: %s, %s\n", ssid.c_str(), password.c_str());
|
||||
printf("To set Hostename: %s\n", hostname.c_str());
|
||||
printf("Fixed IP: %s, Gateway %s, Netmask %s, DNS %s\n", ip.c_str(), gw.c_str(), netmask.c_str(), dns.c_str());
|
||||
|
||||
if (ip.length() == 0 || gw.length() == 0 || netmask.length() == 0)
|
||||
{
|
||||
initialise_wifi(ssid, password, hostname);
|
||||
}
|
||||
else
|
||||
{
|
||||
initialise_wifi_fixed_ip(ip, gw, netmask, ssid, password, hostname, dns);
|
||||
}
|
||||
|
||||
printf("Netparameter: IP: %s - GW: %s - NetMask %s\n", getIPAddress().c_str(), getGW().c_str(), getNetMask().c_str());
|
||||
|
||||
|
||||
initialise_wifi(ssid, password, hostname);
|
||||
// LogFile.WriteToFile("Startsequence 05");
|
||||
|
||||
TickType_t xDelay;
|
||||
@@ -97,7 +121,9 @@ extern "C" void app_main(void)
|
||||
vTaskDelay( xDelay );
|
||||
// LogFile.WriteToFile("Startsequence 07");
|
||||
setup_time();
|
||||
LogFile.WriteToFile("============================== Main Started =======================================");
|
||||
LogFile.WriteToFile("=============================================================================================");
|
||||
LogFile.WriteToFile("=================================== Main Started ============================================");
|
||||
LogFile.WriteToFile("=============================================================================================");
|
||||
LogFile.SwitchOnOff(false);
|
||||
|
||||
std::string zw = gettimestring("%Y%m%d-%H%M%S");
|
||||
@@ -114,6 +140,7 @@ extern "C" void app_main(void)
|
||||
register_server_tflite_uri(server);
|
||||
register_server_file_uri(server, "/sdcard");
|
||||
register_server_ota_sdcard_uri(server);
|
||||
register_server_GPIO_uri(server);
|
||||
register_server_main_uri(server, "/sdcard");
|
||||
|
||||
TFliteDoAutoStart();
|
||||
@@ -13,16 +13,24 @@
|
||||
|
||||
#include "esp_wifi.h"
|
||||
|
||||
#include "server_tflite.h"
|
||||
|
||||
//#define DEBUG_DETAIL_ON
|
||||
|
||||
|
||||
|
||||
httpd_handle_t server = NULL;
|
||||
|
||||
|
||||
std::string starttime = "";
|
||||
|
||||
|
||||
/* An HTTP GET handler */
|
||||
esp_err_t info_get_handler(httpd_req_t *req)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("info_get_handler - Start");
|
||||
#endif
|
||||
|
||||
LogFile.WriteToFile("info_get_handler");
|
||||
char _query[200];
|
||||
char _valuechar[30];
|
||||
@@ -123,25 +131,40 @@ esp_err_t info_get_handler(httpd_req_t *req)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("info_get_handler - Done");
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t starttime_get_handler(httpd_req_t *req)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("starttime_get_handler - Start");
|
||||
#endif
|
||||
|
||||
httpd_resp_send(req, starttime.c_str(), strlen(starttime.c_str()));
|
||||
/* Respond with an empty chunk to signal HTTP response completion */
|
||||
httpd_resp_send_chunk(req, NULL, 0);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("starttime_get_handler - Done");
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t hello_main_handler(httpd_req_t *req)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("hello_main_handler - Start");
|
||||
#endif
|
||||
|
||||
char filepath[50];
|
||||
struct stat file_stat;
|
||||
printf("uri: %s\n", req->uri);
|
||||
int _pos;
|
||||
esp_err_t res;
|
||||
|
||||
char *base_path = (char*) req->user_ctx;
|
||||
std::string filetosend(base_path);
|
||||
@@ -152,7 +175,9 @@ esp_err_t hello_main_handler(httpd_req_t *req)
|
||||
|
||||
if ((strcmp(req->uri, "/") == 0))
|
||||
{
|
||||
filetosend = filetosend + "/html/index.html";
|
||||
{
|
||||
filetosend = filetosend + "/html/index.html";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -163,6 +188,11 @@ esp_err_t hello_main_handler(httpd_req_t *req)
|
||||
}
|
||||
}
|
||||
|
||||
if (filetosend == "/sdcard/html/index.html" && isSetupModusActive()) {
|
||||
printf("System ist im Setupmodus --> index.html --> setup.html");
|
||||
filetosend = "/sdcard/html/setup.html";
|
||||
}
|
||||
|
||||
printf("Filename: %s\n", filename);
|
||||
|
||||
printf("File requested: %s\n", filetosend.c_str());
|
||||
@@ -173,60 +203,37 @@ esp_err_t hello_main_handler(httpd_req_t *req)
|
||||
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Filename too long");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
if (stat(filetosend.c_str(), &file_stat) == -1) {
|
||||
/* If file not present on SPIFFS check if URI
|
||||
* corresponds to one of the hardcoded paths */
|
||||
ESP_LOGE(TAG, "Failed to stat file : %s", filetosend.c_str());
|
||||
/* Respond with 404 Not Found */
|
||||
httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "File does not exist");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
esp_err_t res;
|
||||
res = httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
if (res != ESP_OK)
|
||||
return res;
|
||||
|
||||
res = send_file(req, filetosend, &file_stat);
|
||||
res = send_file(req, filetosend);
|
||||
if (res != ESP_OK)
|
||||
return res;
|
||||
|
||||
/* Respond with an empty chunk to signal HTTP response completion */
|
||||
httpd_resp_send_chunk(req, NULL, 0);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("hello_main_handler - Stop");
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t img_tmp_handler(httpd_req_t *req)
|
||||
{
|
||||
char filepath[50];
|
||||
struct stat file_stat;
|
||||
printf("uri: %s\n", req->uri);
|
||||
|
||||
char *base_path = (char*) req->user_ctx;
|
||||
std::string filetosend(base_path);
|
||||
|
||||
const char *filename = get_path_from_uri(filepath, base_path,
|
||||
req->uri + sizeof("/img_tmp") - 1, sizeof(filepath));
|
||||
req->uri + sizeof("/img_tmp/") - 1, sizeof(filepath));
|
||||
printf("1 uri: %s, filename: %s, filepath: %s\n", req->uri, filename, filepath);
|
||||
|
||||
filetosend = filetosend + "/img_tmp/" + std::string(filename);
|
||||
printf("File to upload: %s\n", filetosend.c_str());
|
||||
|
||||
if (!filename) {
|
||||
ESP_LOGE(TAG, "Filename is too long");
|
||||
/* Respond with 500 Internal Server Error */
|
||||
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Filename too long");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
if (stat(filetosend.c_str(), &file_stat) == -1) {
|
||||
/* If file not present on SPIFFS check if URI
|
||||
* corresponds to one of the hardcoded paths */
|
||||
ESP_LOGE(TAG, "Failed to stat file : %s", filetosend.c_str());
|
||||
/* Respond with 404 Not Found */
|
||||
httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "File does not exist");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t res = send_file(req, filetosend, &file_stat);
|
||||
esp_err_t res = send_file(req, filetosend);
|
||||
if (res != ESP_OK)
|
||||
return res;
|
||||
|
||||
@@ -235,8 +242,54 @@ esp_err_t img_tmp_handler(httpd_req_t *req)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t img_tmp_virtual_handler(httpd_req_t *req)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("img_tmp_virtual_handler - Start");
|
||||
#endif
|
||||
|
||||
char filepath[50];
|
||||
|
||||
printf("uri: %s\n", req->uri);
|
||||
|
||||
char *base_path = (char*) req->user_ctx;
|
||||
std::string filetosend(base_path);
|
||||
|
||||
const char *filename = get_path_from_uri(filepath, base_path,
|
||||
req->uri + sizeof("/img_tmp/") - 1, sizeof(filepath));
|
||||
printf("1 uri: %s, filename: %s, filepath: %s\n", req->uri, filename, filepath);
|
||||
|
||||
filetosend = std::string(filename);
|
||||
printf("File to upload: %s\n", filetosend.c_str());
|
||||
|
||||
if (filetosend == "raw.jpg")
|
||||
{
|
||||
return GetRawJPG(req);
|
||||
}
|
||||
|
||||
esp_err_t zw = GetJPG(filetosend, req);
|
||||
|
||||
if (zw == ESP_OK)
|
||||
return ESP_OK;
|
||||
|
||||
// File wird nicht intern bereit gestellt --> klassischer weg:
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("img_tmp_virtual_handler - Done");
|
||||
#endif
|
||||
|
||||
return img_tmp_handler(req);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
esp_err_t sysinfo_handler(httpd_req_t *req)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("sysinfo_handler - Start");
|
||||
#endif
|
||||
|
||||
const char* resp_str;
|
||||
std::string zw;
|
||||
std::string cputemp = std::to_string(temperatureRead());
|
||||
@@ -272,6 +325,10 @@ esp_err_t sysinfo_handler(httpd_req_t *req)
|
||||
/* Respond with an empty chunk to signal HTTP response completion */
|
||||
httpd_resp_send_chunk(req, NULL, 0);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("sysinfo_handler - Done");
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@@ -305,7 +362,7 @@ void register_server_main_uri(httpd_handle_t server, const char *base_path)
|
||||
httpd_uri_t img_tmp_handle = {
|
||||
.uri = "/img_tmp/*", // Match all URIs of type /path/to/file
|
||||
.method = HTTP_GET,
|
||||
.handler = img_tmp_handler,
|
||||
.handler = img_tmp_virtual_handler,
|
||||
.user_ctx = (void*) base_path // Pass server data as context
|
||||
};
|
||||
httpd_register_uri_handler(server, &img_tmp_handle);
|
||||
@@ -22,9 +22,4 @@ httpd_handle_t start_webserver(void);
|
||||
|
||||
void register_server_main_uri(httpd_handle_t server, const char *base_path);
|
||||
|
||||
|
||||
//void disconnect_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data);
|
||||
//void connect_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data);
|
||||
|
||||
|
||||
#endif
|
||||
4
code/main/version.cpp
Normal file
4
code/main/version.cpp
Normal file
@@ -0,0 +1,4 @@
|
||||
const char* GIT_REV="46cfe45";
|
||||
const char* GIT_TAG="";
|
||||
const char* GIT_BRANCH="master";
|
||||
const char* BUILD_TIME="2021-01-20 19:47";
|
||||
@@ -13,7 +13,7 @@ extern "C"
|
||||
#include "Helper.h"
|
||||
#include <fstream>
|
||||
|
||||
const char* GIT_BASE_BRANCH = "master - v4.1.0 - 2020-11-30";
|
||||
const char* GIT_BASE_BRANCH = "master - v6.1.0 - 2020-01-20";
|
||||
|
||||
|
||||
const char* git_base_branch(void)
|
||||
@@ -9,20 +9,20 @@
|
||||
; https://docs.platformio.org/page/projectconf.html
|
||||
|
||||
|
||||
[platformio]
|
||||
src_dir = main
|
||||
|
||||
|
||||
[env:esp32cam]
|
||||
platform = espressif32
|
||||
platform = espressif32@2.1.0
|
||||
board = esp32cam
|
||||
framework = espidf
|
||||
|
||||
board_build.embed_files =
|
||||
src/favicon.ico
|
||||
|
||||
|
||||
;board_build.partitions = partitions_singleapp.csv
|
||||
board_build.partitions = partitions.csv
|
||||
|
||||
|
||||
|
||||
lib_deps =
|
||||
jomjol_helper
|
||||
connect_wlan
|
||||
@@ -35,6 +35,7 @@ lib_deps =
|
||||
jomjol_time_sntp
|
||||
jomjol_logfile
|
||||
jomjol_mqtt
|
||||
jomjol_controlGPIO
|
||||
|
||||
monitor_speed = 115200
|
||||
|
||||
|
||||
110
code/sdkconfig
110
code/sdkconfig
@@ -83,11 +83,11 @@ CONFIG_ESPTOOLPY_FLASHFREQ_40M=y
|
||||
# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set
|
||||
CONFIG_ESPTOOLPY_FLASHFREQ="40m"
|
||||
# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y
|
||||
# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set
|
||||
# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
||||
# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set
|
||||
# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE="2MB"
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE="4MB"
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y
|
||||
CONFIG_ESPTOOLPY_BEFORE_RESET=y
|
||||
# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set
|
||||
@@ -109,11 +109,11 @@ CONFIG_ESPTOOLPY_MONITOR_BAUD=115200
|
||||
#
|
||||
# Partition Table
|
||||
#
|
||||
CONFIG_PARTITION_TABLE_SINGLE_APP=y
|
||||
# CONFIG_PARTITION_TABLE_SINGLE_APP is not set
|
||||
# CONFIG_PARTITION_TABLE_TWO_OTA is not set
|
||||
# CONFIG_PARTITION_TABLE_CUSTOM is not set
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||
CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv"
|
||||
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
||||
CONFIG_PARTITION_TABLE_OFFSET=0x8000
|
||||
CONFIG_PARTITION_TABLE_MD5=y
|
||||
# end of Partition Table
|
||||
@@ -173,7 +173,95 @@ CONFIG_BTDM_BLE_SLEEP_CLOCK_ACCURACY_INDEX_EFF=1
|
||||
CONFIG_BT_RESERVE_DRAM=0
|
||||
# end of Bluetooth
|
||||
|
||||
# CONFIG_BLE_MESH is not set
|
||||
CONFIG_BLE_MESH=y
|
||||
CONFIG_BLE_MESH_HCI_5_0=y
|
||||
# CONFIG_BLE_MESH_ALLOC_FROM_PSRAM_FIRST is not set
|
||||
# CONFIG_BLE_MESH_FAST_PROV is not set
|
||||
# CONFIG_BLE_MESH_NODE is not set
|
||||
# CONFIG_BLE_MESH_PROVISIONER is not set
|
||||
CONFIG_BLE_MESH_PROV=y
|
||||
CONFIG_BLE_MESH_PB_ADV=y
|
||||
# CONFIG_BLE_MESH_PB_GATT is not set
|
||||
CONFIG_BLE_MESH_PROXY=y
|
||||
# CONFIG_BLE_MESH_GATT_PROXY_CLIENT is not set
|
||||
CONFIG_BLE_MESH_NET_BUF_POOL_USAGE=y
|
||||
# CONFIG_BLE_MESH_SETTINGS is not set
|
||||
CONFIG_BLE_MESH_SUBNET_COUNT=3
|
||||
CONFIG_BLE_MESH_APP_KEY_COUNT=3
|
||||
CONFIG_BLE_MESH_MODEL_KEY_COUNT=3
|
||||
CONFIG_BLE_MESH_MODEL_GROUP_COUNT=3
|
||||
CONFIG_BLE_MESH_LABEL_COUNT=3
|
||||
CONFIG_BLE_MESH_CRPL=10
|
||||
CONFIG_BLE_MESH_MSG_CACHE_SIZE=10
|
||||
CONFIG_BLE_MESH_ADV_BUF_COUNT=60
|
||||
# CONFIG_BLE_MESH_SUPPORT_BLE_ADV is not set
|
||||
CONFIG_BLE_MESH_IVU_DIVIDER=4
|
||||
CONFIG_BLE_MESH_TX_SEG_MSG_COUNT=1
|
||||
CONFIG_BLE_MESH_RX_SEG_MSG_COUNT=1
|
||||
CONFIG_BLE_MESH_RX_SDU_MAX=384
|
||||
CONFIG_BLE_MESH_TX_SEG_MAX=32
|
||||
# CONFIG_BLE_MESH_FRIEND is not set
|
||||
# CONFIG_BLE_MESH_NO_LOG is not set
|
||||
|
||||
#
|
||||
# BLE Mesh STACK DEBUG LOG LEVEL
|
||||
#
|
||||
# CONFIG_BLE_MESH_TRACE_LEVEL_NONE is not set
|
||||
# CONFIG_BLE_MESH_TRACE_LEVEL_ERROR is not set
|
||||
CONFIG_BLE_MESH_TRACE_LEVEL_WARNING=y
|
||||
# CONFIG_BLE_MESH_TRACE_LEVEL_INFO is not set
|
||||
# CONFIG_BLE_MESH_TRACE_LEVEL_DEBUG is not set
|
||||
# CONFIG_BLE_MESH_TRACE_LEVEL_VERBOSE is not set
|
||||
CONFIG_BLE_MESH_STACK_TRACE_LEVEL=2
|
||||
# end of BLE Mesh STACK DEBUG LOG LEVEL
|
||||
|
||||
#
|
||||
# BLE Mesh NET BUF DEBUG LOG LEVEL
|
||||
#
|
||||
# CONFIG_BLE_MESH_NET_BUF_TRACE_LEVEL_NONE is not set
|
||||
# CONFIG_BLE_MESH_NET_BUF_TRACE_LEVEL_ERROR is not set
|
||||
CONFIG_BLE_MESH_NET_BUF_TRACE_LEVEL_WARNING=y
|
||||
# CONFIG_BLE_MESH_NET_BUF_TRACE_LEVEL_INFO is not set
|
||||
# CONFIG_BLE_MESH_NET_BUF_TRACE_LEVEL_DEBUG is not set
|
||||
# CONFIG_BLE_MESH_NET_BUF_TRACE_LEVEL_VERBOSE is not set
|
||||
CONFIG_BLE_MESH_NET_BUF_TRACE_LEVEL=2
|
||||
# end of BLE Mesh NET BUF DEBUG LOG LEVEL
|
||||
|
||||
CONFIG_BLE_MESH_CLIENT_MSG_TIMEOUT=4000
|
||||
|
||||
#
|
||||
# Support for BLE Mesh Client Models
|
||||
#
|
||||
# CONFIG_BLE_MESH_CFG_CLI is not set
|
||||
# CONFIG_BLE_MESH_HEALTH_CLI is not set
|
||||
# CONFIG_BLE_MESH_GENERIC_ONOFF_CLI is not set
|
||||
# CONFIG_BLE_MESH_GENERIC_LEVEL_CLI is not set
|
||||
# CONFIG_BLE_MESH_GENERIC_DEF_TRANS_TIME_CLI is not set
|
||||
# CONFIG_BLE_MESH_GENERIC_POWER_ONOFF_CLI is not set
|
||||
# CONFIG_BLE_MESH_GENERIC_POWER_LEVEL_CLI is not set
|
||||
# CONFIG_BLE_MESH_GENERIC_BATTERY_CLI is not set
|
||||
# CONFIG_BLE_MESH_GENERIC_LOCATION_CLI is not set
|
||||
# CONFIG_BLE_MESH_GENERIC_PROPERTY_CLI is not set
|
||||
# CONFIG_BLE_MESH_SENSOR_CLI is not set
|
||||
# CONFIG_BLE_MESH_TIME_CLI is not set
|
||||
# CONFIG_BLE_MESH_SCENE_CLI is not set
|
||||
# CONFIG_BLE_MESH_SCHEDULER_CLI is not set
|
||||
# CONFIG_BLE_MESH_LIGHT_LIGHTNESS_CLI is not set
|
||||
# CONFIG_BLE_MESH_LIGHT_CTL_CLI is not set
|
||||
# CONFIG_BLE_MESH_LIGHT_HSL_CLI is not set
|
||||
# CONFIG_BLE_MESH_LIGHT_XYL_CLI is not set
|
||||
# CONFIG_BLE_MESH_LIGHT_LC_CLI is not set
|
||||
# end of Support for BLE Mesh Client Models
|
||||
|
||||
# CONFIG_BLE_MESH_IV_UPDATE_TEST is not set
|
||||
|
||||
#
|
||||
# BLE Mesh specific test option
|
||||
#
|
||||
# CONFIG_BLE_MESH_SELF_TEST is not set
|
||||
# CONFIG_BLE_MESH_SHELL is not set
|
||||
# CONFIG_BLE_MESH_DEBUG is not set
|
||||
# end of BLE Mesh specific test option
|
||||
|
||||
#
|
||||
# CoAP Configuration
|
||||
@@ -537,8 +625,8 @@ CONFIG_FATFS_MAX_LFN=255
|
||||
CONFIG_FATFS_API_ENCODING_ANSI_OEM=y
|
||||
# CONFIG_FATFS_API_ENCODING_UTF_16 is not set
|
||||
# CONFIG_FATFS_API_ENCODING_UTF_8 is not set
|
||||
CONFIG_FATFS_FS_LOCK=5
|
||||
CONFIG_FATFS_TIMEOUT_MS=10000
|
||||
CONFIG_FATFS_FS_LOCK=10
|
||||
CONFIG_FATFS_TIMEOUT_MS=5000
|
||||
CONFIG_FATFS_PER_FILE_CACHE=y
|
||||
CONFIG_FATFS_ALLOC_PREFER_EXTRAM=y
|
||||
# end of FAT Filesystem support
|
||||
@@ -965,7 +1053,7 @@ CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y
|
||||
#
|
||||
# Virtual file system
|
||||
#
|
||||
CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y
|
||||
# CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT is not set
|
||||
CONFIG_VFS_SUPPORT_TERMIOS=y
|
||||
|
||||
#
|
||||
@@ -1166,6 +1254,6 @@ CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread"
|
||||
CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y
|
||||
# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS is not set
|
||||
# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set
|
||||
CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y
|
||||
# CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT is not set
|
||||
CONFIG_SUPPORT_TERMIOS=y
|
||||
# End of deprecated options
|
||||
|
||||
@@ -83,11 +83,11 @@ CONFIG_ESPTOOLPY_FLASHFREQ_40M=y
|
||||
# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set
|
||||
CONFIG_ESPTOOLPY_FLASHFREQ="40m"
|
||||
# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y
|
||||
# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set
|
||||
# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
||||
# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set
|
||||
# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE="2MB"
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE="4MB"
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y
|
||||
CONFIG_ESPTOOLPY_BEFORE_RESET=y
|
||||
# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set
|
||||
@@ -109,11 +109,11 @@ CONFIG_ESPTOOLPY_MONITOR_BAUD=115200
|
||||
#
|
||||
# Partition Table
|
||||
#
|
||||
CONFIG_PARTITION_TABLE_SINGLE_APP=y
|
||||
# CONFIG_PARTITION_TABLE_SINGLE_APP is not set
|
||||
# CONFIG_PARTITION_TABLE_TWO_OTA is not set
|
||||
# CONFIG_PARTITION_TABLE_CUSTOM is not set
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||
CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv"
|
||||
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
||||
CONFIG_PARTITION_TABLE_OFFSET=0x8000
|
||||
CONFIG_PARTITION_TABLE_MD5=y
|
||||
# end of Partition Table
|
||||
@@ -315,8 +315,8 @@ CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR=y
|
||||
CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES=4
|
||||
# CONFIG_ESP32_ULP_COPROC_ENABLED is not set
|
||||
CONFIG_ESP32_ULP_COPROC_RESERVE_MEM=0
|
||||
# CONFIG_ESP32_PANIC_PRINT_HALT is not set
|
||||
CONFIG_ESP32_PANIC_PRINT_REBOOT=y
|
||||
CONFIG_ESP32_PANIC_PRINT_HALT=y
|
||||
# CONFIG_ESP32_PANIC_PRINT_REBOOT is not set
|
||||
# CONFIG_ESP32_PANIC_SILENT_REBOOT is not set
|
||||
# CONFIG_ESP32_PANIC_GDBSTUB is not set
|
||||
CONFIG_ESP32_DEBUG_OCDAWARE=y
|
||||
@@ -537,8 +537,8 @@ CONFIG_FATFS_MAX_LFN=255
|
||||
CONFIG_FATFS_API_ENCODING_ANSI_OEM=y
|
||||
# CONFIG_FATFS_API_ENCODING_UTF_16 is not set
|
||||
# CONFIG_FATFS_API_ENCODING_UTF_8 is not set
|
||||
CONFIG_FATFS_FS_LOCK=2
|
||||
CONFIG_FATFS_TIMEOUT_MS=10000
|
||||
CONFIG_FATFS_FS_LOCK=10
|
||||
CONFIG_FATFS_TIMEOUT_MS=5000
|
||||
CONFIG_FATFS_PER_FILE_CACHE=y
|
||||
CONFIG_FATFS_ALLOC_PREFER_EXTRAM=y
|
||||
# end of FAT Filesystem support
|
||||
@@ -965,7 +965,7 @@ CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y
|
||||
#
|
||||
# Virtual file system
|
||||
#
|
||||
CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y
|
||||
# CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT is not set
|
||||
CONFIG_VFS_SUPPORT_TERMIOS=y
|
||||
|
||||
#
|
||||
@@ -1166,6 +1166,6 @@ CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread"
|
||||
CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y
|
||||
# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS is not set
|
||||
# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set
|
||||
CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y
|
||||
# CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT is not set
|
||||
CONFIG_SUPPORT_TERMIOS=y
|
||||
# End of deprecated options
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
const char* GIT_REV="ffc15aa";
|
||||
const char* GIT_TAG="";
|
||||
const char* GIT_BRANCH="master";
|
||||
const char* BUILD_TIME="2020-12-02 21:56";
|
||||
@@ -1,4 +1,4 @@
|
||||
const char* GIT_REV="ffc15aa";
|
||||
const char* GIT_REV="46cfe45";
|
||||
const char* GIT_TAG="";
|
||||
const char* GIT_BRANCH="master";
|
||||
const char* BUILD_TIME="2020-12-02 21:55";
|
||||
const char* BUILD_TIME="2021-01-20 19:47";
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -11,10 +11,11 @@ InitalRotate=180
|
||||
/config/ref1.jpg 456 138
|
||||
SearchFieldX = 20
|
||||
SearchFieldY = 20
|
||||
AlignmentAlgo = Default
|
||||
|
||||
|
||||
[Digits]
|
||||
Model = /config/dig0720s1.tflite
|
||||
Model = /config/dig0721s1.tflite
|
||||
;LogImageLocation = /log/digit
|
||||
;LogfileRetentionInDays = 3
|
||||
ModelInputSize = 20 32
|
||||
@@ -31,6 +32,7 @@ analog1 444 225 92 92
|
||||
analog2 391 329 92 92
|
||||
analog3 294 369 92 92
|
||||
analog4 168 326 92 92
|
||||
ExtendedResolution = false
|
||||
|
||||
[PostProcessing]
|
||||
DecimalShift = 0
|
||||
@@ -39,13 +41,13 @@ PreValueAgeStartup = 720
|
||||
AllowNegativeRates = false
|
||||
MaxRateValue = 0.1
|
||||
ErrorMessage = true
|
||||
CheckDigitIncreaseConsistency = true
|
||||
CheckDigitIncreaseConsistency = false
|
||||
|
||||
[MQTT]
|
||||
Uri = mqtt://IP-ADRESS:1883
|
||||
Topic = wasserzaehler/zaehlerstand
|
||||
TopicError = wasserzaehler/error
|
||||
ClientID = wasser
|
||||
;Uri = mqtt://IP-ADRESS:1883
|
||||
;Topic = wasserzaehler/zaehlerstand
|
||||
;TopicError = wasserzaehler/error
|
||||
;ClientID = wasser
|
||||
;user = USERNAME
|
||||
;password = PASSWORD
|
||||
|
||||
@@ -59,5 +61,8 @@ LogfileRetentionInDays = 3
|
||||
|
||||
[System]
|
||||
TimeZone = CET-1CEST,M3.5.0,M10.5.0/3
|
||||
;TimeServer = fritz.box
|
||||
;hostname = watermeter
|
||||
SetupMode = true
|
||||
|
||||
[Ende]
|
||||
Binary file not shown.
Binary file not shown.
BIN
sd-card/config/dig0721s1.tflite
Normal file
BIN
sd-card/config/dig0721s1.tflite
Normal file
Binary file not shown.
BIN
sd-card/html/cnn_images.jpg
Normal file
BIN
sd-card/html/cnn_images.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 30 KiB |
3
sd-card/html/debug.log
Normal file
3
sd-card/html/debug.log
Normal file
@@ -0,0 +1,3 @@
|
||||
[1204/185120.033:ERROR:directory_reader_win.cc(43)] FindFirstFile: Das System kann den angegebenen Pfad nicht finden. (0x3)
|
||||
[0102/122131.430:ERROR:directory_reader_win.cc(43)] FindFirstFile: Das System kann den angegebenen Pfad nicht finden. (0x3)
|
||||
[0118/210038.095:ERROR:directory_reader_win.cc(43)] FindFirstFile: Das System kann den angegebenen Pfad nicht finden. (0x3)
|
||||
@@ -91,6 +91,7 @@ select {
|
||||
|
||||
<script type="text/javascript" src="./gethost.js"></script>
|
||||
<script type="text/javascript" src="./readconfig.js"></script>
|
||||
<script type="text/javascript" src="./readconfigcommon.js"></script>
|
||||
|
||||
<script language="JavaScript">
|
||||
var canvas = document.getElementById('canvas'),
|
||||
|
||||
@@ -49,13 +49,26 @@ select {
|
||||
th, td {
|
||||
padding: 5px 5px 5px 0px;
|
||||
}
|
||||
|
||||
#div2{
|
||||
background-color:#777;
|
||||
margin-bottom:20px;
|
||||
}
|
||||
.disabledDiv {
|
||||
pointer-events: none;
|
||||
opacity: 0.4;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
<body style="font-family: arial; padding: 0px 10px;">
|
||||
|
||||
<h2>Edit Analog</h2>
|
||||
<h2><input type="checkbox" id="Category_Analog_enabled" value="1" onclick = 'EnDisableAnalog()' checked >
|
||||
Edit Analog</h2>
|
||||
|
||||
|
||||
<div id="div1">
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
@@ -78,8 +91,8 @@ th, td {
|
||||
</td>
|
||||
<td>Name: <input type="text" name="name" id="name" onchange="onNameChange()" size="13"></td>
|
||||
<td>
|
||||
<input class="move" type="submit" id="moveNext" onclick="moveNext()" value="move Next">
|
||||
<input class="move" type="submit" id="movePrevious" onclick="movePrevious()" value="move Previous">
|
||||
<input class="button" type="submit" id="moveNext" onclick="moveNext()" value="move Next">
|
||||
<input class="button" type="submit" id="movePrevious" onclick="movePrevious()" value="move Previous">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -92,15 +105,19 @@ th, td {
|
||||
<td>dy: <input type="number" name="refdy" id="refdy" step=1 onchange="valuemanualchanged()"></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td><input class="button" type="submit" id="saveroi" name="saveroi" onclick="SaveToConfig()" value="Save all to Config.ini"></td>
|
||||
</tr>
|
||||
</table>
|
||||
</table>
|
||||
|
||||
|
||||
<script type="text/javascript" src="./gethost.js"></script>
|
||||
<script type="text/javascript" src="./readconfigcommon.js"></script>
|
||||
<script type="text/javascript" src="./readconfig.js"></script>
|
||||
<script type="text/javascript" src="./jquery-3.5.1.min.js"></script>
|
||||
|
||||
<script language="JavaScript">
|
||||
var canvas = document.getElementById('canvas'),
|
||||
@@ -114,6 +131,40 @@ th, td {
|
||||
lockAR = true;
|
||||
basepath = "http://192.168.178.26";
|
||||
|
||||
|
||||
function EnDisableAnalog() {
|
||||
isEnabled = document.getElementById("Category_Analog_enabled").checked;
|
||||
|
||||
$("#div2").attr("disabled", "disabled").off('click');
|
||||
var x1=$("#div2").hasClass("disabledDiv");
|
||||
|
||||
if (isEnabled)
|
||||
{
|
||||
$("#div2").removeClass("disabledDiv");
|
||||
}
|
||||
else
|
||||
{
|
||||
$("#div2").addClass("disabledDiv");
|
||||
}
|
||||
|
||||
sah1(document.getElementById("div1"), !isEnabled);
|
||||
if (isEnabled)
|
||||
{
|
||||
UpdateROIs();
|
||||
}
|
||||
}
|
||||
|
||||
function sah1(el, _target) {
|
||||
try {
|
||||
el.disabled = _target;
|
||||
} catch (E) {}
|
||||
if (el.childNodes && el.childNodes.length > 0) {
|
||||
for (var x = 0; x < el.childNodes.length; x++) {
|
||||
sah1(el.childNodes[x], _target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onNameChange(){
|
||||
ROIInfo[aktindex]["name"] = document.getElementById("name").value;
|
||||
UpdateROIs();
|
||||
@@ -172,7 +223,8 @@ function ChangeSelection(){
|
||||
}
|
||||
|
||||
function SaveToConfig(){
|
||||
SaveROIToConfig(ROIInfo, "[Analog]", basepath);
|
||||
_enabled = document.getElementById("Category_Analog_enabled").checked;
|
||||
SaveROIToConfig(ROIInfo, "[Analog]", basepath, _enabled);
|
||||
UpdatePage();
|
||||
}
|
||||
|
||||
@@ -230,8 +282,18 @@ function UpdateROIs(){
|
||||
function ParseIni(_basepath) {
|
||||
loadConfig(_basepath);
|
||||
ParseConfig();
|
||||
|
||||
document.getElementById("Category_Analog_enabled").checked = true;
|
||||
ROIInfo = getROIInfo("[Analog]");
|
||||
|
||||
if (!GetAnalogEnabled())
|
||||
{
|
||||
document.getElementById("Category_Analog_enabled").checked = false;
|
||||
EnDisableAnalog();
|
||||
alert("Analog ROIs are disabled - please enable (Check box top left).\n");
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateROIs();
|
||||
}
|
||||
|
||||
@@ -288,22 +350,25 @@ function ParseIni(_basepath) {
|
||||
}
|
||||
|
||||
|
||||
function draw() {
|
||||
function draw() {
|
||||
var canvas = document.getElementById('canvas');
|
||||
var context = canvas.getContext('2d');
|
||||
context.drawImage(imageObj, 0, 0);
|
||||
lw = 4
|
||||
context.lineWidth = lw;
|
||||
context.strokeStyle = "#FF0000";
|
||||
var x0 = parseInt(rect.startX) - parseInt(lw/2);
|
||||
var y0 = parseInt(rect.startY) - parseInt(lw/2);
|
||||
var dx = parseInt(rect.w) + parseInt(lw);
|
||||
var dy = parseInt(rect.h) + parseInt(lw);
|
||||
context.strokeRect(x0, y0, dx, dy);
|
||||
ROIInfo[aktindex]["x"] = rect.startX;
|
||||
ROIInfo[aktindex]["y"] = rect.startY;
|
||||
ROIInfo[aktindex]["dx"] = rect.w;
|
||||
ROIInfo[aktindex]["dy"] = rect.h;
|
||||
if (document.getElementById("Category_Analog_enabled").checked)
|
||||
{
|
||||
lw = 4
|
||||
context.lineWidth = lw;
|
||||
context.strokeStyle = "#FF0000";
|
||||
var x0 = parseInt(rect.startX) - parseInt(lw/2);
|
||||
var y0 = parseInt(rect.startY) - parseInt(lw/2);
|
||||
var dx = parseInt(rect.w) + parseInt(lw);
|
||||
var dy = parseInt(rect.h) + parseInt(lw);
|
||||
context.strokeRect(x0, y0, dx, dy);
|
||||
ROIInfo[aktindex]["x"] = rect.startX;
|
||||
ROIInfo[aktindex]["y"] = rect.startY;
|
||||
ROIInfo[aktindex]["dx"] = rect.w;
|
||||
ROIInfo[aktindex]["dy"] = rect.h;
|
||||
}
|
||||
}
|
||||
|
||||
function getCoords(elem) { // crossbrowser version
|
||||
|
||||
@@ -42,6 +42,7 @@ textarea {
|
||||
|
||||
<script type="text/javascript" src="./gethost.js"></script>
|
||||
<script type="text/javascript" src="./readconfig.js"></script>
|
||||
<script type="text/javascript" src="./readconfigcommon.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
var canvas = document.getElementById('canvas'),
|
||||
|
||||
@@ -61,7 +61,7 @@ textarea {
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="20px" style="padding-left: 40px;">
|
||||
<input type="checkbox" id="MakeImage_LogImageLocation_enabled" value="1" onclick = 'document.getElementById("MakeImage_LogImageLocation_value").disabled = !document.getElementById("MakeImage_LogImageLocation_value1").disabled' unchecked >
|
||||
<input type="checkbox" id="MakeImage_LogImageLocation_enabled" value="1" onclick = 'document.getElementById("MakeImage_LogImageLocation_value1").disabled = !document.getElementById("MakeImage_LogImageLocation_value1").disabled' unchecked >
|
||||
</td>
|
||||
<td width="200px">
|
||||
<class id="MakeImage_LogImageLocation_text" style="color:black;">LogImageLocation</class>
|
||||
@@ -75,7 +75,7 @@ textarea {
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="20px" style="padding-left: 40px;">
|
||||
<td"><input type="checkbox" id="MakeImage_LogfileRetentionInDays_enabled" value="1" onclick = 'document.getElementById("MakeImage_LogfileRetentionInDays_value").disabled = !document.getElementById("MakeImage_LogfileRetentionInDays_value1").disabled' unchecked ></td>
|
||||
<td"><input type="checkbox" id="MakeImage_LogfileRetentionInDays_enabled" value="1" onclick = 'document.getElementById("MakeImage_LogfileRetentionInDays_value1").disabled = !document.getElementById("MakeImage_LogfileRetentionInDays_value1").disabled' unchecked ></td>
|
||||
</td>
|
||||
<td>
|
||||
<class id="MakeImage_LogfileRetentionInDays_text" style="color:black;">LogfileRetentionInDays</class>
|
||||
@@ -123,7 +123,7 @@ textarea {
|
||||
<td>
|
||||
<select id="MakeImage_ImageSize_value1">
|
||||
<option value="0" selected>VGA</option>
|
||||
<option value="1" >SVGA</option>
|
||||
<option value="1" >QVGA</option>
|
||||
</select>
|
||||
</td>
|
||||
<td style="font-size: 80%;">
|
||||
@@ -160,9 +160,29 @@ textarea {
|
||||
y size (height) in which the reference is searched (default = "20")
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="expert" id="AlignmentAlgo_ex8">
|
||||
<td width="20px" style="padding-left: 40px;">
|
||||
<input type="checkbox" id="Alignment_AlignmentAlgo_enabled" value="1" onclick = 'document.getElementById("Alignment_AlignmentAlgo_value1").disabled = !document.getElementById("Alignment_AlignmentAlgo_value1").disabled' unchecked >
|
||||
</td>
|
||||
<td>
|
||||
<class id="Alignment_AlignmentAlgo_text" style="color:black;">AlignmentAlgo</class>
|
||||
</td>
|
||||
<td>
|
||||
<select id="Alignment_AlignmentAlgo_value1">
|
||||
<option value="0" selected>Default</option>
|
||||
<option value="1" >HighAccurity</option>
|
||||
<option value="2" >Fast</option>
|
||||
</select>
|
||||
</td>
|
||||
<td style="font-size: 80%;">
|
||||
"Default" = use only R-Channel, "HighAccurity" = use all Channels (RGB, 3x slower), <br> "Fast" (First time RGB, then only check if image is shifted)
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr class="expert" id="ex4">
|
||||
<td colspan="4" style="padding-left: 20px;"><h4>Digits</h4></td>
|
||||
|
||||
<tr id="Category_Digits_ex4">
|
||||
<td colspan="4" style="padding-left: 20px;">
|
||||
<h4><input type="checkbox" id="Category_Digits_enabled" value="1" onclick = 'UpdateAfterCategoryCheck()' unchecked >Digits</h4></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="20px" style="padding-left: 40px;">
|
||||
@@ -174,7 +194,7 @@ textarea {
|
||||
<input type="text" id="Digits_Model_value1">
|
||||
</td>
|
||||
<td style="font-size: 80%;">
|
||||
path to CNN model file for image recognition (in seconds)
|
||||
path to CNN model file for image recognition
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -221,62 +241,61 @@ textarea {
|
||||
</tr>
|
||||
|
||||
<tr class="expert" id="ex4">
|
||||
<td colspan="4" style="padding-left: 20px;"><h4>Analog</h4></td>
|
||||
<td colspan="4" style="padding-left: 20px;">
|
||||
<h4><input type="checkbox" id="Category_Analog_enabled" value="1" onclick = 'UpdateAfterCategoryCheck()' unchecked > Analog</h4></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="20px" style="padding-left: 40px;">
|
||||
</td>
|
||||
<td width="200px">
|
||||
<class id="Analog_Model_text" style="color:black;">Model</class>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" id="Analog_Model_value1">
|
||||
</td>
|
||||
<td style="font-size: 80%;">
|
||||
path to CNN model file for image recognition (in seconds)
|
||||
</td>
|
||||
<td width="20px" style="padding-left: 40px;"> </td>
|
||||
<td width="200px"> <class id="Analog_Model_text" style="color:black;">Model</class> </td>
|
||||
<td> <input type="text" id="Analog_Model_value1"> </td>
|
||||
<td style="font-size: 80%;"> path to CNN model file for image recognition</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="20px" style="padding-left: 40px;">
|
||||
<input type="checkbox" id="Analog_LogImageLocation_enabled" value="1" onclick = 'document.getElementById("Analog_LogImageLocation_value1").disabled = !document.getElementById("Analog_LogImageLocation_value1").disabled' unchecked >
|
||||
</td>
|
||||
<td>
|
||||
<class id="Analog_LogImageLocation_text" style="color:black;">LogImageLocation</class>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" name="name" id="Analog_LogImageLocation_value1">
|
||||
</td>
|
||||
<td style="font-size: 80%;">
|
||||
Location to store separated digits for logging
|
||||
</td>
|
||||
<td> <class id="Analog_LogImageLocation_text" style="color:black;">LogImageLocation</class> </td>
|
||||
<td> <input type="text" name="name" id="Analog_LogImageLocation_value1"> </td>
|
||||
<td style="font-size: 80%;"> Location to store separated digits for logging </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="20px" style="padding-left: 40px;">
|
||||
<td"><input type="checkbox" id="Analog_LogfileRetentionInDays_enabled" value="1" onclick = 'document.getElementById("Analog_LogfileRetentionInDays_value1").disabled = !document.getElementById("Analog_LogfileRetentionInDays_value1").disabled' unchecked ></td>
|
||||
</td>
|
||||
<td>
|
||||
<class id="Analog_LogfileRetentionInDays_text" style="color:black;">LogfileRetentionInDays</class>
|
||||
<td> <class id="Analog_LogfileRetentionInDays_text" style="color:black;">LogfileRetentionInDays</class> </td>
|
||||
<td> <input type="number" id="Analog_LogfileRetentionInDays_value1" min="0" step="1"> </td>
|
||||
<td style="font-size: 80%;"> Time to keep the separated digit images (in days -"0" = forever) </td>
|
||||
</tr>
|
||||
|
||||
<tr class="expert" id="Analog_ExtendedResolution_ex10">
|
||||
<td width="20px" style="padding-left: 40px;">
|
||||
<input type="checkbox" id="Analog_ExtendedResolution_enabled" value="1" onclick = 'document.getElementById("Analog_ExtendedResolution_value1").disabled = !document.getElementById("Analog_ExtendedResolution_value1").disabled' unchecked >
|
||||
</td>
|
||||
<td width="200px">
|
||||
<class id="Analog_ExtendedResolution_text" style="color:black;">ExtendedResolution</class>
|
||||
</td>
|
||||
<td>
|
||||
<input type="number" id="Analog_LogfileRetentionInDays_value1" min="0" step="1">
|
||||
<select id="Analog_ExtendedResolution_value1">
|
||||
<option value="0" selected>true</option>
|
||||
<option value="1" >false</option>
|
||||
</select>
|
||||
</td>
|
||||
<td style="font-size: 80%;">
|
||||
Time to keep the separated digit images (in days -"0" = forever)
|
||||
Enable to use the after point resolution for the last analog counter
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
ExtendedResolution
|
||||
|
||||
<tr class="expert" id="ex10">
|
||||
<td width="20px" style="padding-left: 40px;">
|
||||
</td>
|
||||
<td>
|
||||
<class id="Analog_ModelInputSize_text" style="color:black;">ModelInputSize</class>
|
||||
</td>
|
||||
<td width="20px" style="padding-left: 40px;"> </td>
|
||||
<td> <class id="Analog_ModelInputSize_text" style="color:black;">ModelInputSize</class> </td>
|
||||
<td>
|
||||
x: <input type="number" id="Analog_ModelInputSize_value1" style="width: 30px;" min="1" step="1">
|
||||
y: <input type="number" id="Analog_ModelInputSize_value2" style="width: 30px;" min="1" step="1">
|
||||
</td>
|
||||
<td style="font-size: 80%;">
|
||||
Size of the input image for the CNN model
|
||||
</td>
|
||||
<td style="font-size: 80%;"> Size of the input image for the CNN model </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -394,7 +413,7 @@ textarea {
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td colspan="4" style="padding-left: 20px;"><h4>MQTT</h4></td>
|
||||
<td colspan="4" style="padding-left: 20px;"><h4><input type="checkbox" id="Category_MQTT_enabled" value="1" onclick = 'UpdateAfterCategoryCheck()' unchecked > MQTT</h4></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="20px" style="padding-left: 40px;">
|
||||
@@ -468,7 +487,7 @@ textarea {
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="20px" style="padding-left: 40px;">
|
||||
<input type="checkbox" id="MQTT_password_enabled" value="1" onclick = 'document.getElementById("MQTT_password_value1").disabled = !document.getElementById("MQTT_password_value1").disabled' checked >
|
||||
<input type="checkbox" id="MQTT_password_enabled" value="1" onclick = 'document.getElementById("MQTT_password_value1").disabled = !document.getElementById("MQTT_password_value1").disabled' unchecked >
|
||||
</td>
|
||||
<td width="200px">
|
||||
<class id="MQTT_password_text" style="color:black;">password</class>
|
||||
@@ -538,7 +557,7 @@ textarea {
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="20px" style="padding-left: 40px;">
|
||||
<td"><input type="checkbox" id="Debug_LogfileRetentionInDays_enabled" value="1" onclick = 'document.getElementById("Debug_LogfileRetentionInDays_value").disabled = !document.getElementById("Debug_LogfileRetentionInDays_value1").disabled' unchecked ></td>
|
||||
<td"><input type="checkbox" id="Debug_LogfileRetentionInDays_enabled" value="1" onclick = 'document.getElementById("Debug_LogfileRetentionInDays_value1").disabled = !document.getElementById("Debug_LogfileRetentionInDays_value1").disabled' unchecked ></td>
|
||||
</td>
|
||||
<td>
|
||||
<class id="Debug_LogfileRetentionInDays_text" style="color:black;">LogfileRetentionInDays</class>
|
||||
@@ -556,7 +575,7 @@ textarea {
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="20px" style="padding-left: 40px;">
|
||||
<td"><input type="checkbox" id="System_TimeZone_enabled" value="1" onclick = 'document.getElementById("System_TimeZone_value").disabled = !document.getElementById("System_TimeZone_value1").disabled' unchecked ></td>
|
||||
<td"><input type="checkbox" id="System_TimeZone_enabled" value="1" onclick = 'document.getElementById("System_TimeZone_value1").disabled = !document.getElementById("System_TimeZone_value1").disabled' unchecked ></td>
|
||||
</td>
|
||||
<td>
|
||||
<class id="System_TimeZone_text" style="color:black;">TimeZone</class>
|
||||
@@ -570,18 +589,33 @@ textarea {
|
||||
</tr>
|
||||
<tr class="expert" id="ex16">
|
||||
<td width="20px" style="padding-left: 40px;">
|
||||
<input type="checkbox" id="System_TimeUpdateIntervall_enabled" value="1" onclick = 'document.getElementById("System_TimeUpdateIntervall_value1").disabled = !document.getElementById("System_TimeUpdateIntervall_value1").disabled' unchecked >
|
||||
</td>
|
||||
<td width="200px">
|
||||
<class id="System_TimeUpdateIntervall_text" style="color:black;">TimeUpdateIntervall</class>
|
||||
<td"><input type="checkbox" id="System_TimeServer_enabled" value="1" onclick = 'document.getElementById("System_TimeServer_value1").disabled = !document.getElementById("System_TimeServer_value1").disabled' unchecked ></td>
|
||||
</td>
|
||||
<td>
|
||||
<input type="number" id="System_TimeUpdateIntervall_value1" size="13" min="0" step="1">
|
||||
<class id="System_TimeServer_text" style="color:black;">TimeServer</class>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" id="System_TimeServer_value1">
|
||||
</td>
|
||||
<td style="font-size: 80%;">
|
||||
Intervall for synchronizing the time with the time server (in hours)
|
||||
Time server to synchronize system time (default: "pool.ntp.org" - used if nothing is specified)
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="expert" id="System_Hostname">
|
||||
<td width="20px" style="padding-left: 40px;">
|
||||
<td"><input type="checkbox" id="System_Hostname_enabled" value="1" onclick = 'document.getElementById("System_Hostname_value1").disabled = !document.getElementById("System_Hostname_value1").disabled' unchecked ></td>
|
||||
</td>
|
||||
<td>
|
||||
<class id="System_Hostname_text" style="color:black;">Hostname</class>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" id="System_Hostname_value1">
|
||||
</td>
|
||||
<td style="font-size: 80%;">
|
||||
Hostname for server - will be transfered to wlan.ini at next startup)
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
<p>
|
||||
@@ -597,12 +631,14 @@ textarea {
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" src="./gethost.js"></script>
|
||||
<script type="text/javascript" src="./readconfigcommon.js"></script>
|
||||
<script type="text/javascript" src="./readconfigparam.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
var canvas = document.getElementById('canvas'),
|
||||
basepath = "http://192.168.178.22";
|
||||
param;
|
||||
category;
|
||||
|
||||
|
||||
function LoadConfigNeu() {
|
||||
@@ -613,12 +649,14 @@ function LoadConfigNeu() {
|
||||
}
|
||||
loadConfig(basepath);
|
||||
ParseConfig();
|
||||
param = getConfigParameters();
|
||||
category = getConfigCategory();
|
||||
UpdateInput();
|
||||
UpdateExpertModus();
|
||||
document.getElementById("divall").style.display = '';
|
||||
}
|
||||
|
||||
function WriteParameter(_param, _cat, _name, _optional, _select = false, _anzpara = 1){
|
||||
function WriteParameter(_param, _category, _cat, _name, _optional, _select = false, _anzpara = 1){
|
||||
if (_param[_cat][_name]["found"]){
|
||||
if (_optional) {
|
||||
document.getElementById(_cat+"_"+_name+"_enabled").checked = _param[_cat][_name]["enabled"];
|
||||
@@ -654,6 +692,52 @@ function WriteParameter(_param, _cat, _name, _optional, _select = false, _anzpar
|
||||
document.getElementById(_cat+"_"+_name+"_text").style="color:lightgrey;"
|
||||
}
|
||||
|
||||
|
||||
///////////////// am Ende, falls Kategorie als gesamtes nicht ausgewählt --> deaktivieren
|
||||
if (_category[_cat]["enabled"] == false)
|
||||
{
|
||||
if (_optional) {
|
||||
document.getElementById(_cat+"_"+_name+"_enabled").disabled = true;
|
||||
for (var j = 1; j <= _anzpara; ++j) {
|
||||
document.getElementById(_cat+"_"+_name+"_value"+j).disabled = true;
|
||||
}
|
||||
}
|
||||
document.getElementById(_cat+"_"+_name+"_text").style="color:lightgrey;"
|
||||
}
|
||||
EnDisableItem(_category[_cat]["enabled"], _param, _category, _cat, _name, _optional);
|
||||
}
|
||||
|
||||
function EnDisableItem(_status, _param, _category, _cat, _name, _optional)
|
||||
{
|
||||
_status = _param[_cat][_name]["found"] && _category[_cat]["enabled"];
|
||||
|
||||
_color = "color:lightgrey;";
|
||||
if (_status) {
|
||||
_color = "color:black;";
|
||||
}
|
||||
|
||||
if (_optional) {
|
||||
document.getElementById(_cat+"_"+_name+"_enabled").disabled = !_status;
|
||||
document.getElementById(_cat+"_"+_name+"_enabled").style=_color;
|
||||
}
|
||||
|
||||
if (!_param[_cat][_name]["enabled"]) {
|
||||
_status = false;
|
||||
_color = "color:lightgrey;";
|
||||
}
|
||||
|
||||
document.getElementById(_cat+"_"+_name+"_text").disabled = !_status;
|
||||
document.getElementById(_cat+"_"+_name+"_text").style = _color;
|
||||
|
||||
if (_param[_cat][_name]["anzParam"] == 2) {
|
||||
_color = "width: 30px;" + _color;
|
||||
}
|
||||
|
||||
for (var j = 1; j <= _param[_cat][_name]["anzParam"]; ++j) {
|
||||
document.getElementById(_cat+"_"+_name+"_value"+j).disabled = !_status;
|
||||
document.getElementById(_cat+"_"+_name+"_value"+j).style=_color;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -667,7 +751,7 @@ function ReadParameter(_param, _cat, _name, _optional, _select = false){
|
||||
_param[_cat][_name]["value1"] = sel.options[sel.selectedIndex].text;
|
||||
}
|
||||
else {
|
||||
for (var j = 1; j <= _param[_cat][_name]["anzpara"]; ++j) {
|
||||
for (var j = 1; j <= _param[_cat][_name]["anzParam"]; ++j) {
|
||||
_param[_cat][_name]["value"+j] = document.getElementById(_cat+"_"+_name+"_value"+j).value;
|
||||
}
|
||||
}
|
||||
@@ -675,52 +759,63 @@ function ReadParameter(_param, _cat, _name, _optional, _select = false){
|
||||
}
|
||||
|
||||
function UpdateInput() {
|
||||
param = getConfigParameters();
|
||||
WriteParameter(param, "MakeImage", "LogImageLocation", true);
|
||||
WriteParameter(param, "MakeImage", "LogfileRetentionInDays", true);
|
||||
WriteParameter(param, "MakeImage", "WaitBeforeTakingPicture", false);
|
||||
WriteParameter(param, "MakeImage", "ImageQuality", false);
|
||||
WriteParameter(param, "MakeImage", "ImageSize", false, true, true);
|
||||
document.getElementById("Category_Analog_enabled").checked = category["Analog"]["enabled"];
|
||||
document.getElementById("Category_Digits_enabled").checked = category["Digits"]["enabled"];
|
||||
document.getElementById("Category_MQTT_enabled").checked = category["MQTT"]["enabled"];
|
||||
|
||||
WriteParameter(param, "Alignment", "SearchFieldX", false);
|
||||
WriteParameter(param, "Alignment", "SearchFieldY", false);
|
||||
WriteParameter(param, category, "MakeImage", "LogImageLocation", true);
|
||||
WriteParameter(param, category, "MakeImage", "LogfileRetentionInDays", true);
|
||||
WriteParameter(param, category, "MakeImage", "WaitBeforeTakingPicture", false);
|
||||
WriteParameter(param, category, "MakeImage", "ImageQuality", false);
|
||||
WriteParameter(param, category, "MakeImage", "ImageSize", false, true, true);
|
||||
|
||||
WriteParameter(param, "Digits", "Model", false);
|
||||
WriteParameter(param, "Digits", "LogImageLocation", false);
|
||||
WriteParameter(param, "Digits", "LogfileRetentionInDays", false);
|
||||
WriteParameter(param, "Digits", "ModelInputSize", false, false, 2);
|
||||
WriteParameter(param, category, "Alignment", "SearchFieldX", false);
|
||||
WriteParameter(param, category, "Alignment", "SearchFieldY", false);
|
||||
WriteParameter(param, category, "Alignment", "AlignmentAlgo", true, true, true);
|
||||
|
||||
WriteParameter(param, "Analog", "Model", false);
|
||||
WriteParameter(param, "Analog", "LogImageLocation", false);
|
||||
WriteParameter(param, "Analog", "LogfileRetentionInDays", false);
|
||||
WriteParameter(param, "Analog", "ModelInputSize", false, false, 2);
|
||||
WriteParameter(param, category, "Digits", "Model", false);
|
||||
WriteParameter(param, category, "Digits", "LogImageLocation", true);
|
||||
WriteParameter(param, category, "Digits", "LogfileRetentionInDays", true);
|
||||
WriteParameter(param, category, "Digits", "ModelInputSize", false, false, 2);
|
||||
|
||||
WriteParameter(param, "PostProcessing", "DecimalShift", true);
|
||||
WriteParameter(param, "PostProcessing", "PreValueUse", true, true);
|
||||
WriteParameter(param, "PostProcessing", "PreValueAgeStartup", true);
|
||||
WriteParameter(param, "PostProcessing", "AllowNegativeRates", true, true);
|
||||
WriteParameter(param, "PostProcessing", "MaxRateValue", true);
|
||||
WriteParameter(param, "PostProcessing", "ErrorMessage", true, true);
|
||||
WriteParameter(param, "PostProcessing", "CheckDigitIncreaseConsistency", true, true);
|
||||
WriteParameter(param, category, "Analog", "Model", false);
|
||||
WriteParameter(param, category, "Analog", "LogImageLocation", true);
|
||||
WriteParameter(param, category, "Analog", "LogfileRetentionInDays", true);
|
||||
WriteParameter(param, category, "Analog", "ExtendedResolution", true, true);
|
||||
WriteParameter(param, category, "Analog", "ModelInputSize", false, false, 2);
|
||||
|
||||
WriteParameter(param, "MQTT", "Uri", true);
|
||||
WriteParameter(param, "MQTT", "Topic", true);
|
||||
WriteParameter(param, "MQTT", "TopicError", true);
|
||||
WriteParameter(param, "MQTT", "ClientID", true);
|
||||
WriteParameter(param, "MQTT", "user", true);
|
||||
WriteParameter(param, "MQTT", "password", true);
|
||||
WriteParameter(param, category, "PostProcessing", "DecimalShift", true);
|
||||
WriteParameter(param, category, "PostProcessing", "PreValueUse", true, true);
|
||||
WriteParameter(param, category, "PostProcessing", "PreValueAgeStartup", true);
|
||||
WriteParameter(param, category, "PostProcessing", "AllowNegativeRates", true, true);
|
||||
WriteParameter(param, category, "PostProcessing", "MaxRateValue", true);
|
||||
WriteParameter(param, category, "PostProcessing", "ErrorMessage", true, true);
|
||||
WriteParameter(param, category, "PostProcessing", "CheckDigitIncreaseConsistency", true, true);
|
||||
|
||||
WriteParameter(param, "AutoTimer", "AutoStart", true, true);
|
||||
WriteParameter(param, "AutoTimer", "Intervall", true);
|
||||
WriteParameter(param, category, "MQTT", "Uri", true);
|
||||
WriteParameter(param, category, "MQTT", "Topic", true);
|
||||
WriteParameter(param, category, "MQTT", "TopicError", true);
|
||||
WriteParameter(param, category, "MQTT", "ClientID", true);
|
||||
WriteParameter(param, category, "MQTT", "user", true);
|
||||
WriteParameter(param, category, "MQTT", "password", true);
|
||||
|
||||
WriteParameter(param, "Debug", "Logfile", true, true);
|
||||
WriteParameter(param, "Debug", "LogfileRetentionInDays", true);
|
||||
WriteParameter(param, category, "AutoTimer", "AutoStart", true, true);
|
||||
WriteParameter(param, category, "AutoTimer", "Intervall", true);
|
||||
|
||||
WriteParameter(param, "System", "TimeZone", true);
|
||||
WriteParameter(param, "System", "TimeUpdateIntervall", true);
|
||||
WriteParameter(param, category, "Debug", "Logfile", true, true);
|
||||
WriteParameter(param, category, "Debug", "LogfileRetentionInDays", true);
|
||||
|
||||
WriteParameter(param, category, "System", "TimeZone", true);
|
||||
WriteParameter(param, category, "System", "Hostname", true);
|
||||
WriteParameter(param, category, "System", "TimeServer", true);
|
||||
}
|
||||
|
||||
function WriteConfig(){
|
||||
function ReadParameterAll()
|
||||
{
|
||||
category["Analog"]["enabled"] = document.getElementById("Category_Analog_enabled").checked;
|
||||
category["Digits"]["enabled"] = document.getElementById("Category_Digits_enabled").checked;
|
||||
category["MQTT"]["enabled"] = document.getElementById("Category_MQTT_enabled").checked;
|
||||
|
||||
ReadParameter(param, "MakeImage", "LogImageLocation", true);
|
||||
ReadParameter(param, "MakeImage", "LogfileRetentionInDays", true);
|
||||
ReadParameter(param, "MakeImage", "WaitBeforeTakingPicture", false);
|
||||
@@ -729,15 +824,17 @@ function WriteConfig(){
|
||||
|
||||
ReadParameter(param, "Alignment", "SearchFieldX", false);
|
||||
ReadParameter(param, "Alignment", "SearchFieldY", false);
|
||||
ReadParameter(param, "Alignment", "AlignmentAlgo", true, true);
|
||||
|
||||
ReadParameter(param, "Digits", "Model", false);
|
||||
ReadParameter(param, "Digits", "LogImageLocation", false);
|
||||
ReadParameter(param, "Digits", "LogfileRetentionInDays", false);
|
||||
ReadParameter(param, "Digits", "LogImageLocation", true);
|
||||
ReadParameter(param, "Digits", "LogfileRetentionInDays", true);
|
||||
ReadParameter(param, "Digits", "ModelInputSize", false, false, 2);
|
||||
|
||||
ReadParameter(param, "Analog", "Model", false);
|
||||
ReadParameter(param, "Analog", "LogImageLocation", false);
|
||||
ReadParameter(param, "Analog", "LogfileRetentionInDays", false);
|
||||
ReadParameter(param, "Analog", "LogImageLocation", true);
|
||||
ReadParameter(param, "Analog", "LogfileRetentionInDays", true);
|
||||
ReadParameter(param, "Analog", "ExtendedResolution", true, true);
|
||||
ReadParameter(param, "Analog", "ModelInputSize", false, false, 2);
|
||||
|
||||
ReadParameter(param, "PostProcessing", "DecimalShift", true);
|
||||
@@ -762,21 +859,32 @@ function WriteConfig(){
|
||||
ReadParameter(param, "Debug", "LogfileRetentionInDays", true);
|
||||
|
||||
ReadParameter(param, "System", "TimeZone", true);
|
||||
ReadParameter(param, "System", "TimeUpdateIntervall", true);
|
||||
ReadParameter(param, "System", "Hostname", true);
|
||||
ReadParameter(param, "System", "TimeServer", true);
|
||||
|
||||
FormatDecimalValue(param, "PostProcessing", "MaxRateValue");
|
||||
}
|
||||
|
||||
return setConfigParameters(param);
|
||||
function WriteConfig(){
|
||||
ReadParameterAll();
|
||||
return setConfigParameters(param, category);
|
||||
}
|
||||
|
||||
function FormatDecimalValue(_param, _cat, _name) {
|
||||
for (var j = 1; j <= _param[_cat][_name]["anzpara"]; ++j) {
|
||||
for (var j = 1; j <= _param[_cat][_name]["anzParam"]; ++j) {
|
||||
var _val = _param[_cat][_name]["value"+j];
|
||||
_val = _val.replace(",", ".");
|
||||
_param[_cat][_name]["value"+j] = _val;
|
||||
}
|
||||
}
|
||||
|
||||
function UpdateAfterCategoryCheck() {
|
||||
ReadParameterAll();
|
||||
category["Analog"]["enabled"] = document.getElementById("Category_Analog_enabled").checked;
|
||||
category["Digits"]["enabled"] = document.getElementById("Category_Digits_enabled").checked;
|
||||
UpdateInput();
|
||||
}
|
||||
|
||||
function UpdateExpertModus()
|
||||
{
|
||||
var _style = 'display:none;';
|
||||
|
||||
@@ -55,7 +55,10 @@ th, td {
|
||||
|
||||
<body style="font-family: arial; padding: 0px 10px;">
|
||||
|
||||
<h2>Edit Digits</h2>
|
||||
<h2><input type="checkbox" id="Category_Digits_enabled" value="1" onclick = 'EnDisableDigits()' checked >
|
||||
Edit Digits</h2>
|
||||
|
||||
<div id="div1">
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
@@ -91,7 +94,9 @@ th, td {
|
||||
<td>y: <input type="number" name="refy" id="refy" step=1 onchange="valuemanualchanged()"></td>
|
||||
<td>dy: <input type="number" name="refdy" id="refdy" step=1 onchange="valuemanualchanged()"></td>
|
||||
</tr>
|
||||
</table>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
@@ -101,6 +106,8 @@ th, td {
|
||||
|
||||
<script type="text/javascript" src="./gethost.js"></script>
|
||||
<script type="text/javascript" src="./readconfig.js"></script>
|
||||
<script type="text/javascript" src="./readconfigcommon.js"></script>
|
||||
<script type="text/javascript" src="./jquery-3.5.1.min.js"></script>
|
||||
|
||||
<script language="JavaScript">
|
||||
var canvas = document.getElementById('canvas'),
|
||||
@@ -114,6 +121,41 @@ th, td {
|
||||
lockAR = true;
|
||||
basepath = "http://192.168.178.26";
|
||||
|
||||
|
||||
function EnDisableDigits() {
|
||||
isEnabled = document.getElementById("Category_Digits_enabled").checked;
|
||||
|
||||
$("#div2").attr("disabled", "disabled").off('click');
|
||||
var x1=$("#div2").hasClass("disabledDiv");
|
||||
|
||||
if (isEnabled)
|
||||
{
|
||||
$("#div2").removeClass("disabledDiv");
|
||||
}
|
||||
else
|
||||
{
|
||||
$("#div2").addClass("disabledDiv");
|
||||
}
|
||||
|
||||
sah1(document.getElementById("div1"), !isEnabled);
|
||||
if (isEnabled)
|
||||
{
|
||||
UpdateROIs();
|
||||
}
|
||||
}
|
||||
|
||||
function sah1(el, _target) {
|
||||
try {
|
||||
el.disabled = _target;
|
||||
} catch (E) {}
|
||||
if (el.childNodes && el.childNodes.length > 0) {
|
||||
for (var x = 0; x < el.childNodes.length; x++) {
|
||||
sah1(el.childNodes[x], _target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function onNameChange(){
|
||||
ROIInfo[aktindex]["name"] = document.getElementById("name").value;
|
||||
UpdateROIs();
|
||||
@@ -172,7 +214,8 @@ function ChangeSelection(){
|
||||
}
|
||||
|
||||
function SaveToConfig(){
|
||||
SaveROIToConfig(ROIInfo, "[Digits]", basepath);
|
||||
_enabled = document.getElementById("Category_Digits_enabled").checked;
|
||||
SaveROIToConfig(ROIInfo, "[Digits]", basepath, _enabled);
|
||||
UpdatePage();
|
||||
}
|
||||
|
||||
@@ -230,8 +273,19 @@ function UpdateROIs(){
|
||||
function ParseIni(_basepath) {
|
||||
loadConfig(_basepath);
|
||||
ParseConfig();
|
||||
|
||||
document.getElementById("Category_Digits_enabled").checked = true;
|
||||
ROIInfo = getROIInfo("[Digits]");
|
||||
|
||||
if (!GetDigitsEnabled())
|
||||
{
|
||||
document.getElementById("Category_Digits_enabled").checked = false;
|
||||
EnDisableDigits();
|
||||
alert("Digital ROIs are disabled - please enable (Check box top left).\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
UpdateROIs();
|
||||
}
|
||||
|
||||
@@ -287,22 +341,25 @@ function ParseIni(_basepath) {
|
||||
}
|
||||
|
||||
|
||||
function draw() {
|
||||
function draw() {
|
||||
var canvas = document.getElementById('canvas');
|
||||
var context = canvas.getContext('2d');
|
||||
context.drawImage(imageObj, 0, 0);
|
||||
lw = 4
|
||||
context.lineWidth = lw;
|
||||
context.strokeStyle = "#FF0000";
|
||||
var x0 = parseInt(rect.startX) - parseInt(lw/2);
|
||||
var y0 = parseInt(rect.startY) - parseInt(lw/2);
|
||||
var dx = parseInt(rect.w) + parseInt(lw);
|
||||
var dy = parseInt(rect.h) + parseInt(lw);
|
||||
context.strokeRect(x0, y0, dx, dy);
|
||||
ROIInfo[aktindex]["x"] = rect.startX;
|
||||
ROIInfo[aktindex]["y"] = rect.startY;
|
||||
ROIInfo[aktindex]["dx"] = rect.w;
|
||||
ROIInfo[aktindex]["dy"] = rect.h;
|
||||
if (document.getElementById("Category_Digits_enabled").checked)
|
||||
{
|
||||
lw = 4
|
||||
context.lineWidth = lw;
|
||||
context.strokeStyle = "#FF0000";
|
||||
var x0 = parseInt(rect.startX) - parseInt(lw/2);
|
||||
var y0 = parseInt(rect.startY) - parseInt(lw/2);
|
||||
var dx = parseInt(rect.w) + parseInt(lw);
|
||||
var dy = parseInt(rect.h) + parseInt(lw);
|
||||
context.strokeRect(x0, y0, dx, dy);
|
||||
ROIInfo[aktindex]["x"] = rect.startX;
|
||||
ROIInfo[aktindex]["y"] = rect.startY;
|
||||
ROIInfo[aktindex]["dx"] = rect.w;
|
||||
ROIInfo[aktindex]["dy"] = rect.h;
|
||||
}
|
||||
}
|
||||
|
||||
function getCoords(elem) { // crossbrowser version
|
||||
|
||||
66
sd-card/html/edit_explain_0.html
Normal file
66
sd-card/html/edit_explain_0.html
Normal file
@@ -0,0 +1,66 @@
|
||||
<!DOCTYPE html>
|
||||
<html style="width: fit-content">
|
||||
<head>
|
||||
<title>jomjol - AI on the edge</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<style>
|
||||
.h_iframe iframe {width:995px;height:605px;}
|
||||
.h_iframe {width:995px;height:605px;}
|
||||
|
||||
h1 {font-size: 2em; margin-block-end: 0.3em;}
|
||||
h2 {font-size: 1.5em;margin-block-start: 0.3em;}
|
||||
h3 {font-size: 1.2em;}
|
||||
p {font-size: 1em;}
|
||||
|
||||
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body style="font-family: arial">
|
||||
|
||||
<h2>Welcome to the Setup of the Digitizer</h2>
|
||||
|
||||
|
||||
<p>
|
||||
<img src="flow_overview.jpg" alt=""><img src="cnn_images.jpg" alt="">
|
||||
</p>
|
||||
|
||||
<p>
|
||||
This is the first time you the digitizer. You have been automatically routed to the <b>initial setup procedure</b>.
|
||||
This procedure should adjust the setting to your local counter. Basically you can customize your settings in five steps.
|
||||
<br>
|
||||
In the final step the inital setup will be disabled and it will restart to the normal mode.
|
||||
<br>
|
||||
<br>
|
||||
Just use the buttons "Next" and "Previous" to nagivate through the process.
|
||||
<br>
|
||||
</p>
|
||||
<p>
|
||||
Follow the instructions:
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<ol>
|
||||
<li>Create reference image <br>
|
||||
Basis for the position references and the marking of the digits and counters.</li>
|
||||
<li>Define two unique references <br>
|
||||
Used to align the individual camera shot and identify the absolut positions</li>
|
||||
<li>Define the digits <br>
|
||||
Digital digits to be recognized</li>
|
||||
<li>Define the analog counters <br>
|
||||
Analog counters to be identified</li>
|
||||
<li>General settings <br>
|
||||
Most can stay to the default value - also MQTT connection can be specified here</li>
|
||||
</ol>
|
||||
<p>
|
||||
|
||||
After step 5 you switch of the setup mode, reboot and start in normal mode!
|
||||
|
||||
<h4>Have fun with the digitizer!</h4>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
82
sd-card/html/edit_explain_6.html
Normal file
82
sd-card/html/edit_explain_6.html
Normal file
@@ -0,0 +1,82 @@
|
||||
<!DOCTYPE html>
|
||||
<html style="width: fit-content">
|
||||
<head>
|
||||
<title>jomjol - AI on the edge</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<style>
|
||||
.h_iframe iframe {width:995px;height:605px;}
|
||||
.h_iframe {width:995px;height:605px;}
|
||||
|
||||
h1 {font-size: 2em; margin-block-end: 0.3em;}
|
||||
h2 {font-size: 1.5em;margin-block-start: 0.3em;}
|
||||
h3 {font-size: 1.2em;}
|
||||
p {font-size: 1em;}
|
||||
|
||||
|
||||
.button {
|
||||
padding: 5px 20px;
|
||||
width: 211px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body style="font-family: arial">
|
||||
|
||||
<h4>Finished!</h4>
|
||||
|
||||
<p>
|
||||
Now you are finished with the setup and ready to reboot to the normal mode.
|
||||
<br>
|
||||
Once you have pushed below button, the setup modus will be left and the digitizer start to normal operation mode.
|
||||
<br>
|
||||
After a view seconds you can reload this page again and will go to normal operation mode.
|
||||
<br>
|
||||
All settings can be changed later on as well in the configuration menue.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<button class="button" onclick="reboot()">Leave Setup Modus and Reboot to Normal</button>
|
||||
</p>
|
||||
|
||||
<script type="text/javascript" src="./gethost.js"></script>
|
||||
<script type="text/javascript" src="./readconfigparam.js"></script>
|
||||
<script type="text/javascript" src="./readconfigcommon.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
var canvas = document.getElementById('canvas'),
|
||||
basepath = "http://192.168.178.22";
|
||||
aktstatu = 0;
|
||||
|
||||
function reboot() {
|
||||
if (confirm("Do you want to leave the configuration mode and restart the ESP32?\n\nPlease reload the page in about 30s.")) {
|
||||
basepath = getbasepath();
|
||||
if (!loadConfig(basepath)) {
|
||||
alert("Setup Modus could not be deactivated!\Please retry.");
|
||||
return;
|
||||
}
|
||||
ParseConfig();
|
||||
param = getConfigParameters();
|
||||
param["System"]["SetupMode"]["enabled"] = false;
|
||||
param["System"]["SetupMode"]["value1"] = "false";
|
||||
setConfigParameters(param);
|
||||
var textToSave = setConfigParameters(param);
|
||||
FileDeleteOnServer("/config/config.ini", basepath);
|
||||
FileSendContent(textToSave, "/config/config.ini", basepath);
|
||||
|
||||
var stringota = "/reboot";
|
||||
window.location = stringota;
|
||||
window.location.href = stringota;
|
||||
window.location.assign(stringota);
|
||||
window.location.replace(stringota);
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -39,7 +39,7 @@ table {
|
||||
<tr>
|
||||
<td><input class="button" type="button" value="Show Actual Reference" onclick="showReference()"></td>
|
||||
<td><input class="button" type="button" value="Create New Reference" onclick="loadRawImage()"></td>
|
||||
<td><input class="button" type="submit" id="take" onclick="doTake()" value="New Raw Image (raw.jpg)"></td>
|
||||
<td><input class="button" type="submit" id="take" onclick="doTake()" value="Take Image"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding-top: 10px"><label for="mirror">Mirror Image:</label></td>
|
||||
@@ -67,6 +67,7 @@ table {
|
||||
|
||||
<script type="text/javascript" src="./gethost.js"></script>
|
||||
<script type="text/javascript" src="./readconfig.js"></script>
|
||||
<script type="text/javascript" src="./readconfigcommon.js"></script>
|
||||
|
||||
<script language="JavaScript">
|
||||
var canvas = document.getElementById('canvas'),
|
||||
@@ -87,7 +88,7 @@ table {
|
||||
}
|
||||
|
||||
function loadRawImage(){
|
||||
url = basepath + "/fileserver/img_tmp/raw.jpg" + "?session=" + Math.floor((Math.random() * 1000000) + 1);
|
||||
url = basepath + "/img_tmp/raw.jpg" + "?session=" + Math.floor((Math.random() * 1000000) + 1);
|
||||
document.getElementById("finerotate").value = 0;
|
||||
document.getElementById("prerotateangle").value = getPreRotate();
|
||||
document.getElementById("mirror").checked = getMirror();
|
||||
|
||||
29
sd-card/html/explain_0.html
Normal file
29
sd-card/html/explain_0.html
Normal file
@@ -0,0 +1,29 @@
|
||||
<!DOCTYPE html>
|
||||
<html style="width: fit-content">
|
||||
<head>
|
||||
<title>jomjol - AI on the edge</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<style>
|
||||
.h_iframe iframe {width:995px;height:605px;}
|
||||
.h_iframe {width:995px;height:605px;}
|
||||
|
||||
h1 {font-size: 2em; margin-block-end: 0.3em;}
|
||||
h2 {font-size: 1.5em;margin-block-start: 0.3em;}
|
||||
h3 {font-size: 1.2em;}
|
||||
p {font-size: 1em;}
|
||||
|
||||
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body style="font-family: arial">
|
||||
|
||||
<h4>Introduction</h4>
|
||||
<p>
|
||||
Read below!
|
||||
|
||||
</body>
|
||||
</html>
|
||||
33
sd-card/html/explain_1.html
Normal file
33
sd-card/html/explain_1.html
Normal file
@@ -0,0 +1,33 @@
|
||||
<!DOCTYPE html>
|
||||
<html style="width: fit-content">
|
||||
<head>
|
||||
<title>jomjol - AI on the edge</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<style>
|
||||
.h_iframe iframe {width:995px;height:605px;}
|
||||
.h_iframe {width:995px;height:605px;}
|
||||
|
||||
h1 {font-size: 2em; margin-block-end: 0.3em;}
|
||||
h2 {font-size: 1.5em;margin-block-start: 0.3em;}
|
||||
h3 {font-size: 1.2em;}
|
||||
p {font-size: 1em;}
|
||||
|
||||
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body style="font-family: arial">
|
||||
|
||||
<h4>Reference Image</h4>
|
||||
The reference image is needed to define the digits, counters and references for alignment.
|
||||
<p>
|
||||
The last taken raw image from the camera is taken. Use the Button "Create New Reference" to make your own reference.<br>
|
||||
Most important feature is a straight alignment of the image. Use the Pre roate Angle and the fine alignment to fine tune the rotation of the image<br>
|
||||
Finish the step by pushing <b>"Update Reference Image"</b>.
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
36
sd-card/html/explain_2.html
Normal file
36
sd-card/html/explain_2.html
Normal file
@@ -0,0 +1,36 @@
|
||||
<!DOCTYPE html>
|
||||
<html style="width: fit-content">
|
||||
<head>
|
||||
<title>jomjol - AI on the edge</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<style>
|
||||
.h_iframe iframe {width:995px;height:605px;}
|
||||
.h_iframe {width:995px;height:605px;}
|
||||
|
||||
h1 {font-size: 2em; margin-block-end: 0.3em;}
|
||||
h2 {font-size: 1.5em;margin-block-start: 0.3em;}
|
||||
h3 {font-size: 1.2em;}
|
||||
p {font-size: 1em;}
|
||||
|
||||
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body style="font-family: arial">
|
||||
|
||||
<h4>Alignment References</h4>
|
||||
Two opposite alignment references are needed to identify unique fix points on the image.
|
||||
<p>
|
||||
Mark the reference by drag and dop with the mouse or with the coordinates and push <b>"Update Reference"</b>.
|
||||
<br>
|
||||
You can switch between the two reference with <b>"Select Reference"</b>.
|
||||
</p>
|
||||
<p>
|
||||
Don't forget to save your changes with <b>"Save to Config.ini"</b>!.
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
37
sd-card/html/explain_3.html
Normal file
37
sd-card/html/explain_3.html
Normal file
@@ -0,0 +1,37 @@
|
||||
<!DOCTYPE html>
|
||||
<html style="width: fit-content">
|
||||
<head>
|
||||
<title>jomjol - AI on the edge</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<style>
|
||||
.h_iframe iframe {width:995px;height:605px;}
|
||||
.h_iframe {width:995px;height:605px;}
|
||||
|
||||
h1 {font-size: 2em; margin-block-end: 0.3em;}
|
||||
h2 {font-size: 1.5em;margin-block-start: 0.3em;}
|
||||
h3 {font-size: 1.2em;}
|
||||
p {font-size: 1em;}
|
||||
|
||||
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body style="font-family: arial">
|
||||
|
||||
<h4>Define Digits</h4>
|
||||
Here you define your digits you want to read.
|
||||
<p>
|
||||
With the drop down menue <b>"ROI x"</b> you can change between the different digits. Mark them with the mouse or the coordinates.
|
||||
<br>
|
||||
To create new ROIs use <b>"New ROIs"</b>. The order of the ROIs defines the positon within the reading. <br>
|
||||
You can change it with <b>"move Next" / "move Previous"</b>.
|
||||
</p>
|
||||
<p>
|
||||
Don't forget to save your changes with <b>"Save all to Config.ini"</b>!.
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
37
sd-card/html/explain_4.html
Normal file
37
sd-card/html/explain_4.html
Normal file
@@ -0,0 +1,37 @@
|
||||
<!DOCTYPE html>
|
||||
<html style="width: fit-content">
|
||||
<head>
|
||||
<title>jomjol - AI on the edge</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<style>
|
||||
.h_iframe iframe {width:995px;height:605px;}
|
||||
.h_iframe {width:995px;height:605px;}
|
||||
|
||||
h1 {font-size: 2em; margin-block-end: 0.3em;}
|
||||
h2 {font-size: 1.5em;margin-block-start: 0.3em;}
|
||||
h3 {font-size: 1.2em;}
|
||||
p {font-size: 1em;}
|
||||
|
||||
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body style="font-family: arial">
|
||||
|
||||
<h4>Define Digits</h4>
|
||||
Here you define your analog counters you want to read. If you do not have analog counters delete all ROIs.
|
||||
<p>
|
||||
With the drop down menue <b>"ROI x"</b> you can change between the different counters. Mark them with the mouse or the coordinates.
|
||||
<br>
|
||||
To create new ROIs use <b>"New ROIs"</b>. The order of the ROIs defines the positon within the reading. <br>
|
||||
You can change it with <b>"move Next" / "move Previous"</b>.
|
||||
</p>
|
||||
<p>
|
||||
Don't forget to save your changes with <b>"Save all to Config.ini"</b>!.
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
35
sd-card/html/explain_5.html
Normal file
35
sd-card/html/explain_5.html
Normal file
@@ -0,0 +1,35 @@
|
||||
<!DOCTYPE html>
|
||||
<html style="width: fit-content">
|
||||
<head>
|
||||
<title>jomjol - AI on the edge</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<style>
|
||||
.h_iframe iframe {width:995px;height:605px;}
|
||||
.h_iframe {width:995px;height:605px;}
|
||||
|
||||
h1 {font-size: 2em; margin-block-end: 0.3em;}
|
||||
h2 {font-size: 1.5em;margin-block-start: 0.3em;}
|
||||
h3 {font-size: 1.2em;}
|
||||
p {font-size: 1em;}
|
||||
|
||||
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body style="font-family: arial">
|
||||
|
||||
<h4>General configuration parameters</h4>
|
||||
Here you define additional setting. The settings should fit for a normal setup. </p>
|
||||
<p>
|
||||
Only if you want to connect to a MQTT-broker you need to adjust the corresponding parameters.
|
||||
</p>
|
||||
<p>
|
||||
Don't forget to save your changes with <b>"Update Config.ini"</b>!.
|
||||
<br>You should not reboot here, but leave the setup modus on the next page.
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
27
sd-card/html/explain_6.html
Normal file
27
sd-card/html/explain_6.html
Normal file
@@ -0,0 +1,27 @@
|
||||
<!DOCTYPE html>
|
||||
<html style="width: fit-content">
|
||||
<head>
|
||||
<title>jomjol - AI on the edge</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<style>
|
||||
.h_iframe iframe {width:995px;height:605px;}
|
||||
.h_iframe {width:995px;height:605px;}
|
||||
|
||||
h1 {font-size: 2em; margin-block-end: 0.3em;}
|
||||
h2 {font-size: 1.5em;margin-block-start: 0.3em;}
|
||||
h3 {font-size: 1.2em;}
|
||||
p {font-size: 1em;}
|
||||
|
||||
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body style="font-family: arial">
|
||||
|
||||
<h4>Finished!</h4>
|
||||
Read below!
|
||||
</body>
|
||||
</html>
|
||||
BIN
sd-card/html/flow_overview.jpg
Normal file
BIN
sd-card/html/flow_overview.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 57 KiB |
@@ -7,9 +7,11 @@ function getbasepath(){
|
||||
var host = window.location.hostname;
|
||||
if ((host == "127.0.0.1") || (host == "localhost"))
|
||||
{
|
||||
// host = "http://192.168.178.26"; // jomjol interner test
|
||||
host = "http://192.168.178.22"; // jomjol interner Real
|
||||
// host = "http://192.168.2.118"; // jomjol interner test
|
||||
host = "http://192.168.178.26"; // jomjol interner test
|
||||
// host = "http://192.168.178.22"; // jomjol interner Real
|
||||
// host = "."; // jomjol interner localhost
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -97,6 +97,7 @@ li.dropdown {
|
||||
</div>
|
||||
</ul>
|
||||
<p>
|
||||
|
||||
<div class="h_iframe">
|
||||
<iframe name="maincontent" id ="maincontent" src="/wasserzaehler_roi.html" title="fileserver" allowfullscreen></iframe>
|
||||
</div>
|
||||
|
||||
@@ -8,6 +8,10 @@ var ref = new Array(2);
|
||||
var digit = new Array(0);
|
||||
var analog = new Array(0);
|
||||
var initalrotate = new Object();
|
||||
var analogEnabled = false;
|
||||
var posAnalogHeader;
|
||||
var digitsEnabled = false;
|
||||
var posDigitsHeader;
|
||||
|
||||
function MakeRefZW(zw, _basepath){
|
||||
url = _basepath + "/editflow.html?task=cutref&in=/config/reference.jpg&out=/img_tmp/ref_zw_org.jpg&x=" + zw["x"] + "&y=" + zw["y"] + "&dx=" + zw["dx"] + "&dy=" + zw["dy"];
|
||||
@@ -36,7 +40,9 @@ function ParseConfigAlignment(_aktline){
|
||||
var akt_ref = 0;
|
||||
++_aktline;
|
||||
|
||||
while ((akt_ref < 2) && (_aktline < config_split.length) && (config_split[_aktline][0] != "[")) {
|
||||
while ((_aktline < config_split.length)
|
||||
&& !(config_split[_aktline][0] == "[")
|
||||
&& !((config_split[_aktline][0] == ";") && (config_split[_aktline][1] == "["))) {
|
||||
var linesplit = ZerlegeZeile(config_split[_aktline]);
|
||||
if ((linesplit[0].toUpperCase() == "INITIALMIRROR") && (linesplit.length > 1))
|
||||
{
|
||||
@@ -67,7 +73,9 @@ function ParseConfigDigit(_aktline){
|
||||
++_aktline;
|
||||
digit.length = 0;
|
||||
|
||||
while ((_aktline < config_split.length) && (config_split[_aktline][0] != "[")) {
|
||||
while ((_aktline < config_split.length)
|
||||
&& !(config_split[_aktline][0] == "[")
|
||||
&& !((config_split[_aktline][0] == ";") && (config_split[_aktline][1] == "["))) {
|
||||
var linesplit = ZerlegeZeile(config_split[_aktline]);
|
||||
if (linesplit.length >= 5)
|
||||
{
|
||||
@@ -86,12 +94,23 @@ function ParseConfigDigit(_aktline){
|
||||
return _aktline;
|
||||
}
|
||||
|
||||
function GetAnalogEnabled() {
|
||||
return analogEnabled;
|
||||
}
|
||||
|
||||
|
||||
function GetDigitsEnabled() {
|
||||
return digitsEnabled;
|
||||
}
|
||||
|
||||
|
||||
function ParseConfigAnalog(_aktline){
|
||||
++_aktline;
|
||||
analog.length = 0;
|
||||
|
||||
while ((_aktline < config_split.length) && (config_split[_aktline][0] != "[")) {
|
||||
while ((_aktline < config_split.length)
|
||||
&& !(config_split[_aktline][0] == "[")
|
||||
&& !((config_split[_aktline][0] == ";") && (config_split[_aktline][1] == "["))) {
|
||||
var linesplit = ZerlegeZeile(config_split[_aktline]);
|
||||
if (linesplit.length >= 5)
|
||||
{
|
||||
@@ -121,11 +140,21 @@ function getROIInfo(_typeROI){
|
||||
return targetROI.slice(); // Kopie senden, nicht orginal!!!
|
||||
}
|
||||
|
||||
function SaveROIToConfig(_ROIInfo, _typeROI, _basepath){
|
||||
function SaveROIToConfig(_ROIInfo, _typeROI, _basepath, _enabled){
|
||||
if (_enabled) {
|
||||
text = _typeROI;
|
||||
}
|
||||
else {
|
||||
text = ";" + _typeROI;
|
||||
}
|
||||
|
||||
if (_typeROI == "[Digits]"){
|
||||
config_split[posDigitsHeader] = text;
|
||||
targetROI = digit;
|
||||
}
|
||||
|
||||
if (_typeROI == "[Analog]"){
|
||||
config_split[posAnalogHeader] = text;
|
||||
targetROI = analog;
|
||||
}
|
||||
|
||||
@@ -165,16 +194,24 @@ function ParseConfig() {
|
||||
var aktline = 0;
|
||||
|
||||
while (aktline < config_split.length){
|
||||
if (config_split[aktline].trim().toUpperCase() == "[ALIGNMENT]") {
|
||||
if ((config_split[aktline].trim().toUpperCase() == "[ALIGNMENT]") || (config_split[aktline].trim().toUpperCase() == ";[ALIGNMENT]")){
|
||||
aktline = ParseConfigAlignment(aktline);
|
||||
continue;
|
||||
}
|
||||
if (config_split[aktline].trim().toUpperCase() == "[DIGITS]") {
|
||||
if ((config_split[aktline].trim().toUpperCase() == "[DIGITS]") || (config_split[aktline].trim().toUpperCase() == ";[DIGITS]")){
|
||||
posDigitsHeader = aktline;
|
||||
if (config_split[aktline][0] == "[") {
|
||||
digitsEnabled = true;
|
||||
}
|
||||
aktline = ParseConfigDigit(aktline);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (config_split[aktline].trim().toUpperCase() == "[ANALOG]") {
|
||||
if ((config_split[aktline].trim().toUpperCase() == "[ANALOG]") || (config_split[aktline].trim().toUpperCase() == ";[ANALOG]")) {
|
||||
posAnalogHeader = aktline;
|
||||
if (config_split[aktline][0] == "[") {
|
||||
analogEnabled = true;
|
||||
}
|
||||
aktline = ParseConfigAnalog(aktline);
|
||||
continue;
|
||||
}
|
||||
@@ -313,19 +350,6 @@ function MakeContrastImageZW(zw, _enhance, _basepath){
|
||||
}
|
||||
}
|
||||
|
||||
function createReader(file) {
|
||||
var image = new Image();
|
||||
reader.onload = function(evt) {
|
||||
var image = new Image();
|
||||
image.onload = function(evt) {
|
||||
var width = this.width;
|
||||
var height = this.height;
|
||||
alert (width); // will produce something like 198
|
||||
};
|
||||
image.src = evt.target.result;
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
|
||||
function GetReferenceSize(name){
|
||||
img = new Image();
|
||||
@@ -347,83 +371,6 @@ function GetReferenceSize(name){
|
||||
}
|
||||
|
||||
|
||||
function ZerlegeZeile(input)
|
||||
{
|
||||
var Output = Array(0);
|
||||
delimiter = " =,";
|
||||
|
||||
input = trim(input, delimiter);
|
||||
var pos = findDelimiterPos(input, delimiter);
|
||||
var token;
|
||||
while (pos > -1) {
|
||||
token = input.substr(0, pos);
|
||||
token = trim(token, delimiter);
|
||||
Output.push(token);
|
||||
input = input.substr(pos+1, input.length);
|
||||
input = trim(input, delimiter);
|
||||
pos = findDelimiterPos(input, delimiter);
|
||||
}
|
||||
Output.push(input);
|
||||
|
||||
return Output;
|
||||
|
||||
}
|
||||
|
||||
function findDelimiterPos(input, delimiter)
|
||||
{
|
||||
var pos = -1;
|
||||
var zw;
|
||||
var akt_del;
|
||||
|
||||
for (var anz = 0; anz < delimiter.length; ++anz)
|
||||
{
|
||||
akt_del = delimiter[anz];
|
||||
zw = input.indexOf(akt_del);
|
||||
if (zw > -1)
|
||||
{
|
||||
if (pos > -1)
|
||||
{
|
||||
if (zw < pos)
|
||||
pos = zw;
|
||||
}
|
||||
else
|
||||
pos = zw;
|
||||
}
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
||||
|
||||
function trim(istring, adddelimiter)
|
||||
{
|
||||
while ((istring.length > 0) && (adddelimiter.indexOf(istring[0]) >= 0)){
|
||||
istring = istring.substr(1, istring.length-1);
|
||||
}
|
||||
|
||||
while ((istring.length > 0) && (adddelimiter.indexOf(istring[istring.length-1]) >= 0)){
|
||||
istring = istring.substr(0, istring.length-1);
|
||||
}
|
||||
|
||||
return istring;
|
||||
}
|
||||
|
||||
|
||||
|
||||
function loadConfig(_basepath) {
|
||||
var xhttp = new XMLHttpRequest();
|
||||
try {
|
||||
url = _basepath + '/fileserver/config/config.ini';
|
||||
xhttp.open("GET", url, false);
|
||||
xhttp.send();
|
||||
config_gesamt = xhttp.responseText;
|
||||
}
|
||||
catch (error)
|
||||
{
|
||||
// alert("Deleting Config.ini failed");
|
||||
}
|
||||
}
|
||||
|
||||
function getConfig() {
|
||||
return config_gesamt;
|
||||
}
|
||||
@@ -439,75 +386,6 @@ function dataURLtoBlob(dataurl) {
|
||||
return new Blob([u8arr], {type:mime});
|
||||
}
|
||||
|
||||
function FileCopyOnServer(_source, _target, _basepath = ""){
|
||||
url = _basepath + "/editflow.html?task=copy&in=" + _source + "&out=" + _target;
|
||||
var xhttp = new XMLHttpRequest();
|
||||
try {
|
||||
xhttp.open("GET", url, false);
|
||||
xhttp.send(); }
|
||||
catch (error)
|
||||
{
|
||||
// alert("Deleting Config.ini failed");
|
||||
}
|
||||
}
|
||||
|
||||
function FileDeleteOnServer(_filename, _basepath = ""){
|
||||
var xhttp = new XMLHttpRequest();
|
||||
var okay = false;
|
||||
|
||||
xhttp.onreadystatechange = function() {
|
||||
if (xhttp.readyState == 4) {
|
||||
if (xhttp.status == 200) {
|
||||
okay = true;
|
||||
} else if (xhttp.status == 0) {
|
||||
// alert("Server closed the connection on delete abruptly!");
|
||||
// location.reload()
|
||||
} else {
|
||||
// alert(xhttp.status + " Error!\n" + xhttp.responseText);
|
||||
// location.reload()
|
||||
}
|
||||
}
|
||||
};
|
||||
try {
|
||||
var url = _basepath + "/delete" + _filename;
|
||||
xhttp.open("POST", url, false);
|
||||
xhttp.send();
|
||||
}
|
||||
catch (error)
|
||||
{
|
||||
// alert("Deleting Config.ini failed");
|
||||
}
|
||||
|
||||
return okay;
|
||||
}
|
||||
|
||||
function FileSendContent(_content, _filename, _basepath = ""){
|
||||
var xhttp = new XMLHttpRequest();
|
||||
var okay = false;
|
||||
|
||||
xhttp.onreadystatechange = function() {
|
||||
if (xhttp.readyState == 4) {
|
||||
if (xhttp.status == 200) {
|
||||
okay = true;
|
||||
} else if (xhttp.status == 0) {
|
||||
alert("Server closed the connection abruptly!");
|
||||
} else {
|
||||
alert(xhttp.status + " Error!\n" + xhttp.responseText);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
upload_path = _basepath + "/upload" + _filename;
|
||||
xhttp.open("POST", upload_path, false);
|
||||
xhttp.send(_content);
|
||||
}
|
||||
catch (error)
|
||||
{
|
||||
// alert("Deleting Config.ini failed");
|
||||
}
|
||||
return okay;
|
||||
}
|
||||
|
||||
function SaveReferenceImage(_id_canvas, _filename, _doDelete, _basepath = ""){
|
||||
if (_doDelete){
|
||||
|
||||
263
sd-card/html/readconfigcommon.js
Normal file
263
sd-card/html/readconfigcommon.js
Normal file
@@ -0,0 +1,263 @@
|
||||
function readconfig_Version(){
|
||||
return "1.0.0 - 20200910";
|
||||
}
|
||||
|
||||
function SaveConfigToServer(_basepath){
|
||||
// leere Zeilen am Ende löschen
|
||||
var zw = config_split.length - 1;
|
||||
while (config_split[zw] == "") {
|
||||
config_split.pop();
|
||||
}
|
||||
|
||||
var config_gesamt = "";
|
||||
for (var i = 0; i < config_split.length; ++i)
|
||||
{
|
||||
config_gesamt = config_gesamt + config_split[i] + "\n";
|
||||
}
|
||||
|
||||
FileDeleteOnServer("/config/config.ini", _basepath);
|
||||
|
||||
FileSendContent(config_gesamt, "/config/config.ini", _basepath);
|
||||
}
|
||||
|
||||
function UpdateConfigFileReferenceChange(_basepath){
|
||||
for (var _index = 0; _index < ref.length; ++_index){
|
||||
var zeile = ref[_index]["name"] + " " + ref[_index]["x"] + " " + ref[_index]["y"];
|
||||
var _pos = ref[_index]["pos_ref"];
|
||||
config_split[_pos] = zeile;
|
||||
}
|
||||
|
||||
zeile = "InitialRotate = " + initalrotate["angle"];
|
||||
var _pos = initalrotate["pos_config"];
|
||||
config_split[_pos] = zeile;
|
||||
|
||||
var mirror = false;
|
||||
if (initalrotate.hasOwnProperty("mirror")) {
|
||||
mirror = initalrotate["mirror"];
|
||||
}
|
||||
var mirror_pos = -1;
|
||||
if (initalrotate.hasOwnProperty("pos_config_mirror")) {
|
||||
mirror_pos = initalrotate["pos_config_mirror"];
|
||||
}
|
||||
if (mirror_pos > -1) {
|
||||
if (mirror) {
|
||||
config_split[mirror_pos] = "InitialMirror = true";
|
||||
}
|
||||
else {
|
||||
config_split[mirror_pos] = "InitialMirror = false";
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (mirror) { // neue Zeile muss an der richtigen Stelle eingefügt werden - hier direct nach [Alignment]
|
||||
var aktline = 0;
|
||||
|
||||
while (aktline < config_split.length){
|
||||
if (config_split[aktline].trim() == "[Alignment]") {
|
||||
break;
|
||||
}
|
||||
aktline++
|
||||
}
|
||||
|
||||
// fuege neue Zeile in config_split ein
|
||||
var zw = config_split[config_split.length-1];
|
||||
config_split.push(zw);
|
||||
for (var j = config_split.length-2; j > aktline + 1; --j){
|
||||
config_split[j] = config_split[j-1];
|
||||
}
|
||||
|
||||
config_split[aktline + 1] = "InitialMirror = True"
|
||||
}
|
||||
}
|
||||
|
||||
SaveConfigToServer(_basepath);
|
||||
}
|
||||
|
||||
function UpdateConfig(zw, _index, _enhance, _basepath){
|
||||
var zeile = zw["name"] + " " + zw["x"] + " " + zw["y"];
|
||||
var _pos = ref[_index]["pos_ref"];
|
||||
config_split[_pos] = zeile;
|
||||
|
||||
SaveConfigToServer(_basepath);
|
||||
|
||||
var namezw = zw["name"];
|
||||
FileCopyOnServer("/img_tmp/ref_zw.jpg", namezw, _basepath);
|
||||
var namezw = zw["name"].replace(".jpg", "_org.jpg");
|
||||
FileCopyOnServer("/img_tmp/ref_zw_org.jpg", namezw, _basepath);
|
||||
}
|
||||
|
||||
|
||||
function createReader(file) {
|
||||
var image = new Image();
|
||||
reader.onload = function(evt) {
|
||||
var image = new Image();
|
||||
image.onload = function(evt) {
|
||||
var width = this.width;
|
||||
var height = this.height;
|
||||
alert (width); // will produce something like 198
|
||||
};
|
||||
image.src = evt.target.result;
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
|
||||
|
||||
|
||||
function ZerlegeZeile(input)
|
||||
{
|
||||
var Output = Array(0);
|
||||
delimiter = " =,\r";
|
||||
|
||||
input = trim(input, delimiter);
|
||||
var pos = findDelimiterPos(input, delimiter);
|
||||
var token;
|
||||
while (pos > -1) {
|
||||
token = input.substr(0, pos);
|
||||
token = trim(token, delimiter);
|
||||
Output.push(token);
|
||||
input = input.substr(pos+1, input.length);
|
||||
input = trim(input, delimiter);
|
||||
pos = findDelimiterPos(input, delimiter);
|
||||
}
|
||||
Output.push(input);
|
||||
|
||||
return Output;
|
||||
|
||||
}
|
||||
|
||||
function findDelimiterPos(input, delimiter)
|
||||
{
|
||||
var pos = -1;
|
||||
var zw;
|
||||
var akt_del;
|
||||
|
||||
for (var anz = 0; anz < delimiter.length; ++anz)
|
||||
{
|
||||
akt_del = delimiter[anz];
|
||||
zw = input.indexOf(akt_del);
|
||||
if (zw > -1)
|
||||
{
|
||||
if (pos > -1)
|
||||
{
|
||||
if (zw < pos)
|
||||
pos = zw;
|
||||
}
|
||||
else
|
||||
pos = zw;
|
||||
}
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
||||
|
||||
function trim(istring, adddelimiter)
|
||||
{
|
||||
while ((istring.length > 0) && (adddelimiter.indexOf(istring[0]) >= 0)){
|
||||
istring = istring.substr(1, istring.length-1);
|
||||
}
|
||||
|
||||
while ((istring.length > 0) && (adddelimiter.indexOf(istring[istring.length-1]) >= 0)){
|
||||
istring = istring.substr(0, istring.length-1);
|
||||
}
|
||||
|
||||
return istring;
|
||||
}
|
||||
|
||||
|
||||
|
||||
function loadConfig(_basepath) {
|
||||
var xhttp = new XMLHttpRequest();
|
||||
try {
|
||||
url = _basepath + '/fileserver/config/config.ini';
|
||||
xhttp.open("GET", url, false);
|
||||
xhttp.send();
|
||||
config_gesamt = xhttp.responseText;
|
||||
}
|
||||
catch (error)
|
||||
{
|
||||
// alert("Deleting Config.ini failed");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function dataURLtoBlob(dataurl) {
|
||||
var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
|
||||
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
|
||||
while(n--){
|
||||
u8arr[n] = bstr.charCodeAt(n);
|
||||
}
|
||||
return new Blob([u8arr], {type:mime});
|
||||
}
|
||||
|
||||
function FileCopyOnServer(_source, _target, _basepath = ""){
|
||||
url = _basepath + "/editflow.html?task=copy&in=" + _source + "&out=" + _target;
|
||||
var xhttp = new XMLHttpRequest();
|
||||
try {
|
||||
xhttp.open("GET", url, false);
|
||||
xhttp.send(); }
|
||||
catch (error)
|
||||
{
|
||||
// alert("Deleting Config.ini failed");
|
||||
}
|
||||
}
|
||||
|
||||
function FileDeleteOnServer(_filename, _basepath = ""){
|
||||
var xhttp = new XMLHttpRequest();
|
||||
var okay = false;
|
||||
|
||||
xhttp.onreadystatechange = function() {
|
||||
if (xhttp.readyState == 4) {
|
||||
if (xhttp.status == 200) {
|
||||
okay = true;
|
||||
} else if (xhttp.status == 0) {
|
||||
// alert("Server closed the connection on delete abruptly!");
|
||||
// location.reload()
|
||||
} else {
|
||||
// alert(xhttp.status + " Error!\n" + xhttp.responseText);
|
||||
// location.reload()
|
||||
}
|
||||
}
|
||||
};
|
||||
try {
|
||||
var url = _basepath + "/delete" + _filename;
|
||||
xhttp.open("POST", url, false);
|
||||
xhttp.send();
|
||||
}
|
||||
catch (error)
|
||||
{
|
||||
// alert("Deleting Config.ini failed");
|
||||
}
|
||||
|
||||
return okay;
|
||||
}
|
||||
|
||||
function FileSendContent(_content, _filename, _basepath = ""){
|
||||
var xhttp = new XMLHttpRequest();
|
||||
var okay = false;
|
||||
|
||||
xhttp.onreadystatechange = function() {
|
||||
if (xhttp.readyState == 4) {
|
||||
if (xhttp.status == 200) {
|
||||
okay = true;
|
||||
} else if (xhttp.status == 0) {
|
||||
alert("Server closed the connection abruptly!");
|
||||
} else {
|
||||
alert(xhttp.status + " Error!\n" + xhttp.responseText);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
upload_path = _basepath + "/upload" + _filename;
|
||||
xhttp.open("POST", upload_path, false);
|
||||
xhttp.send(_content);
|
||||
}
|
||||
catch (error)
|
||||
{
|
||||
// alert("Deleting Config.ini failed");
|
||||
}
|
||||
return okay;
|
||||
}
|
||||
@@ -5,6 +5,7 @@ function readconfig_Version(){
|
||||
var config_gesamt;
|
||||
var config_split;
|
||||
var param;
|
||||
var category;
|
||||
var ref = new Array(2);
|
||||
|
||||
function ParseConfig() {
|
||||
@@ -12,8 +13,12 @@ function ParseConfig() {
|
||||
var aktline = 0;
|
||||
|
||||
param = new Object();
|
||||
category = new Object();
|
||||
|
||||
var catname = "MakeImage";
|
||||
category[catname] = new Object();
|
||||
category[catname]["enabled"] = false;
|
||||
category[catname]["found"] = false;
|
||||
param[catname] = new Object();
|
||||
ParamAddValue(param, catname, "LogImageLocation");
|
||||
ParamAddValue(param, catname, "WaitBeforeTakingPicture");
|
||||
@@ -22,25 +27,39 @@ function ParseConfig() {
|
||||
ParamAddValue(param, catname, "ImageSize");
|
||||
|
||||
var catname = "Alignment";
|
||||
category[catname] = new Object();
|
||||
category[catname]["enabled"] = false;
|
||||
category[catname]["found"] = false;
|
||||
param[catname] = new Object();
|
||||
ParamAddValue(param, catname, "SearchFieldX");
|
||||
ParamAddValue(param, catname, "SearchFieldY");
|
||||
ParamAddValue(param, catname, "AlignmentAlgo");
|
||||
|
||||
var catname = "Digits";
|
||||
category[catname] = new Object();
|
||||
category[catname]["enabled"] = false;
|
||||
category[catname]["found"] = false;
|
||||
param[catname] = new Object();
|
||||
ParamAddValue(param, catname, "Model");
|
||||
ParamAddValue(param, catname, "LogImageLocation");
|
||||
ParamAddValue(param, catname, "LogfileRetentionInDays");
|
||||
ParamAddValue(param, catname, "ModelInputSize");
|
||||
ParamAddValue(param, catname, "ModelInputSize", 2);
|
||||
|
||||
var catname = "Analog";
|
||||
category[catname] = new Object();
|
||||
category[catname]["enabled"] = false;
|
||||
category[catname]["found"] = false;
|
||||
param[catname] = new Object();
|
||||
ParamAddValue(param, catname, "Model");
|
||||
ParamAddValue(param, catname, "LogImageLocation");
|
||||
ParamAddValue(param, catname, "LogfileRetentionInDays");
|
||||
ParamAddValue(param, catname, "ModelInputSize");
|
||||
ParamAddValue(param, catname, "ModelInputSize", 2);
|
||||
ParamAddValue(param, catname, "ExtendedResolution");
|
||||
|
||||
var catname = "PostProcessing";
|
||||
category[catname] = new Object();
|
||||
category[catname]["enabled"] = false;
|
||||
category[catname]["found"] = false;
|
||||
param[catname] = new Object();
|
||||
ParamAddValue(param, catname, "DecimalShift");
|
||||
ParamAddValue(param, catname, "PreValueUse");
|
||||
@@ -51,6 +70,9 @@ function ParseConfig() {
|
||||
ParamAddValue(param, catname, "CheckDigitIncreaseConsistency");
|
||||
|
||||
var catname = "MQTT";
|
||||
category[catname] = new Object();
|
||||
category[catname]["enabled"] = false;
|
||||
category[catname]["found"] = false;
|
||||
param[catname] = new Object();
|
||||
ParamAddValue(param, catname, "Uri");
|
||||
ParamAddValue(param, catname, "Topic");
|
||||
@@ -60,224 +82,77 @@ function ParseConfig() {
|
||||
ParamAddValue(param, catname, "password");
|
||||
|
||||
var catname = "AutoTimer";
|
||||
category[catname] = new Object();
|
||||
category[catname]["enabled"] = false;
|
||||
category[catname]["found"] = false;
|
||||
param[catname] = new Object();
|
||||
ParamAddValue(param, catname, "AutoStart");
|
||||
ParamAddValue(param, catname, "Intervall");
|
||||
|
||||
var catname = "Debug";
|
||||
category[catname] = new Object();
|
||||
category[catname]["enabled"] = false;
|
||||
category[catname]["found"] = false;
|
||||
param[catname] = new Object();
|
||||
ParamAddValue(param, catname, "Logfile");
|
||||
ParamAddValue(param, catname, "LogfileRetentionInDays");
|
||||
|
||||
var catname = "System";
|
||||
category[catname] = new Object();
|
||||
category[catname]["enabled"] = false;
|
||||
category[catname]["found"] = false;
|
||||
param[catname] = new Object();
|
||||
ParamAddValue(param, catname, "TimeZone");
|
||||
ParamAddValue(param, catname, "TimeServer");
|
||||
ParamAddValue(param, catname, "AutoAdjustSummertime");
|
||||
ParamAddValue(param, catname, "TimeUpdateIntervall");
|
||||
ParamAddValue(param, catname, "Hostname");
|
||||
ParamAddValue(param, catname, "SetupMode");
|
||||
|
||||
while (aktline < config_split.length){
|
||||
if (config_split[aktline].trim().toUpperCase() == "[MAKEIMAGE]") {
|
||||
aktline = ParseConfigParamMakeImage(aktline);
|
||||
continue;
|
||||
for (var cat in category) {
|
||||
zw = cat.toUpperCase();
|
||||
zw1 = "[" + zw + "]";
|
||||
zw2 = ";[" + zw + "]";
|
||||
if ((config_split[aktline].trim().toUpperCase() == zw1) || (config_split[aktline].trim().toUpperCase() == zw2)) {
|
||||
if (config_split[aktline].trim().toUpperCase() == zw1) {
|
||||
category[cat]["enabled"] = true;
|
||||
}
|
||||
category[cat]["found"] = true;
|
||||
category[cat]["line"] = aktline;
|
||||
aktline = ParseConfigParamAll(aktline, cat);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (config_split[aktline].trim().toUpperCase() == "[ALIGNMENT]") {
|
||||
aktline = ParseConfigParamAlignment(aktline);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (config_split[aktline].trim().toUpperCase() == "[DIGITS]") {
|
||||
aktline = ParseConfigParamDigit(aktline);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (config_split[aktline].trim().toUpperCase() == "[ANALOG]") {
|
||||
aktline = ParseConfigParamAnalog(aktline);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (config_split[aktline].trim().toUpperCase() == "[POSTPROCESSING]") {
|
||||
aktline = ParseConfigParamPostProcessing(aktline);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (config_split[aktline].trim().toUpperCase() == "[MQTT]") {
|
||||
aktline = ParseConfigParamMQTT(aktline);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (config_split[aktline].trim().toUpperCase() == "[AUTOTIMER]") {
|
||||
aktline = ParseConfigParamAutoTimer(aktline);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (config_split[aktline].trim().toUpperCase() == "[DEBUG]") {
|
||||
aktline = ParseConfigParamDebug(aktline);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (config_split[aktline].trim().toUpperCase() == "[SYSTEM]") {
|
||||
aktline = ParseConfigParamSystem(aktline);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
aktline++;
|
||||
}
|
||||
}
|
||||
|
||||
function ParamAddValue(param, _cat, _param){
|
||||
function ParamAddValue(param, _cat, _param, _anzParam = 1){
|
||||
param[_cat][_param] = new Object();
|
||||
param[_cat][_param]["found"] = false;
|
||||
param[_cat][_param]["enabled"] = false;
|
||||
param[_cat][_param]["line"] = -1;
|
||||
param[_cat][_param]["anzParam"] = _anzParam;
|
||||
};
|
||||
|
||||
|
||||
function ParseConfigParamSystem(_aktline){
|
||||
var akt_ref = 0;
|
||||
|
||||
function ParseConfigParamAll(_aktline, _catname){
|
||||
++_aktline;
|
||||
|
||||
var catname = "System";
|
||||
while ((akt_ref < 2) && (_aktline < config_split.length) && (config_split[_aktline][0] != "[")) {
|
||||
var _input = config_split[_aktline];
|
||||
let [isCom, input] = isCommented(_input);
|
||||
var linesplit = ZerlegeZeile(input, " =");
|
||||
|
||||
ParamExtractValue(param, linesplit, catname, "TimeZone", _aktline, isCom);
|
||||
ParamExtractValue(param, linesplit, catname, "AutoAdjustSummertime", _aktline, isCom);
|
||||
ParamExtractValue(param, linesplit, catname, "TimeUpdateIntervall", _aktline, isCom);
|
||||
|
||||
++_aktline;
|
||||
}
|
||||
return _aktline;
|
||||
}
|
||||
|
||||
function ParseConfigParamDebug(_aktline){
|
||||
var akt_ref = 0;
|
||||
++_aktline;
|
||||
|
||||
var catname = "Debug";
|
||||
while ((akt_ref < 2) && (_aktline < config_split.length) && (config_split[_aktline][0] != "[")) {
|
||||
while ((_aktline < config_split.length)
|
||||
&& !(config_split[_aktline][0] == "[")
|
||||
&& !((config_split[_aktline][0] == ";") && (config_split[_aktline][1] == "["))) {
|
||||
var _input = config_split[_aktline];
|
||||
let [isCom, input] = isCommented(_input);
|
||||
var linesplit = ZerlegeZeile(input);
|
||||
|
||||
ParamExtractValue(param, linesplit, catname, "Logfile", _aktline, isCom);
|
||||
ParamExtractValue(param, linesplit, catname, "LogfileRetentionInDays", _aktline, isCom);
|
||||
ParamExtractValueAll(param, linesplit, _catname, _aktline, isCom);
|
||||
|
||||
++_aktline;
|
||||
}
|
||||
return _aktline;
|
||||
}
|
||||
|
||||
function ParseConfigParamAutoTimer(_aktline){
|
||||
var akt_ref = 0;
|
||||
++_aktline;
|
||||
|
||||
var catname = "AutoTimer";
|
||||
while ((akt_ref < 2) && (_aktline < config_split.length) && (config_split[_aktline][0] != "[")) {
|
||||
var _input = config_split[_aktline];
|
||||
let [isCom, input] = isCommented(_input);
|
||||
var linesplit = ZerlegeZeile(input);
|
||||
|
||||
ParamExtractValue(param, linesplit, catname, "AutoStart", _aktline, isCom);
|
||||
ParamExtractValue(param, linesplit, catname, "Intervall", _aktline, isCom);
|
||||
|
||||
++_aktline;
|
||||
}
|
||||
return _aktline;
|
||||
}
|
||||
|
||||
function ParseConfigParamMQTT(_aktline){
|
||||
var akt_ref = 0;
|
||||
++_aktline;
|
||||
|
||||
var catname = "MQTT";
|
||||
while ((akt_ref < 2) && (_aktline < config_split.length) && (config_split[_aktline][0] != "[")) {
|
||||
var _input = config_split[_aktline];
|
||||
let [isCom, input] = isCommented(_input);
|
||||
var linesplit = ZerlegeZeile(input);
|
||||
|
||||
ParamExtractValue(param, linesplit, catname, "Uri", _aktline, isCom);
|
||||
ParamExtractValue(param, linesplit, catname, "Topic", _aktline, isCom);
|
||||
ParamExtractValue(param, linesplit, catname, "TopicError", _aktline, isCom);
|
||||
ParamExtractValue(param, linesplit, catname, "ClientID", _aktline, isCom);
|
||||
ParamExtractValue(param, linesplit, catname, "user", _aktline, isCom);
|
||||
ParamExtractValue(param, linesplit, catname, "password", _aktline, isCom);
|
||||
|
||||
++_aktline;
|
||||
}
|
||||
return _aktline;
|
||||
}
|
||||
|
||||
function ParseConfigParamPostProcessing(_aktline){
|
||||
var akt_ref = 0;
|
||||
++_aktline;
|
||||
|
||||
var catname = "PostProcessing";
|
||||
while ((akt_ref < 2) && (_aktline < config_split.length) && (config_split[_aktline][0] != "[")) {
|
||||
var _input = config_split[_aktline];
|
||||
let [isCom, input] = isCommented(_input);
|
||||
var linesplit = ZerlegeZeile(input);
|
||||
|
||||
ParamExtractValue(param, linesplit, catname, "DecimalShift", _aktline, isCom);
|
||||
ParamExtractValue(param, linesplit, catname, "PreValueUse", _aktline, isCom);
|
||||
ParamExtractValue(param, linesplit, catname, "PreValueAgeStartup", _aktline, isCom);
|
||||
ParamExtractValue(param, linesplit, catname, "AllowNegativeRates", _aktline, isCom);
|
||||
ParamExtractValue(param, linesplit, catname, "MaxRateValue", _aktline, isCom);
|
||||
ParamExtractValue(param, linesplit, catname, "ErrorMessage", _aktline, isCom);
|
||||
ParamExtractValue(param, linesplit, catname, "CheckDigitIncreaseConsistency", _aktline, isCom);
|
||||
|
||||
++_aktline;
|
||||
}
|
||||
return _aktline;
|
||||
}
|
||||
|
||||
function ParseConfigParamAnalog(_aktline){
|
||||
var akt_ref = 0;
|
||||
++_aktline;
|
||||
|
||||
var catname = "Analog";
|
||||
while ((akt_ref < 2) && (_aktline < config_split.length) && (config_split[_aktline][0] != "[")) {
|
||||
var _input = config_split[_aktline];
|
||||
let [isCom, input] = isCommented(_input);
|
||||
var linesplit = ZerlegeZeile(input);
|
||||
|
||||
ParamExtractValue(param, linesplit, catname, "Model", _aktline, isCom);
|
||||
ParamExtractValue(param, linesplit, catname, "LogImageLocation", _aktline, isCom);
|
||||
ParamExtractValue(param, linesplit, catname, "LogfileRetentionInDays", _aktline, isCom);
|
||||
ParamExtractValue(param, linesplit, catname, "ModelInputSize", _aktline, isCom, 2);
|
||||
|
||||
++_aktline;
|
||||
}
|
||||
return _aktline;
|
||||
}
|
||||
|
||||
function ParseConfigParamDigit(_aktline){
|
||||
var akt_ref = 0;
|
||||
++_aktline;
|
||||
|
||||
var catname = "Digits";
|
||||
while ((akt_ref < 2) && (_aktline < config_split.length) && (config_split[_aktline][0] != "[")) {
|
||||
var _input = config_split[_aktline];
|
||||
let [isCom, input] = isCommented(_input);
|
||||
var linesplit = ZerlegeZeile(input);
|
||||
|
||||
ParamExtractValue(param, linesplit, catname, "Model", _aktline, isCom);
|
||||
ParamExtractValue(param, linesplit, catname, "LogImageLocation", _aktline, isCom);
|
||||
ParamExtractValue(param, linesplit, catname, "LogfileRetentionInDays", _aktline, isCom);
|
||||
ParamExtractValue(param, linesplit, catname, "ModelInputSize", _aktline, isCom, 2);
|
||||
|
||||
++_aktline;
|
||||
}
|
||||
return _aktline;
|
||||
}
|
||||
|
||||
|
||||
function ParamExtractValue(_param, _linesplit, _catname, _paramname, _aktline, _iscom, _anzvalue = 1){
|
||||
if ((_linesplit[0].toUpperCase() == _paramname.toUpperCase()) && (_linesplit.length > _anzvalue))
|
||||
{
|
||||
@@ -291,66 +166,40 @@ function ParamExtractValue(_param, _linesplit, _catname, _paramname, _aktline, _
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function ParseConfigParamAlignment(_aktline){
|
||||
var akt_ref = 0;
|
||||
++_aktline;
|
||||
|
||||
var catname = "Alignment";
|
||||
while ((akt_ref < 2) && (_aktline < config_split.length) && (config_split[_aktline][0] != "[")) {
|
||||
var _input = config_split[_aktline];
|
||||
let [isCom, input] = isCommented(_input);
|
||||
var linesplit = ZerlegeZeile(input);
|
||||
|
||||
ParamExtractValue(param, linesplit, catname, "SearchFieldX", _aktline, isCom);
|
||||
ParamExtractValue(param, linesplit, catname, "SearchFieldY", _aktline, isCom);
|
||||
|
||||
++_aktline;
|
||||
function ParamExtractValueAll(_param, _linesplit, _catname, _aktline, _iscom){
|
||||
for (var paramname in _param[_catname]) {
|
||||
if ((_linesplit[0].toUpperCase() == paramname.toUpperCase()) && (_linesplit.length > _param[_catname][paramname]["anzParam"]))
|
||||
{
|
||||
_param[_catname][paramname]["found"] = true;
|
||||
_param[_catname][paramname]["enabled"] = !_iscom;
|
||||
_param[_catname][paramname]["line"] = _aktline;
|
||||
for (var j = 1; j <= _param[_catname][paramname]["anzParam"]; ++j) {
|
||||
_param[_catname][paramname]["value"+j] = _linesplit[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
return _aktline;
|
||||
}
|
||||
|
||||
function ParseConfigParamMakeImage(_aktline){
|
||||
var akt_ref = 0;
|
||||
++_aktline;
|
||||
|
||||
var catname = "MakeImage";
|
||||
while ((akt_ref < 2) && (_aktline < config_split.length) && (config_split[_aktline][0] != "[")) {
|
||||
var _input = config_split[_aktline];
|
||||
let [isCom, input] = isCommented(_input);
|
||||
var linesplit = ZerlegeZeile(input);
|
||||
|
||||
ParamExtractValue(param, linesplit, catname, "LogImageLocation", _aktline, isCom);
|
||||
ParamExtractValue(param, linesplit, catname, "WaitBeforeTakingPicture", _aktline, isCom);
|
||||
ParamExtractValue(param, linesplit, catname, "LogfileRetentionInDays", _aktline, isCom);
|
||||
ParamExtractValue(param, linesplit, catname, "ImageQuality", _aktline, isCom);
|
||||
ParamExtractValue(param, linesplit, catname, "ImageSize", _aktline, isCom);
|
||||
|
||||
++_aktline;
|
||||
}
|
||||
return _aktline;
|
||||
}
|
||||
|
||||
function getConfigParameters() {
|
||||
return param;
|
||||
}
|
||||
|
||||
function setConfigParameters(_param) {
|
||||
function setConfigParameters(_param, _category) {
|
||||
for (var cat in _param) {
|
||||
for (var name in _param[cat]) {
|
||||
param[cat][name]["found"] = _param[cat][name]["found"];
|
||||
param[cat][name]["enabled"] = _param[cat][name]["enabled"];
|
||||
param[cat][name]["line"] = _param[cat][name]["line"];
|
||||
|
||||
param[cat][name]["anzpara"] = _param[cat][name]["anzpara"];
|
||||
for (var j = 1; j <= _param[cat][name]["anzpara"]; ++j) {
|
||||
param[cat][name]["anzParam"] = _param[cat][name]["anzParam"];
|
||||
for (var j = 1; j <= _param[cat][name]["anzParam"]; ++j) {
|
||||
param[cat][name]["value"+j] = _param[cat][name]["value"+j];
|
||||
}
|
||||
|
||||
if (param[cat][name]["found"]) {
|
||||
var text = name + " ="
|
||||
|
||||
for (var j = 1; j <= _param[cat][name]["anzpara"]; ++j) {
|
||||
for (var j = 1; j <= _param[cat][name]["anzParam"]; ++j) {
|
||||
text = text + " " + param[cat][name]["value"+j];
|
||||
}
|
||||
if (!param[cat][name]["enabled"]) {
|
||||
@@ -361,6 +210,19 @@ function setConfigParameters(_param) {
|
||||
}
|
||||
}
|
||||
|
||||
for (var cat in _category) {
|
||||
if (category[cat]["found"])
|
||||
{
|
||||
category[cat]["enabled"] = _category[cat]["enabled"];
|
||||
text = "[" + cat + "]";
|
||||
if (!category[cat]["enabled"]) {
|
||||
text = ";" + text;
|
||||
}
|
||||
config_split[category[cat]["line"]] = text;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
config_gesamt = config_split[0];
|
||||
for (var i = 1; i < config_split.length; ++i){
|
||||
config_gesamt = config_gesamt + "\n" + config_split[i];
|
||||
@@ -394,171 +256,16 @@ function SaveConfigToServer(_basepath){
|
||||
}
|
||||
|
||||
FileDeleteOnServer("/config/config.ini", _basepath);
|
||||
|
||||
FileSendContent(config_gesamt, "/config/config.ini", _basepath);
|
||||
}
|
||||
|
||||
function createReader(file) {
|
||||
var image = new Image();
|
||||
reader.onload = function(evt) {
|
||||
var image = new Image();
|
||||
image.onload = function(evt) {
|
||||
var width = this.width;
|
||||
var height = this.height;
|
||||
alert (width); // will produce something like 198
|
||||
};
|
||||
image.src = evt.target.result;
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
|
||||
function ZerlegeZeile(input, delimiter = " =,")
|
||||
{
|
||||
var Output = Array(0);
|
||||
// delimiter = " =,";
|
||||
|
||||
input = trim(input, delimiter);
|
||||
var pos = findDelimiterPos(input, delimiter);
|
||||
var token;
|
||||
while (pos > -1) {
|
||||
token = input.substr(0, pos);
|
||||
token = trim(token, delimiter);
|
||||
Output.push(token);
|
||||
input = input.substr(pos+1, input.length);
|
||||
input = trim(input, delimiter);
|
||||
pos = findDelimiterPos(input, delimiter);
|
||||
}
|
||||
Output.push(input);
|
||||
|
||||
return Output;
|
||||
|
||||
}
|
||||
|
||||
function findDelimiterPos(input, delimiter)
|
||||
{
|
||||
var pos = -1;
|
||||
var zw;
|
||||
var akt_del;
|
||||
|
||||
for (var anz = 0; anz < delimiter.length; ++anz)
|
||||
{
|
||||
akt_del = delimiter[anz];
|
||||
zw = input.indexOf(akt_del);
|
||||
if (zw > -1)
|
||||
{
|
||||
if (pos > -1)
|
||||
{
|
||||
if (zw < pos)
|
||||
pos = zw;
|
||||
}
|
||||
else
|
||||
pos = zw;
|
||||
}
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
function trim(istring, adddelimiter)
|
||||
{
|
||||
while ((istring.length > 0) && (adddelimiter.indexOf(istring[0]) >= 0)){
|
||||
istring = istring.substr(1, istring.length-1);
|
||||
}
|
||||
|
||||
while ((istring.length > 0) && (adddelimiter.indexOf(istring[istring.length-1]) >= 0)){
|
||||
istring = istring.substr(0, istring.length-1);
|
||||
}
|
||||
|
||||
return istring;
|
||||
}
|
||||
|
||||
function loadConfig(_basepath) {
|
||||
var xhttp = new XMLHttpRequest();
|
||||
config_gesamt = "";
|
||||
try {
|
||||
url = _basepath + '/fileserver/config/config.ini';
|
||||
xhttp.open("GET", url, false);
|
||||
xhttp.send();
|
||||
config_gesamt = xhttp.responseText;
|
||||
return true;
|
||||
}
|
||||
catch (error)
|
||||
{
|
||||
// alert("Deleting Config.ini failed");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function getConfig() {
|
||||
return config_gesamt;
|
||||
}
|
||||
|
||||
|
||||
function FileCopyOnServer(_source, _target, _basepath = ""){
|
||||
url = _basepath + "/editflow.html?task=copy&in=" + _source + "&out=" + _target;
|
||||
var xhttp = new XMLHttpRequest();
|
||||
try {
|
||||
xhttp.open("GET", url, false);
|
||||
xhttp.send(); }
|
||||
catch (error)
|
||||
{
|
||||
// alert("Deleting Config.ini failed");
|
||||
}
|
||||
function getConfigCategory() {
|
||||
return category;
|
||||
}
|
||||
|
||||
function FileDeleteOnServer(_filename, _basepath = ""){
|
||||
var xhttp = new XMLHttpRequest();
|
||||
var okay = false;
|
||||
|
||||
xhttp.onreadystatechange = function() {
|
||||
if (xhttp.readyState == 4) {
|
||||
if (xhttp.status == 200) {
|
||||
okay = true;
|
||||
} else if (xhttp.status == 0) {
|
||||
// alert("Server closed the connection on delete abruptly!");
|
||||
// location.reload()
|
||||
} else {
|
||||
// alert(xhttp.status + " Error!\n" + xhttp.responseText);
|
||||
// location.reload()
|
||||
}
|
||||
}
|
||||
};
|
||||
try {
|
||||
var url = _basepath + "/delete" + _filename;
|
||||
xhttp.open("POST", url, false);
|
||||
xhttp.send();
|
||||
}
|
||||
catch (error)
|
||||
{
|
||||
// alert("Deleting Config.ini failed");
|
||||
}
|
||||
|
||||
return okay;
|
||||
}
|
||||
|
||||
function FileSendContent(_content, _filename, _basepath = ""){
|
||||
var xhttp = new XMLHttpRequest();
|
||||
var okay = false;
|
||||
|
||||
xhttp.onreadystatechange = function() {
|
||||
if (xhttp.readyState == 4) {
|
||||
if (xhttp.status == 200) {
|
||||
okay = true;
|
||||
} else if (xhttp.status == 0) {
|
||||
alert("Server closed the connection abruptly!");
|
||||
} else {
|
||||
alert(xhttp.status + " Error!\n" + xhttp.responseText);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
upload_path = _basepath + "/upload" + _filename;
|
||||
xhttp.open("POST", upload_path, false);
|
||||
xhttp.send(_content);
|
||||
}
|
||||
catch (error)
|
||||
{
|
||||
// alert("Deleting Config.ini failed");
|
||||
}
|
||||
return okay;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user