mirror of
https://github.com/jomjol/AI-on-the-edge-device.git
synced 2025-12-10 21:46:55 +03:00
Merge pull request #75 from jomjol/rolling-reduce-sd-use
Update with reduced SD card usage
This commit is contained in:
21
README.md
21
README.md
@@ -19,13 +19,30 @@ A 3d-printable housing can be found here: https://www.thingiverse.com/thing:4571
|
||||
|
||||
### Known Issues
|
||||
|
||||
* Reboot on extensive web access due to the limits of the internal web server
|
||||
* Spontaneous reboots, most probably due to weak power supply during power intensive operations (taking / calculating pictures)
|
||||
|
||||
------
|
||||
|
||||
**General remark:** Beside the `firmware.bin`, typically also the content of `/html` needs to be updated!
|
||||
|
||||
##### Rolling - (2020-12-07)
|
||||
##### Rolling - (2020-12-27)
|
||||
|
||||
* Major change: no need of SD card for image processing anymore (all in memory)
|
||||
* 95% less SD card writing
|
||||
* SD use: mainly reading of data (config, html, tflite parameters), only log files and prevalue write on SD card anymore
|
||||
* Need to limit camera resolution to VGA (due to memory limits)
|
||||
* New Feature: setting of time server in `config.ini`
|
||||
|
||||
```
|
||||
[System]
|
||||
TimeServer = fritz.box
|
||||
```
|
||||
|
||||
* Bug fix: corrected handling of out commented analog pointer ROIs
|
||||
|
||||
|
||||
2020-12-07
|
||||
|
||||
|
||||
* Improvement: internal file handling
|
||||
|
||||
|
||||
@@ -270,37 +270,6 @@ void LoadWlanFromFile(std::string fn, std::string &_ssid, std::string &_passphra
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
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 = "";
|
||||
|
||||
@@ -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,8 @@
|
||||
|
||||
#include "esp_camera.h"
|
||||
|
||||
// WROVER-KIT PIN Map
|
||||
#ifdef BOARD_WROVER_KIT
|
||||
|
||||
#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 +46,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 = {
|
||||
@@ -120,7 +73,8 @@ static camera_config_t camera_config = {
|
||||
.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,14 +82,11 @@ 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
|
||||
|
||||
@@ -145,8 +96,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
|
||||
@@ -172,14 +121,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){
|
||||
@@ -200,12 +141,157 @@ 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;
|
||||
static const int BMP_HEADER_LEN = 54; // von to_bmp.c !!!!!!!!!!!!!!!
|
||||
|
||||
LEDOnOff(true);
|
||||
|
||||
// if (debug_detail_heap) LogFile.WriteHeapInfo("CCamera::CaptureToBasisImage - Start");
|
||||
|
||||
if (delay > 0)
|
||||
{
|
||||
LightOnOff(true);
|
||||
const TickType_t xDelay = delay / portTICK_PERIOD_MS;
|
||||
vTaskDelay( xDelay );
|
||||
}
|
||||
|
||||
// if (debug_detail_heap) LogFile.WriteHeapInfo("CCamera::CaptureToBasisImage - After LightOn");
|
||||
|
||||
camera_fb_t * fb = esp_camera_fb_get();
|
||||
if (!fb) {
|
||||
ESP_LOGE(TAGCAMERACLASS, "Camera Capture Failed");
|
||||
LEDOnOff(false);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
// if (debug_detail_heap) LogFile.WriteHeapInfo("CCamera::CaptureToBasisImage - After fb_get");
|
||||
|
||||
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;
|
||||
size_t buf_len = 0;
|
||||
|
||||
int _anz = 0;
|
||||
xDelay = 3000 / portTICK_PERIOD_MS;
|
||||
|
||||
while (!frame2bmp(fb, &buf, &buf_len) && _anz < 5)
|
||||
{
|
||||
std::string _zw1 = "CCamera::CaptureToBasisImage failed #" + std::to_string(++_anz);
|
||||
LogFile.WriteToFile(_zw1);
|
||||
|
||||
esp_camera_fb_return(fb);
|
||||
_zw1 = "CCamera::CaptureToBasisImage failed #" + std::to_string(_anz) + " - after esp_camera_fb_return";
|
||||
LogFile.WriteToFile(_zw1);
|
||||
free(buf);
|
||||
|
||||
_zw1 = "CCamera::CaptureToBasisImage failed #" + std::to_string(_anz) + " - after free";
|
||||
LogFile.WriteToFile(_zw1);
|
||||
|
||||
InitCam();
|
||||
|
||||
_zw1 = "CCamera::CaptureToBasisImage failed #" + std::to_string(_anz) + " - after InitCam";
|
||||
LogFile.WriteToFile(_zw1);
|
||||
|
||||
vTaskDelay( xDelay );
|
||||
fb = esp_camera_fb_get();
|
||||
|
||||
_zw1 = "CCamera::CaptureToBasisImage failed #" + std::to_string(_anz) + " - after esp_camera_fb_get";
|
||||
LogFile.WriteToFile(_zw1);
|
||||
|
||||
}
|
||||
|
||||
|
||||
esp_camera_fb_return(fb);
|
||||
|
||||
if (debug_detail_heap) LogFile.WriteHeapInfo("CCamera::CaptureToBasisImage - After frame2bmp");
|
||||
|
||||
int _len_zw = buf_len - BMP_HEADER_LEN;
|
||||
uint8_t *_buf_zeiger = buf + BMP_HEADER_LEN;
|
||||
|
||||
stbi_uc* p_target;
|
||||
stbi_uc* p_source;
|
||||
int channels = 3;
|
||||
int width = image_width;
|
||||
int height = image_height;
|
||||
|
||||
std::string _zw = "Targetimage: " + std::to_string((int) _Image->rgb_image) + " Size: " + std::to_string(_Image->width) + ", " + std::to_string(_Image->height);
|
||||
_zw = _zw + " Buf: " + std::to_string((int) buf);
|
||||
|
||||
if (debug_detail_heap) LogFile.WriteToFile(_zw);
|
||||
|
||||
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 = _buf_zeiger + (channels * (y * width + x));
|
||||
p_target[0] = p_source[2];
|
||||
p_target[1] = p_source[1];
|
||||
p_target[2] = p_source[0];
|
||||
}
|
||||
|
||||
if (debug_detail_heap) LogFile.WriteHeapInfo("CCamera::CaptureToBasisImage - After Copy To Target");
|
||||
|
||||
// _Image->CopyFromMemory(_buf_zeiger, _len_zw);
|
||||
|
||||
free(buf);
|
||||
|
||||
if (debug_detail_heap) LogFile.WriteHeapInfo("CCamera::CaptureToBasisImage - Done");
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
esp_err_t CCamera::CaptureToFile(std::string nm, int delay)
|
||||
{
|
||||
// nm = "/sdcard/josef_zw.bmp";
|
||||
string ftype;
|
||||
|
||||
LEDOnOff(true);
|
||||
@@ -286,15 +372,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){
|
||||
@@ -312,6 +412,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;
|
||||
}
|
||||
|
||||
@@ -409,8 +515,6 @@ CCamera::CCamera()
|
||||
|
||||
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,6 +25,8 @@ class CCamera {
|
||||
framesize_t ActualResolution;
|
||||
|
||||
public:
|
||||
int image_height, image_width;
|
||||
|
||||
CCamera();
|
||||
esp_err_t InitCam();
|
||||
|
||||
@@ -35,13 +38,13 @@ class CCamera {
|
||||
|
||||
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;
|
||||
|
||||
extern bool debug_detail_heap;
|
||||
|
||||
#endif
|
||||
@@ -29,26 +29,38 @@ void PowerResetCamera(){
|
||||
|
||||
esp_err_t handler_lightOn(httpd_req_t *req)
|
||||
{
|
||||
if (debug_detail_heap) LogFile.WriteHeapInfo("handler_lightOn - Start");
|
||||
|
||||
LogFile.WriteToFile("handler_lightOn");
|
||||
printf("handler_lightOn uri:\n"); printf(req->uri); printf("\n");
|
||||
Camera.LightOnOff(true);
|
||||
const char* resp_str = (const char*) req->user_ctx;
|
||||
httpd_resp_send(req, resp_str, strlen(resp_str));
|
||||
|
||||
if (debug_detail_heap) LogFile.WriteHeapInfo("handler_lightOn - Done");
|
||||
|
||||
return ESP_OK;
|
||||
};
|
||||
|
||||
esp_err_t handler_lightOff(httpd_req_t *req)
|
||||
{
|
||||
if (debug_detail_heap) LogFile.WriteHeapInfo("handler_lightOff - Start");
|
||||
|
||||
LogFile.WriteToFile("handler_lightOff");
|
||||
printf("handler_lightOff uri:\n"); printf(req->uri); printf("\n");
|
||||
Camera.LightOnOff(false);
|
||||
const char* resp_str = (const char*) req->user_ctx;
|
||||
httpd_resp_send(req, resp_str, strlen(resp_str));
|
||||
|
||||
if (debug_detail_heap) LogFile.WriteHeapInfo("handler_lightOff - Done");
|
||||
|
||||
return ESP_OK;
|
||||
};
|
||||
|
||||
esp_err_t handler_capture(httpd_req_t *req)
|
||||
{
|
||||
if (debug_detail_heap) LogFile.WriteHeapInfo("handler_capture - Start");
|
||||
|
||||
LogFile.WriteToFile("handler_capture");
|
||||
int quality;
|
||||
framesize_t res;
|
||||
@@ -59,12 +71,17 @@ esp_err_t handler_capture(httpd_req_t *req)
|
||||
|
||||
esp_err_t ressult;
|
||||
ressult = Camera.CaptureToHTTP(req);
|
||||
|
||||
if (debug_detail_heap) LogFile.WriteHeapInfo("handler_capture - Done");
|
||||
|
||||
return ressult;
|
||||
};
|
||||
|
||||
|
||||
esp_err_t handler_capture_with_ligth(httpd_req_t *req)
|
||||
{
|
||||
if (debug_detail_heap) LogFile.WriteHeapInfo("handler_capture_with_ligth - Start");
|
||||
|
||||
LogFile.WriteToFile("handler_capture_with_ligth");
|
||||
char _query[100];
|
||||
char _delay[10];
|
||||
@@ -99,6 +116,8 @@ esp_err_t handler_capture_with_ligth(httpd_req_t *req)
|
||||
|
||||
Camera.LightOnOff(false);
|
||||
|
||||
if (debug_detail_heap) LogFile.WriteHeapInfo("handler_capture_with_ligth - Done");
|
||||
|
||||
return ressult;
|
||||
};
|
||||
|
||||
@@ -106,6 +125,8 @@ esp_err_t handler_capture_with_ligth(httpd_req_t *req)
|
||||
|
||||
esp_err_t handler_capture_save_to_file(httpd_req_t *req)
|
||||
{
|
||||
if (debug_detail_heap) LogFile.WriteHeapInfo("handler_capture_save_to_file - Start");
|
||||
|
||||
LogFile.WriteToFile("handler_capture_save_to_file");
|
||||
char _query[100];
|
||||
char _delay[10];
|
||||
@@ -151,6 +172,8 @@ 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));
|
||||
|
||||
if (debug_detail_heap) LogFile.WriteHeapInfo("handler_capture_save_to_file - Done");
|
||||
|
||||
return ressult;
|
||||
};
|
||||
|
||||
|
||||
@@ -13,4 +13,7 @@ void register_server_camera_uri(httpd_handle_t server);
|
||||
|
||||
void PowerResetCamera();
|
||||
|
||||
|
||||
extern bool debug_detail_heap;
|
||||
|
||||
#endif
|
||||
@@ -25,7 +25,7 @@ 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 = OpenFileAndWait(filename.c_str(), "r");
|
||||
if (!fd) {
|
||||
@@ -35,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 */
|
||||
@@ -67,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);
|
||||
@@ -303,6 +303,8 @@ void CheckOTAUpdate(void)
|
||||
|
||||
esp_err_t handler_ota_update(httpd_req_t *req)
|
||||
{
|
||||
if (debug_detail_heap) LogFile.WriteHeapInfo("handler_ota_update - Start");
|
||||
|
||||
LogFile.WriteToFile("handler_ota_update");
|
||||
char _query[200];
|
||||
char _filename[30];
|
||||
@@ -379,6 +381,8 @@ esp_err_t handler_ota_update(httpd_req_t *req)
|
||||
|
||||
httpd_resp_send(req, resp_str, strlen(resp_str));
|
||||
|
||||
if (debug_detail_heap) LogFile.WriteHeapInfo("handler_ota_update - Done");
|
||||
|
||||
return ESP_OK;
|
||||
};
|
||||
|
||||
@@ -414,6 +418,8 @@ void doReboot(){
|
||||
|
||||
esp_err_t handler_reboot(httpd_req_t *req)
|
||||
{
|
||||
if (debug_detail_heap) LogFile.WriteHeapInfo("handler_reboot - Start");
|
||||
|
||||
LogFile.WriteToFile("handler_reboot");
|
||||
ESP_LOGI(TAGPARTOTA, "!!! System will restart within 5 sec!!!");
|
||||
const char* resp_str = "!!! System will restart within 5 sec!!!";
|
||||
@@ -421,6 +427,7 @@ esp_err_t handler_reboot(httpd_req_t *req)
|
||||
|
||||
doReboot();
|
||||
|
||||
if (debug_detail_heap) LogFile.WriteHeapInfo("handler_reboot - Done");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,3 +9,5 @@ static const char *TAGPARTOTA = "server_ota";
|
||||
void register_server_ota_sdcard_uri(httpd_handle_t server);
|
||||
void CheckOTAUpdate();
|
||||
void doReboot();
|
||||
|
||||
extern bool debug_detail_heap;
|
||||
@@ -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)
|
||||
|
||||
|
||||
|
||||
@@ -9,9 +9,11 @@
|
||||
void ClassFlow::SetInitialParameter(void)
|
||||
{
|
||||
ListFlowControll = NULL;
|
||||
previousElement = NULL;
|
||||
}
|
||||
|
||||
//std::vector<string> ClassFlow::ZerlegeZeile(std::string input, std::string delimiter);
|
||||
|
||||
|
||||
|
||||
std::vector<string> ClassFlow::ZerlegeZeile(std::string input, std::string delimiter)
|
||||
{
|
||||
@@ -55,7 +57,6 @@ bool ClassFlow::GetNextParagraph(FILE* pfile, string& aktparamgraph)
|
||||
ClassFlow::ClassFlow(void)
|
||||
{
|
||||
SetInitialParameter();
|
||||
ListFlowControll = NULL;
|
||||
}
|
||||
|
||||
ClassFlow::ClassFlow(std::vector<ClassFlow*> * lfc)
|
||||
@@ -64,6 +65,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 +108,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)) // Kommentarzeilen (; oder #) und Leerzeilen überspringen
|
||||
{
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
@@ -30,12 +33,15 @@ protected:
|
||||
bool getNextLine(FILE* pfile, string* rt);
|
||||
|
||||
std::vector<ClassFlow*>* ListFlowControll;
|
||||
ClassFlow *previousElement;
|
||||
|
||||
virtual void SetInitialParameter(void);
|
||||
|
||||
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,29 +1,55 @@
|
||||
#include "ClassFlowAlignment.h"
|
||||
#include "ClassFlowMakeImage.h"
|
||||
#include "ClassFlow.h"
|
||||
|
||||
#include "CRotateImage.h"
|
||||
|
||||
#include "ClassLogFile.h"
|
||||
|
||||
ClassFlowAlignment::ClassFlowAlignment()
|
||||
|
||||
|
||||
bool AlignmentExtendedDebugging = true;
|
||||
|
||||
|
||||
void ClassFlowAlignment::SetInitialParameter(void)
|
||||
{
|
||||
initalrotate = 0;
|
||||
anz_ref = 0;
|
||||
suchex = 40;
|
||||
suchey = 40;
|
||||
initialmirror = false;
|
||||
SaveAllFiles = false;
|
||||
namerawimage = "/sdcard/img_tmp/raw.jpg";
|
||||
ListFlowControll = NULL;
|
||||
AlignAndCutImage = NULL;
|
||||
ImageBasis = NULL;
|
||||
ImageTMP = NULL;
|
||||
previousElement = NULL;
|
||||
ref_dx[0] = 0; ref_dx[1] = 0;
|
||||
ref_dy[0] = 0; ref_dy[1] = 0;
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -59,11 +85,18 @@ bool ClassFlowAlignment::ReadParameter(FILE* pfile, string& aktparamgraph)
|
||||
}
|
||||
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]);
|
||||
reffilename[anz_ref] = FormatFileName("/sdcard" + zerlegt[0]);
|
||||
ref_x[anz_ref] = std::stod(zerlegt[1]);
|
||||
ref_y[anz_ref] = std::stod(zerlegt[2]);
|
||||
anz_ref++;
|
||||
}
|
||||
|
||||
if ((toUpper(zerlegt[0]) == "SAVEALLFILES") && (zerlegt.size() > 1))
|
||||
{
|
||||
if (toUpper(zerlegt[1]) == "TRUE")
|
||||
SaveAllFiles = true;
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -82,70 +115,50 @@ 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(initalrotate);
|
||||
if (SaveAllFiles) AlignAndCutImage->SaveToFile(FormatFileName("/sdcard/img_tmp/rot.jpg"));
|
||||
}
|
||||
rt->Rotate(this->initalrotate);
|
||||
rt->SaveToFile(output);
|
||||
delete rt;
|
||||
}
|
||||
else
|
||||
|
||||
AlignAndCutImage->Align(reffilename[0], ref_x[0], ref_y[0], reffilename[1], ref_x[1], ref_y[1], suchex, suchey, "");
|
||||
AlignAndCutImage->GetRefSize(ref_dx, ref_dy);
|
||||
if (SaveAllFiles) AlignAndCutImage->SaveToFile(FormatFileName("/sdcard/img_tmp/alg.jpg"));
|
||||
|
||||
if (SaveAllFiles)
|
||||
{
|
||||
CopyFile(input, output);
|
||||
DrawRef(ImageTMP);
|
||||
ImageTMP->SaveToFile(FormatFileName("/sdcard/img_tmp/alg_roi.jpg"));
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
printf("Startwriting Output4:%s\n", output4.c_str());
|
||||
if (output4.length() > 0)
|
||||
if (ImageTMP) // nuss gelöscht werden, um Speicherplatz für das Laden von tflite zu haben
|
||||
{
|
||||
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());
|
||||
delete ImageTMP;
|
||||
ImageTMP = NULL;
|
||||
}
|
||||
|
||||
delete caic;
|
||||
|
||||
// Align mit Templates
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void ClassFlowAlignment::DrawRef(CImageBasis *_zw)
|
||||
{
|
||||
_zw->drawRect(ref_x[0], ref_y[0], ref_dx[0], ref_dy[0], 255, 0, 0, 2);
|
||||
_zw->drawRect(ref_x[1], ref_y[1], ref_dx[1], ref_dy[1], 255, 0, 0, 2);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "ClassFlow.h"
|
||||
#include "Helper.h"
|
||||
#include "CAlignAndCutImage.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
@@ -15,13 +16,24 @@ protected:
|
||||
bool initialmirror;
|
||||
string reffilename[2];
|
||||
int ref_x[2], ref_y[2];
|
||||
int ref_dx[2], ref_dy[2];
|
||||
int anz_ref;
|
||||
int suchex, suchey;
|
||||
string namerawimage;
|
||||
bool SaveAllFiles;
|
||||
CAlignAndCutImage *AlignAndCutImage;
|
||||
|
||||
void SetInitialParameter(void);
|
||||
|
||||
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,21 +16,30 @@ 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;
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
string ClassFlowAnalog::getReadout()
|
||||
@@ -113,9 +122,24 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -162,77 +186,35 @@ 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);
|
||||
|
||||
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"));
|
||||
|
||||
ROI[i]->image_org->Resize(modelxsize, modelysize, ROI[i]->image);
|
||||
if (SaveAllFiles) ROI[i]->image->SaveToFile(FormatFileName("/sdcard/img_tmp/" + ROI[i]->name + ".bmp"));
|
||||
}
|
||||
|
||||
rs->Resize(modelxsize, modelysize);
|
||||
ioresize = "/sdcard/img_tmp/ra" + std::to_string(i) + ".bmp";
|
||||
ioresize = FormatFileName(ioresize);
|
||||
rs->SaveToFile(ioresize);
|
||||
delete rs;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (img_roi)
|
||||
{
|
||||
void ClassFlowAnalog::DrawROI(CImageBasis *_zw)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
delete caic;
|
||||
|
||||
|
||||
if (img_roi)
|
||||
for (int i = 0; i < ROI.size(); ++i)
|
||||
{
|
||||
img_roi->SaveToFile(input_roi);
|
||||
delete img_roi;
|
||||
_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);
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ClassFlowAnalog::doNeuralNetwork(string time)
|
||||
@@ -265,7 +247,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 +263,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;
|
||||
|
||||
@@ -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,15 +19,22 @@ protected:
|
||||
string cnnmodelfile;
|
||||
int modelxsize, modelysize;
|
||||
int ZeigerEval(float zahl, int ziffer_vorgaenger);
|
||||
bool SaveAllFiles;
|
||||
|
||||
ClassFlowAlignment* flowpostalignment;
|
||||
|
||||
void SetInitialParameter(void);
|
||||
|
||||
public:
|
||||
ClassFlowAnalog();
|
||||
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();
|
||||
|
||||
@@ -9,8 +9,11 @@
|
||||
#include "Helper.h"
|
||||
#include "server_ota.h"
|
||||
|
||||
#include "server_help.h"
|
||||
|
||||
static const char* TAG = "flow_controll";
|
||||
|
||||
|
||||
std::string ClassFlowControll::doSingleStep(std::string _stepname, std::string _host){
|
||||
std::string _classname = "";
|
||||
std::string result = "";
|
||||
@@ -68,6 +71,9 @@ void ClassFlowControll::SetInitialParameter(void)
|
||||
AutoStart = false;
|
||||
SetupModeActive = false;
|
||||
AutoIntervall = 10;
|
||||
flowdigit = NULL;
|
||||
flowanalog = NULL;
|
||||
flowpostprocessing = NULL;
|
||||
}
|
||||
|
||||
bool ClassFlowControll::isAutoStart(long &_intervall)
|
||||
@@ -83,13 +89,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)
|
||||
@@ -139,6 +157,7 @@ void ClassFlowControll::InitFlow(std::string config)
|
||||
cfc = CreateClassFlow(line);
|
||||
if (cfc)
|
||||
{
|
||||
printf("Start ReadParameter\n");
|
||||
cfc->ReadParameter(pFile, line);
|
||||
}
|
||||
else
|
||||
@@ -158,9 +177,7 @@ std::string ClassFlowControll::getActStatus(){
|
||||
}
|
||||
|
||||
void ClassFlowControll::doFlowMakeImageOnly(string time){
|
||||
bool result = true;
|
||||
std::string zw_time;
|
||||
int repeat = 0;
|
||||
|
||||
for (int i = 0; i < FlowControll.size(); ++i)
|
||||
{
|
||||
@@ -181,12 +198,18 @@ bool ClassFlowControll::doFlow(string time)
|
||||
std::string zw_time;
|
||||
int repeat = 0;
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
if (debug_detail_heap) LogFile.WriteHeapInfo("ClassFlowAnalog::doFlow - Start");
|
||||
/////////////////////////////////////////////////////////
|
||||
|
||||
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);
|
||||
if (debug_detail_heap) LogFile.WriteHeapInfo(zw);
|
||||
// LogFile.WriteToFile(zw);
|
||||
if (!FlowControll[i]->doFlow(time)){
|
||||
repeat++;
|
||||
LogFile.WriteToFile("Fehler im vorheriger Schritt - wird zum " + to_string(repeat) + ". Mal wiederholt");
|
||||
@@ -202,6 +225,8 @@ bool ClassFlowControll::doFlow(string time)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
if (debug_detail_heap) LogFile.WriteHeapInfo("ClassFlowAnalog::doFlow");
|
||||
}
|
||||
zw_time = gettimestring("%Y%m%d-%H%M%S");
|
||||
aktstatus = zw_time + ": Flow is done";
|
||||
@@ -320,6 +345,14 @@ bool ClassFlowControll::ReadParameter(FILE* pfile, string& aktparamgraph)
|
||||
setTimeZone(zerlegt[1]);
|
||||
}
|
||||
|
||||
if ((toUpper(zerlegt[0]) == "TIMESERVER") && (zerlegt.size() > 1))
|
||||
{
|
||||
string zw = "Set TimeZone: " + zerlegt[1];
|
||||
reset_servername(zerlegt[1]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ((toUpper(zerlegt[0]) == "SETUPMODE") && (zerlegt.size() > 1))
|
||||
{
|
||||
if (toUpper(zerlegt[1]) == "TRUE")
|
||||
@@ -363,3 +396,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,6 +17,10 @@ class ClassFlowControll :
|
||||
protected:
|
||||
std::vector<ClassFlow*> FlowControll;
|
||||
ClassFlowPostProcessing* flowpostprocessing;
|
||||
ClassFlowAlignment* flowalignment;
|
||||
ClassFlowAnalog* flowanalog;
|
||||
ClassFlowDigit* flowdigit;
|
||||
ClassFlowMakeImage* flowmakeimage;
|
||||
ClassFlow* CreateClassFlow(std::string _type);
|
||||
|
||||
bool AutoStart;
|
||||
@@ -35,6 +39,9 @@ public:
|
||||
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);
|
||||
@@ -49,3 +56,5 @@ public:
|
||||
string name(){return "ClassFlowControll";};
|
||||
};
|
||||
|
||||
extern bool debug_detail_heap;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "ClassFlowDigit.h"
|
||||
|
||||
|
||||
//#include "CFindTemplate.h"
|
||||
//#include "CTfLiteClass.h"
|
||||
|
||||
@@ -15,19 +16,49 @@
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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()
|
||||
@@ -85,9 +116,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;
|
||||
}
|
||||
|
||||
@@ -133,60 +180,17 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
@@ -196,17 +200,9 @@ bool ClassFlowDigit::doNeuralNetwork(string time)
|
||||
{
|
||||
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 +211,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 +230,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 +243,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,6 +5,7 @@
|
||||
#include <dirent.h>
|
||||
#include "time_sntp.h"
|
||||
#include "ClassLogFile.h"
|
||||
#include "CImageBasis.h"
|
||||
|
||||
ClassFlowImage::ClassFlowImage(const char* logTag)
|
||||
{
|
||||
@@ -12,12 +13,19 @@ ClassFlowImage::ClassFlowImage(const char* logTag)
|
||||
isLogImage = 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;
|
||||
}
|
||||
|
||||
ClassFlowImage::ClassFlowImage(std::vector<ClassFlow*> * lfc, ClassFlow *_prev, const char* logTag) : ClassFlow(lfc, _prev)
|
||||
{
|
||||
this->logTag = logTag;
|
||||
isLogImage = false;
|
||||
}
|
||||
|
||||
|
||||
string ClassFlowImage::CreateLogFolder(string time) {
|
||||
if (!isLogImage)
|
||||
return "";
|
||||
@@ -32,7 +40,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 +58,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,34 @@ ClassFlowMQTT::ClassFlowMQTT()
|
||||
flowpostprocessing = NULL;
|
||||
user = "";
|
||||
password = "";
|
||||
previousElement = NULL;
|
||||
ListFlowControll = NULL;
|
||||
}
|
||||
|
||||
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 +53,9 @@ ClassFlowMQTT::ClassFlowMQTT(std::vector<ClassFlow*>* lfc)
|
||||
flowpostprocessing = (ClassFlowPostProcessing*) (*ListFlowControll)[i];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool ClassFlowMQTT::ReadParameter(FILE* pfile, string& aktparamgraph)
|
||||
{
|
||||
std::vector<string> zerlegt;
|
||||
|
||||
@@ -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,7 +1,8 @@
|
||||
#include "ClassFlowMakeImage.h"
|
||||
#include "Helper.h"
|
||||
#include "ClassLogFile.h"
|
||||
|
||||
#include "CFindTemplate.h"
|
||||
#include "CImageBasis.h"
|
||||
#include "ClassControllCamera.h"
|
||||
|
||||
#include <time.h>
|
||||
@@ -16,30 +17,27 @@ 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;
|
||||
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 +62,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 +96,49 @@ 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;
|
||||
|
||||
if (debug_detail_heap) LogFile.WriteHeapInfo("ClassFlowMakeImage::doFlow - Before takePictureWithFlash");
|
||||
|
||||
takePictureWithFlash(flashdauer);
|
||||
time(&TimeImageTaken);
|
||||
localtime(&TimeImageTaken);
|
||||
|
||||
LogImage(logPath, "raw", NULL, NULL, zwtime);
|
||||
if (debug_detail_heap) LogFile.WriteHeapInfo("ClassFlowMakeImage::doFlow - After takePictureWithFlash");
|
||||
|
||||
LogImage(logPath, "raw", NULL, NULL, zwtime, rawImage);
|
||||
|
||||
RemoveOldLogs();
|
||||
if (debug_detail_heap) LogFile.WriteHeapInfo("ClassFlowMakeImage::doFlow - After RemoveOldLogs");
|
||||
|
||||
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,34 @@ 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);
|
||||
};
|
||||
|
||||
|
||||
extern bool debug_detail_heap;
|
||||
|
||||
|
||||
@@ -18,6 +18,64 @@
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -10,7 +10,7 @@ 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 = 10);
|
||||
FILE* OpenFileAndWait(const char* nm, char* _mode, int _waitsec = 1);
|
||||
|
||||
size_t findDelimiterPos(string input, string delimiter);
|
||||
//string trim(string istring);
|
||||
@@ -27,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();
|
||||
|
||||
/////////////////////////////
|
||||
|
||||
192
code/components/jomjol_image_proc/CAlignAndCutImage.cpp
Normal file
192
code/components/jomjol_image_proc/CAlignAndCutImage.cpp
Normal file
@@ -0,0 +1,192 @@
|
||||
#include "CAlignAndCutImage.h"
|
||||
#include "CRotateImage.h"
|
||||
#include "CFindTemplate.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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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(filename);
|
||||
CFindTemplate* ft = new CFindTemplate(rgb_image, channels, width, height, bpp);
|
||||
|
||||
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;
|
||||
|
||||
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
std::string zw = "\tdx:\t" + std::to_string(dx) + "\tdy:\t" + std::to_string(dy) + "\td_winkel:\t" + std::to_string(d_winkel);
|
||||
// LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", zw);
|
||||
|
||||
CRotateImage rt(this, ImageTMP);
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
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->rgb_image;
|
||||
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
rs->SetIndepended();
|
||||
return rs;
|
||||
}
|
||||
18
code/components/jomjol_image_proc/CAlignAndCutImage.h
Normal file
18
code/components/jomjol_image_proc/CAlignAndCutImage.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#include "CImageBasis.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);
|
||||
|
||||
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,197 +1,26 @@
|
||||
#include "CFindTemplate.h"
|
||||
#include "Helper.h"
|
||||
#include "ClassLogFile.h"
|
||||
|
||||
#include "esp_system.h"
|
||||
|
||||
#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)
|
||||
{
|
||||
CImageBasis::CImageBasis(_image);
|
||||
}
|
||||
*/
|
||||
|
||||
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);
|
||||
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);
|
||||
uint8_t* rgb_template = stbi_load(_template.c_str(), &tpl_width, &tpl_height, &tpl_bpp, channels);
|
||||
|
||||
int ow, ow_start, ow_stop;
|
||||
int oh, oh_start, oh_stop;
|
||||
|
||||
if (_dx == 0)
|
||||
{
|
||||
_dx = this->width;
|
||||
_dx = width;
|
||||
*found_x = 0;
|
||||
}
|
||||
|
||||
if (_dy == 0)
|
||||
{
|
||||
_dy = this->height;
|
||||
_dy = height;
|
||||
*found_y = 0;
|
||||
}
|
||||
|
||||
@@ -199,18 +28,18 @@ void CFindTemplate::FindTemplate(std::string _template, int* found_x, int* found
|
||||
ow_start = *found_x - _dx;
|
||||
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;
|
||||
if ((ow_stop + tpl_width) > width)
|
||||
ow_stop = width - tpl_width;
|
||||
ow = ow_stop - ow_start + 1;
|
||||
|
||||
oh_start = *found_y - _dy;
|
||||
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;
|
||||
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);
|
||||
uint8_t* odata = (unsigned char*)GET_MEMORY(ow * oh * channels);
|
||||
|
||||
double aktSAD;
|
||||
double minSAD = pow(tpl_width * tpl_height * 255, 2);
|
||||
@@ -222,11 +51,11 @@ void CFindTemplate::FindTemplate(std::string _template, int* found_x, int* found
|
||||
for (int tpl_x = 0; tpl_x < tpl_width; tpl_x++)
|
||||
for (int tpl_y = 0; tpl_y < tpl_height; tpl_y++)
|
||||
{
|
||||
stbi_uc* p_org = 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));
|
||||
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));
|
||||
aktSAD += pow(p_tpl[0] - p_org[0], 2);
|
||||
}
|
||||
stbi_uc* p_out = odata + (this->channels * ((youter - oh_start) * ow + (xouter - ow_start)));
|
||||
stbi_uc* p_out = odata + (channels * ((youter - oh_start) * ow + (xouter - ow_start)));
|
||||
|
||||
p_out[0] = int(sqrt(aktSAD / (tpl_width * tpl_height)));
|
||||
if (aktSAD < minSAD)
|
||||
@@ -237,7 +66,7 @@ void CFindTemplate::FindTemplate(std::string _template, int* found_x, int* found
|
||||
}
|
||||
}
|
||||
|
||||
stbi_write_bmp("sdcard\\find.bmp", ow, oh, this->channels, odata);
|
||||
stbi_write_bmp("sdcard\\find.bmp", ow, oh, channels, odata);
|
||||
|
||||
stbi_image_free(odata);
|
||||
stbi_image_free(rgb_template);
|
||||
@@ -245,303 +74,14 @@ void CFindTemplate::FindTemplate(std::string _template, int* found_x, int* found
|
||||
|
||||
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);
|
||||
FindTemplate(_template, found_x, found_y);
|
||||
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);
|
||||
FindTemplate(_template, found_x, found_y, _dx, _dy);
|
||||
SaveToFile(_imageout);
|
||||
}
|
||||
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
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;
|
||||
|
||||
|
||||
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);
|
||||
LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", zw);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void CAlignAndCutImage::CutAndSave(std::string _template1, int x1, int y1, int dx, int dy)
|
||||
{
|
||||
|
||||
int x2, y2;
|
||||
|
||||
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)
|
||||
{
|
||||
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_write_jpg(_template1.c_str(), dx, dy, this->channels, odata, 0);
|
||||
stbi_write_bmp(_template1.c_str(), dx, dy, this->channels, odata);
|
||||
|
||||
stbi_image_free(odata);
|
||||
}
|
||||
|
||||
@@ -1,98 +1,16 @@
|
||||
#pragma once
|
||||
#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);
|
||||
};
|
||||
|
||||
class CFindTemplate : public CImageBasis
|
||||
{
|
||||
public:
|
||||
int tpl_width, tpl_height, tpl_bpp;
|
||||
CFindTemplate(std::string _image);
|
||||
// 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);
|
||||
};
|
||||
|
||||
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
|
||||
|
||||
|
||||
436
code/components/jomjol_image_proc/CImageBasis.cpp
Normal file
436
code/components/jomjol_image_proc/CImageBasis.cpp
Normal file
@@ -0,0 +1,436 @@
|
||||
#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";
|
||||
|
||||
|
||||
|
||||
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;
|
||||
|
||||
stbi_write_jpg_to_func(writejpghelp, ii, width, height, channels, rgb_image, quality);
|
||||
|
||||
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;
|
||||
|
||||
stbi_write_jpg_to_func(writejpgtohttphelp, &ii, width, height, channels, rgb_image, quality);
|
||||
|
||||
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;
|
||||
}
|
||||
memCopy(_source, rgb_image, _size);
|
||||
|
||||
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;
|
||||
|
||||
p_source = rgb_image + (channels * (y * width + x));
|
||||
p_source[0] = r;
|
||||
if ( 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()
|
||||
{
|
||||
externalImage = false;
|
||||
}
|
||||
|
||||
void CImageBasis::CreateEmptyImage(int _width, int _height, int _channels)
|
||||
{
|
||||
bpp = _channels;
|
||||
width = _width;
|
||||
height = _height;
|
||||
channels = _channels;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void CImageBasis::LoadFromMemory(stbi_uc *_buffer, int len)
|
||||
{
|
||||
// if (rgb_image)
|
||||
// free(rgb_image);
|
||||
rgb_image = stbi_load_from_memory(_buffer, len, &width, &height, &channels, 3);
|
||||
bpp = channels;
|
||||
// STBIDEF stbi_uc *stbi_load_from_memory (stbi_uc const *buffer, int len , int *x, int *y, int *channels_in_file, int desired_channels);
|
||||
|
||||
}
|
||||
|
||||
CImageBasis::CImageBasis(CImageBasis *_copyfrom, int _anzrepeat)
|
||||
{
|
||||
externalImage = false;
|
||||
channels = _copyfrom->channels;
|
||||
width = _copyfrom->width;
|
||||
height = _copyfrom->height;
|
||||
bpp = _copyfrom->bpp;
|
||||
|
||||
int memsize = width * height * channels;
|
||||
rgb_image = (unsigned char*)GET_MEMORY(memsize);
|
||||
|
||||
int anz = 1;
|
||||
TickType_t xDelay;
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
||||
memCopy(_copyfrom->rgb_image, rgb_image, memsize);
|
||||
}
|
||||
|
||||
CImageBasis::CImageBasis(int _width, int _height, int _channels)
|
||||
{
|
||||
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)
|
||||
{
|
||||
channels = 3;
|
||||
externalImage = false;
|
||||
filename = _image;
|
||||
long zwld = esp_get_free_heap_size();
|
||||
printf("freeheapsize before: %ld\n", zwld);
|
||||
|
||||
rgb_image = stbi_load(_image.c_str(), &width, &height, &bpp, channels);
|
||||
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)
|
||||
{
|
||||
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);
|
||||
|
||||
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)));
|
||||
}
|
||||
}
|
||||
|
||||
CImageBasis::~CImageBasis()
|
||||
{
|
||||
if (!externalImage)
|
||||
stbi_image_free(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(), width, height, channels, rgb_image, 0);
|
||||
}
|
||||
|
||||
if ((typ == "bmp") || (typ == "BMP"))
|
||||
{
|
||||
stbi_write_bmp(_imageout.c_str(), width, height, channels, rgb_image);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CImageBasis::Resize(int _new_dx, int _new_dy)
|
||||
{
|
||||
int memsize = _new_dx * _new_dy * channels;
|
||||
uint8_t* odata = (unsigned char*)GET_MEMORY(memsize);
|
||||
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
uint8_t* odata = _target->rgb_image;
|
||||
stbir_resize_uint8(rgb_image, width, height, 0, odata, _new_dx, _new_dy, 0, channels);
|
||||
}
|
||||
|
||||
88
code/components/jomjol_image_proc/CImageBasis.h
Normal file
88
code/components/jomjol_image_proc/CImageBasis.h
Normal file
@@ -0,0 +1,88 @@
|
||||
#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);
|
||||
|
||||
public:
|
||||
uint8_t* rgb_image;
|
||||
int channels;
|
||||
int width, height, bpp;
|
||||
|
||||
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)
|
||||
|
||||
|
||||
|
||||
171
code/components/jomjol_image_proc/CRotateImage.cpp
Normal file
171
code/components/jomjol_image_proc/CRotateImage.cpp
Normal file
@@ -0,0 +1,171 @@
|
||||
#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;
|
||||
}
|
||||
|
||||
void CRotateImage::Mirror(){
|
||||
int memsize = width * height * channels;
|
||||
uint8_t* odata;
|
||||
if (ImageTMP)
|
||||
{
|
||||
odata = ImageTMP->rgb_image;
|
||||
}
|
||||
else
|
||||
{
|
||||
odata = (unsigned char*)GET_MEMORY(memsize);
|
||||
}
|
||||
|
||||
|
||||
int x_source, y_source;
|
||||
stbi_uc* p_target;
|
||||
stbi_uc* p_source;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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->rgb_image;
|
||||
}
|
||||
else
|
||||
{
|
||||
odata = (unsigned char*)GET_MEMORY(memsize);
|
||||
}
|
||||
|
||||
|
||||
int x_source, y_source;
|
||||
stbi_uc* p_target;
|
||||
stbi_uc* p_source;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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->rgb_image;
|
||||
}
|
||||
else
|
||||
{
|
||||
odata = (unsigned char*)GET_MEMORY(memsize);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int x_source, y_source;
|
||||
stbi_uc* p_target;
|
||||
stbi_uc* p_source;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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,48 @@ static const char *TAG = "log";
|
||||
|
||||
ClassLogFile LogFile("/sdcard/log/message", "log_%Y-%m-%d.txt");
|
||||
|
||||
void ClassLogFile::WriteHeapInfo(std::string _id)
|
||||
{
|
||||
std::string _zw;
|
||||
_zw = "\t" + _id + "\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 +61,9 @@ void ClassLogFile::WriteToDedicatedFile(std::string _fn, std::string info, bool
|
||||
return;
|
||||
}
|
||||
|
||||
pFile = OpenFileAndWait(_fn.c_str(), "a+");
|
||||
// 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)
|
||||
@@ -55,6 +99,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());
|
||||
@@ -62,7 +107,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];
|
||||
@@ -80,12 +125,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;
|
||||
|
||||
@@ -12,6 +12,10 @@ private:
|
||||
public:
|
||||
ClassLogFile(std::string _logpath, std::string _logfile);
|
||||
|
||||
std::string getESPHeapInfo();
|
||||
|
||||
void WriteHeapInfo(std::string _id);
|
||||
|
||||
void SwitchOnOff(bool _doLogFile);
|
||||
void SetRetention(unsigned short _retentionInDays);
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
#include "CTfLiteClass.h"
|
||||
|
||||
#include "bitmap_image.hpp"
|
||||
// #include "bitmap_image.hpp"
|
||||
|
||||
#include "ClassLogFile.h"
|
||||
|
||||
#include "Helper.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
@@ -21,19 +20,16 @@ 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());
|
||||
printf("After Invoke \n");
|
||||
|
||||
return GetOutClassification();
|
||||
// return 0;
|
||||
}
|
||||
|
||||
int CTfLiteClass::GetOutClassification()
|
||||
@@ -113,17 +109,14 @@ void CTfLiteClass::Invoke()
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
@@ -132,18 +125,15 @@ 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");
|
||||
@@ -154,7 +144,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);
|
||||
|
||||
@@ -164,7 +153,6 @@ void CTfLiteClass::MakeAllocate()
|
||||
this->GetInputDimension();
|
||||
return;
|
||||
}
|
||||
|
||||
// printf("Allocate Done.\n");
|
||||
}
|
||||
|
||||
@@ -172,8 +160,6 @@ void CTfLiteClass::GetInputTensorSize(){
|
||||
float *zw = this->input;
|
||||
int test = sizeof(zw);
|
||||
printf("Input Tensor Dimension: %d\n", test);
|
||||
|
||||
printf("Input Tensor Dimension: %d\n", test);
|
||||
}
|
||||
|
||||
long CTfLiteClass::GetFileSize(std::string filename)
|
||||
@@ -188,7 +174,7 @@ unsigned char* CTfLiteClass::ReadFileToCharArray(std::string _fn)
|
||||
{
|
||||
long size;
|
||||
|
||||
size = this->GetFileSize(_fn);
|
||||
size = GetFileSize(_fn);
|
||||
|
||||
if (size == -1)
|
||||
{
|
||||
@@ -196,8 +182,17 @@ unsigned char* CTfLiteClass::ReadFileToCharArray(std::string _fn)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
unsigned char *result = (unsigned char*) malloc(size);
|
||||
int anz = 1;
|
||||
TickType_t xDelay;
|
||||
while (!result && (anz < 6)) // maximal 5x versuchen (= 5s)
|
||||
{
|
||||
printf("Speicher ist voll - Versuche es erneut: %d.\n", anz);
|
||||
xDelay = 1000 / portTICK_PERIOD_MS;
|
||||
result = (unsigned char*) malloc(size);
|
||||
anz++;
|
||||
}
|
||||
|
||||
|
||||
if(result != NULL) {
|
||||
// printf("\nSpeicher ist reserviert\n");
|
||||
@@ -221,14 +216,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");
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -239,7 +231,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];
|
||||
}
|
||||
|
||||
@@ -257,6 +249,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);
|
||||
|
||||
@@ -24,11 +24,32 @@ 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;
|
||||
@@ -91,6 +112,8 @@ void blink_task_doFlow(void *pvParameter)
|
||||
|
||||
esp_err_t handler_init(httpd_req_t *req)
|
||||
{
|
||||
if (debug_detail_heap) LogFile.WriteHeapInfo("handler_init - Start");
|
||||
|
||||
LogFile.WriteToFile("handler_init");
|
||||
printf("handler_doinit uri:\n"); printf(req->uri); printf("\n");
|
||||
|
||||
@@ -104,11 +127,15 @@ 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);
|
||||
|
||||
if (debug_detail_heap) LogFile.WriteHeapInfo("handler_init - Done");
|
||||
|
||||
return ESP_OK;
|
||||
};
|
||||
|
||||
esp_err_t handler_doflow(httpd_req_t *req)
|
||||
{
|
||||
if (debug_detail_heap) LogFile.WriteHeapInfo("handler_doflow - Start");
|
||||
|
||||
LogFile.WriteToFile("handler_doflow");
|
||||
char* resp_str;
|
||||
|
||||
@@ -128,6 +155,8 @@ 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);
|
||||
if (debug_detail_heap) LogFile.WriteHeapInfo("handler_doflow - Done");
|
||||
|
||||
return ESP_OK;
|
||||
};
|
||||
|
||||
@@ -136,6 +165,8 @@ esp_err_t handler_doflow(httpd_req_t *req)
|
||||
|
||||
esp_err_t handler_wasserzaehler(httpd_req_t *req)
|
||||
{
|
||||
if (debug_detail_heap) LogFile.WriteHeapInfo("handler_wasserzaehler - Start");
|
||||
|
||||
LogFile.WriteToFile("handler_wasserzaehler");
|
||||
bool _rawValue = false;
|
||||
bool _noerror = false;
|
||||
@@ -171,7 +202,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());
|
||||
|
||||
@@ -217,12 +248,15 @@ 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);
|
||||
|
||||
if (debug_detail_heap) LogFile.WriteHeapInfo("handler_wasserzaehler - Done");
|
||||
|
||||
return ESP_OK;
|
||||
};
|
||||
|
||||
|
||||
esp_err_t handler_editflow(httpd_req_t *req)
|
||||
{
|
||||
if (debug_detail_heap) LogFile.WriteHeapInfo("handler_editflow - Start");
|
||||
LogFile.WriteToFile("handler_editflow");
|
||||
|
||||
printf("handler_editflow uri: "); printf(req->uri); printf("\n");
|
||||
@@ -324,6 +358,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)
|
||||
@@ -378,6 +413,7 @@ 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);
|
||||
if (debug_detail_heap) LogFile.WriteHeapInfo("handler_editflow - Done");
|
||||
|
||||
return ESP_OK;
|
||||
};
|
||||
@@ -385,6 +421,8 @@ esp_err_t handler_editflow(httpd_req_t *req)
|
||||
|
||||
esp_err_t handler_prevalue(httpd_req_t *req)
|
||||
{
|
||||
if (debug_detail_heap) LogFile.WriteHeapInfo("handler_prevalue - Start");
|
||||
|
||||
LogFile.WriteToFile("handler_prevalue");
|
||||
const char* resp_str;
|
||||
string zw;
|
||||
@@ -414,6 +452,8 @@ 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);
|
||||
|
||||
if (debug_detail_heap) LogFile.WriteHeapInfo("handler_prevalue - Start");
|
||||
|
||||
return ESP_OK;
|
||||
};
|
||||
|
||||
@@ -434,7 +474,8 @@ void task_autodoFlow(void *pvParameter)
|
||||
|
||||
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();
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <esp_log.h>
|
||||
|
||||
#include <esp_http_server.h>
|
||||
#include "CImageBasis.h"
|
||||
|
||||
//#include "ClassControllCamera.h"
|
||||
|
||||
@@ -13,3 +14,9 @@ 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);
|
||||
|
||||
extern bool debug_detail_heap;
|
||||
@@ -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,25 +11,19 @@
|
||||
#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;
|
||||
|
||||
static void obtain_time(void);
|
||||
static void initialize_sntp(void);
|
||||
|
||||
|
||||
void time_sync_notification_cb(struct timeval *tv)
|
||||
{
|
||||
// LogFile.WriteToFile("Notification of a time synchronization event");
|
||||
ESP_LOGI(TAG, "Notification of a time synchronization event");
|
||||
}
|
||||
|
||||
@@ -54,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);
|
||||
@@ -72,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);
|
||||
@@ -97,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;
|
||||
@@ -110,18 +90,23 @@ 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");
|
||||
|
||||
@@ -16,3 +16,4 @@ void setup_time(void);
|
||||
|
||||
std::string gettimestring(const char * frm);
|
||||
void setTimeZone(std::string _tzstring);
|
||||
void reset_servername(std::string _servername);
|
||||
@@ -28,6 +28,9 @@
|
||||
|
||||
static const char *TAGMAIN = "connect_wlan_main";
|
||||
|
||||
|
||||
bool debug_detail_heap = false;
|
||||
|
||||
#define FLASH_GPIO GPIO_NUM_4
|
||||
|
||||
void Init_NVS_SDCard()
|
||||
@@ -44,10 +47,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) {
|
||||
@@ -116,7 +124,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");
|
||||
|
||||
@@ -18,13 +18,14 @@
|
||||
|
||||
httpd_handle_t server = NULL;
|
||||
|
||||
|
||||
std::string starttime = "";
|
||||
|
||||
|
||||
/* An HTTP GET handler */
|
||||
esp_err_t info_get_handler(httpd_req_t *req)
|
||||
{
|
||||
if (debug_detail_heap) LogFile.WriteHeapInfo("info_get_handler - Start");
|
||||
|
||||
LogFile.WriteToFile("info_get_handler");
|
||||
char _query[200];
|
||||
char _valuechar[30];
|
||||
@@ -125,25 +126,31 @@ esp_err_t info_get_handler(httpd_req_t *req)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
if (debug_detail_heap) LogFile.WriteHeapInfo("info_get_handler - Done");
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t starttime_get_handler(httpd_req_t *req)
|
||||
{
|
||||
if (debug_detail_heap) LogFile.WriteHeapInfo("starttime_get_handler - Start");
|
||||
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);
|
||||
|
||||
if (debug_detail_heap) LogFile.WriteHeapInfo("starttime_get_handler - Done");
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t hello_main_handler(httpd_req_t *req)
|
||||
{
|
||||
if (debug_detail_heap) LogFile.WriteHeapInfo("hello_main_handler - Start");
|
||||
|
||||
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);
|
||||
@@ -182,60 +189,35 @@ 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);
|
||||
|
||||
if (debug_detail_heap) LogFile.WriteHeapInfo("hello_main_handler - Stop");
|
||||
|
||||
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;
|
||||
|
||||
@@ -244,8 +226,47 @@ esp_err_t img_tmp_handler(httpd_req_t *req)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t img_tmp_virtual_handler(httpd_req_t *req)
|
||||
{
|
||||
if (debug_detail_heap) LogFile.WriteHeapInfo("img_tmp_virtual_handler - Start");
|
||||
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:
|
||||
if (debug_detail_heap) LogFile.WriteHeapInfo("img_tmp_virtual_handler - Done");
|
||||
|
||||
return img_tmp_handler(req);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
esp_err_t sysinfo_handler(httpd_req_t *req)
|
||||
{
|
||||
if (debug_detail_heap) LogFile.WriteHeapInfo("sysinfo_handler - Start");
|
||||
|
||||
const char* resp_str;
|
||||
std::string zw;
|
||||
std::string cputemp = std::to_string(temperatureRead());
|
||||
@@ -281,6 +302,8 @@ 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);
|
||||
|
||||
if (debug_detail_heap) LogFile.WriteHeapInfo("sysinfo_handler - Done");
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@@ -314,7 +337,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,7 @@ 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);
|
||||
extern bool debug_detail_heap;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const char* GIT_REV="793f928";
|
||||
const char* GIT_REV="6e521f0";
|
||||
const char* GIT_TAG="";
|
||||
const char* GIT_BRANCH="rolling";
|
||||
const char* BUILD_TIME="2020-12-07 20:40";
|
||||
const char* GIT_BRANCH="rolling-reduce-sd-use";
|
||||
const char* BUILD_TIME="2020-12-28 15:38";
|
||||
@@ -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=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 +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
|
||||
|
||||
@@ -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
|
||||
@@ -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=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 +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 +1,4 @@
|
||||
const char* GIT_REV="793f928";
|
||||
const char* GIT_REV="6e521f0";
|
||||
const char* GIT_TAG="";
|
||||
const char* GIT_BRANCH="rolling";
|
||||
const char* BUILD_TIME="2020-12-07 20:40";
|
||||
const char* GIT_BRANCH="rolling-reduce-sd-use";
|
||||
const char* BUILD_TIME="2020-12-28 15:38";
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -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%;">
|
||||
@@ -570,16 +570,16 @@ 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>
|
||||
</table>
|
||||
@@ -717,7 +717,7 @@ function UpdateInput() {
|
||||
WriteParameter(param, "Debug", "LogfileRetentionInDays", true);
|
||||
|
||||
WriteParameter(param, "System", "TimeZone", true);
|
||||
WriteParameter(param, "System", "TimeUpdateIntervall", true);
|
||||
WriteParameter(param, "System", "TimeServer", true);
|
||||
}
|
||||
|
||||
function WriteConfig(){
|
||||
@@ -762,7 +762,7 @@ function WriteConfig(){
|
||||
ReadParameter(param, "Debug", "LogfileRetentionInDays", true);
|
||||
|
||||
ReadParameter(param, "System", "TimeZone", true);
|
||||
ReadParameter(param, "System", "TimeUpdateIntervall", true);
|
||||
ReadParameter(param, "System", "TimeServer", true);
|
||||
|
||||
FormatDecimalValue(param, "PostProcessing", "MaxRateValue");
|
||||
|
||||
|
||||
@@ -87,7 +87,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();
|
||||
|
||||
@@ -72,8 +72,8 @@ function ParseConfig() {
|
||||
var catname = "System";
|
||||
param[catname] = new Object();
|
||||
ParamAddValue(param, catname, "TimeZone");
|
||||
ParamAddValue(param, catname, "TimeServer");
|
||||
ParamAddValue(param, catname, "AutoAdjustSummertime");
|
||||
ParamAddValue(param, catname, "TimeUpdateIntervall");
|
||||
ParamAddValue(param, catname, "SetupMode");
|
||||
|
||||
while (aktline < config_split.length){
|
||||
@@ -149,6 +149,7 @@ function ParseConfigParamSystem(_aktline){
|
||||
var linesplit = ZerlegeZeile(input, " =");
|
||||
|
||||
ParamExtractValue(param, linesplit, catname, "TimeZone", _aktline, isCom);
|
||||
ParamExtractValue(param, linesplit, catname, "TimeServer", _aktline, isCom);
|
||||
ParamExtractValue(param, linesplit, catname, "AutoAdjustSummertime", _aktline, isCom);
|
||||
ParamExtractValue(param, linesplit, catname, "TimeUpdateIntervall", _aktline, isCom);
|
||||
ParamExtractValue(param, linesplit, catname, "SetupMode", _aktline, isCom);
|
||||
|
||||
@@ -1 +1 @@
|
||||
3.0.0
|
||||
4.0.0
|
||||
|
||||
Reference in New Issue
Block a user