Merge pull request #75 from jomjol/rolling-reduce-sd-use

Update with reduced SD card usage
This commit is contained in:
jomjol
2020-12-28 16:27:29 +01:00
committed by GitHub
60 changed files with 2014 additions and 1081 deletions

View File

@@ -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

View File

@@ -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 = "";

View File

@@ -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);

View File

@@ -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

View File

@@ -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;
};

View File

@@ -13,4 +13,7 @@ void register_server_camera_uri(httpd_handle_t server);
void PowerResetCamera();
extern bool debug_detail_heap;
#endif

View File

@@ -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)

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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)

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -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();

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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";};
};

View File

@@ -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()

View File

@@ -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();
};

View File

@@ -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;

View File

@@ -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";};

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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)
{

View File

@@ -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();
/////////////////////////////

View 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;
}

View 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);
};

View File

@@ -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);
}

View File

@@ -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

View 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);
}

View 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

View File

@@ -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)

View 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);
}
}

View 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();
};

View File

@@ -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;

View File

@@ -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);

View File

@@ -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
}

View File

@@ -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);

View File

@@ -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();

View File

@@ -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;

View File

@@ -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");

View File

@@ -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);

View File

@@ -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");

View File

@@ -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);

View File

@@ -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

View File

@@ -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";

View File

@@ -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

View File

@@ -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

View File

@@ -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.

View File

@@ -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");

View File

@@ -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();

View File

@@ -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);

View File

@@ -1 +1 @@
3.0.0
4.0.0