diff --git a/code/components/jomjol_controlcamera/ClassControllCamera.cpp b/code/components/jomjol_controlcamera/ClassControllCamera.cpp index 9a1a4bc3..c1eb8463 100644 --- a/code/components/jomjol_controlcamera/ClassControllCamera.cpp +++ b/code/components/jomjol_controlcamera/ClassControllCamera.cpp @@ -8,32 +8,9 @@ #include "Helper.h" #include "CFindTemplate.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 #include @@ -47,31 +24,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 +45,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 = { @@ -128,14 +80,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 +94,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 +119,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 +139,102 @@ 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; + } + 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 (delay > 0) + { + LightOnOff(true); + const TickType_t xDelay = delay / portTICK_PERIOD_MS; + vTaskDelay( xDelay ); + } + + camera_fb_t * fb = esp_camera_fb_get(); + if (!fb) { + ESP_LOGE(TAGCAMERACLASS, "Camera Capture Failed"); + LEDOnOff(false); + return ESP_FAIL; + } + LEDOnOff(false); + + uint8_t * buf = NULL; + size_t buf_len = 0; + + frame2bmp(fb, &buf, &buf_len); + + 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; + + 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]; + } + +// _Image->CopyFromMemory(_buf_zeiger, _len_zw); + + free(buf); + + if (delay > 0) + { + LightOnOff(false); + } + + return ESP_OK; } esp_err_t CCamera::CaptureToFile(std::string nm, int delay) { -// nm = "/sdcard/josef_zw.bmp"; string ftype; LEDOnOff(true); @@ -286,15 +315,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 +355,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; } @@ -369,7 +418,7 @@ void CCamera::GetCameraParameter(httpd_req_t *req, int &qual, framesize_t &resol if (strcmp(_size, "SXGA") == 0) resol = FRAMESIZE_SXGA; // 1280x1024 if (strcmp(_size, "UXGA") == 0) - resol = FRAMESIZE_UXGA; // 1600x1200 + resol = FRAMESIZE_UXGA; // 1600x1200 } if (httpd_query_key_value(_query, "quality", _qual, 10) == ESP_OK) { @@ -409,8 +458,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); diff --git a/code/components/jomjol_controlcamera/ClassControllCamera.h b/code/components/jomjol_controlcamera/ClassControllCamera.h index 7ccfae19..7a4e2b12 100644 --- a/code/components/jomjol_controlcamera/ClassControllCamera.h +++ b/code/components/jomjol_controlcamera/ClassControllCamera.h @@ -10,6 +10,7 @@ #include "esp_camera.h" #include #include +#include "CFindTemplate.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,9 +38,8 @@ 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); }; diff --git a/code/components/jomjol_fileserver_ota/server_help.cpp b/code/components/jomjol_fileserver_ota/server_help.cpp index 17faa622..00b3e826 100644 --- a/code/components/jomjol_fileserver_ota/server_help.cpp +++ b/code/components/jomjol_fileserver_ota/server_help.cpp @@ -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) diff --git a/code/components/jomjol_fileserver_ota/server_help.h b/code/components/jomjol_fileserver_ota/server_help.h index 650a8a8e..eb836cc6 100644 --- a/code/components/jomjol_fileserver_ota/server_help.h +++ b/code/components/jomjol_fileserver_ota/server_help.h @@ -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); \ No newline at end of file diff --git a/code/components/jomjol_flowcontroll/CMakeLists.txt b/code/components/jomjol_flowcontroll/CMakeLists.txt index 670be171..b1dfec86 100644 --- a/code/components/jomjol_flowcontroll/CMakeLists.txt +++ b/code/components/jomjol_flowcontroll/CMakeLists.txt @@ -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) diff --git a/code/components/jomjol_flowcontroll/ClassFlow.cpp b/code/components/jomjol_flowcontroll/ClassFlow.cpp index 5913d304..f760cc06 100644 --- a/code/components/jomjol_flowcontroll/ClassFlow.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlow.cpp @@ -9,9 +9,11 @@ void ClassFlow::SetInitialParameter(void) { ListFlowControll = NULL; + previousElement = NULL; } -//std::vector ClassFlow::ZerlegeZeile(std::string input, std::string delimiter); + + std::vector 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 * lfc) @@ -64,6 +65,13 @@ ClassFlow::ClassFlow(std::vector * lfc) ListFlowControll = lfc; } +ClassFlow::ClassFlow(std::vector * lfc, ClassFlow *_prev) +{ + SetInitialParameter(); + ListFlowControll = lfc; + previousElement = _prev; +} + bool ClassFlow::ReadParameter(FILE* pfile, string &aktparamgraph) { return false; diff --git a/code/components/jomjol_flowcontroll/ClassFlow.h b/code/components/jomjol_flowcontroll/ClassFlow.h index 11a5b25d..ee3f37be 100644 --- a/code/components/jomjol_flowcontroll/ClassFlow.h +++ b/code/components/jomjol_flowcontroll/ClassFlow.h @@ -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* ListFlowControll; + ClassFlow *previousElement; virtual void SetInitialParameter(void); public: ClassFlow(void); ClassFlow(std::vector * lfc); + ClassFlow(std::vector * lfc, ClassFlow *_prev); + virtual bool ReadParameter(FILE* pfile, string &aktparamgraph); virtual bool doFlow(string time); virtual string getHTMLSingleStep(string host); diff --git a/code/components/jomjol_flowcontroll/ClassFlowAlignment.cpp b/code/components/jomjol_flowcontroll/ClassFlowAlignment.cpp index fa97aa7f..99423aab 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowAlignment.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowAlignment.cpp @@ -1,29 +1,51 @@ #include "ClassFlowAlignment.h" +#include "ClassFlowMakeImage.h" +#include "ClassFlow.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* 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 zerlegt; @@ -59,11 +81,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; @@ -80,72 +109,52 @@ string ClassFlowAlignment::getHTMLSingleStep(string host) } -bool ClassFlowAlignment::doFlow(string time) +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); - input = FormatFileName(input); - output = FormatFileName(output); - output2 = FormatFileName(output2); + if (AlignAndCutImage) + delete AlignAndCutImage; + AlignAndCutImage = new CAlignAndCutImage(ImageBasis, ImageTMP); + CRotate rt(AlignAndCutImage, ImageTMP); if (initialmirror){ - CRotate *rt; - rt = new CRotate(input); - if (!rt->ImageOkay()){ - LogFile.WriteToFile("ClassFlowAlignment::doFlow CRotate Inital Mirror raw.jpg not okay!"); - delete rt; - return false; - } printf("do mirror\n"); - rt->Mirror(); - rt->SaveToFile(output1); - input = output1; - delete rt; + rt.Mirror(); + if (SaveAllFiles) AlignAndCutImage->SaveToFile(FormatFileName("/sdcard/img_tmp/mirror.jpg")); } - - + if (initalrotate != 0) { - CRotate *rt = NULL; - printf("Load rotationfile: %s\n", input.c_str()); - rt = new CRotate(input); - if (!rt->ImageOkay()){ - LogFile.WriteToFile("ClassFlowAlignment::doFlow CRotate raw.jpg not okay!"); - delete rt; - return false; - } - rt->Rotate(this->initalrotate); - rt->SaveToFile(output); - delete rt; + rt.Rotate(initalrotate); + if (SaveAllFiles) AlignAndCutImage->SaveToFile(FormatFileName("/sdcard/img_tmp/rot.jpg")); } - else + + 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); +} + diff --git a/code/components/jomjol_flowcontroll/ClassFlowAlignment.h b/code/components/jomjol_flowcontroll/ClassFlowAlignment.h index b34908bc..22beed23 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowAlignment.h +++ b/code/components/jomjol_flowcontroll/ClassFlowAlignment.h @@ -15,13 +15,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* lfc); + + CAlignAndCutImage* GetAlignAndCutImage(){return AlignAndCutImage;}; + + void DrawRef(CImageBasis *_zw); + bool ReadParameter(FILE* pfile, string& aktparamgraph); bool doFlow(string time); string getHTMLSingleStep(string host); diff --git a/code/components/jomjol_flowcontroll/ClassFlowAnalog.cpp b/code/components/jomjol_flowcontroll/ClassFlowAnalog.cpp index d0dea860..cea32dca 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowAnalog.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowAnalog.cpp @@ -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* 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,8 +122,18 @@ 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; + } + + } return true; } @@ -162,79 +181,44 @@ 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; - } + CResizeImage *rs = caic->CutAndSave(ROI[i]->posx, ROI[i]->posy, ROI[i]->deltax, ROI[i]->deltay); + if (ROI[i]->image_org) + delete ROI[i]->image_org; + ROI[i]->image_org = new CImageBasis((CImageBasis*) rs); + + if (SaveAllFiles) rs->SaveToFile(FormatFileName("/sdcard/img_tmp/" + ROI[i]->name + ".jpg")); rs->Resize(modelxsize, modelysize); - ioresize = "/sdcard/img_tmp/ra" + std::to_string(i) + ".bmp"; - ioresize = FormatFileName(ioresize); - rs->SaveToFile(ioresize); - delete rs; - - if (img_roi) - { - int r = 0; - int g = 255; - int b = 0; - img_roi->drawRect(ROI[i]->posx, ROI[i]->posy, ROI[i]->deltax, ROI[i]->deltay, r, g, b, 1); - img_roi->drawCircle((int) (ROI[i]->posx + ROI[i]->deltax/2), (int) (ROI[i]->posy + ROI[i]->deltay/2), (int) (ROI[i]->deltax/2), r, g, b, 2); - img_roi->drawLine((int) (ROI[i]->posx + ROI[i]->deltax/2), (int) ROI[i]->posy, (int) (ROI[i]->posx + ROI[i]->deltax/2), (int) (ROI[i]->posy + ROI[i]->deltay), r, g, b, 2); - img_roi->drawLine((int) ROI[i]->posx, (int) (ROI[i]->posy + ROI[i]->deltay/2), (int) ROI[i]->posx + ROI[i]->deltax, (int) (ROI[i]->posy + ROI[i]->deltay/2), r, g, b, 2); - } + if (SaveAllFiles) rs->SaveToFile(FormatFileName("/sdcard/img_tmp/" + ROI[i]->name + ".bmp")); + if (ROI[i]->image) + delete ROI[i]->image; + ROI[i]->image = rs; } - delete caic; - - - if (img_roi) - { - img_roi->SaveToFile(input_roi); - delete img_roi; - } - return true; } +void ClassFlowAnalog::DrawROI(CImageBasis *_zw) +{ + int r = 0; + int g = 255; + int b = 0; + + for (int i = 0; i < ROI.size(); ++i) + { + _zw->drawRect(ROI[i]->posx, ROI[i]->posy, ROI[i]->deltax, ROI[i]->deltay, r, g, b, 1); + _zw->drawCircle((int) (ROI[i]->posx + ROI[i]->deltax/2), (int) (ROI[i]->posy + ROI[i]->deltay/2), (int) (ROI[i]->deltax/2), r, g, b, 2); + _zw->drawLine((int) (ROI[i]->posx + ROI[i]->deltax/2), (int) ROI[i]->posy, (int) (ROI[i]->posx + ROI[i]->deltax/2), (int) (ROI[i]->posy + ROI[i]->deltay), r, g, b, 2); + _zw->drawLine((int) ROI[i]->posx, (int) (ROI[i]->posy + ROI[i]->deltay/2), (int) ROI[i]->posx + ROI[i]->deltax, (int) (ROI[i]->posy + ROI[i]->deltay/2), r, g, b, 2); + } +} + bool ClassFlowAnalog::doNeuralNetwork(string time) { string logPath = CreateLogFolder(time); @@ -265,7 +249,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"); @@ -278,9 +263,12 @@ bool ClassFlowAnalog::doNeuralNetwork(string time) // printf("Result sin, cos, ziffer: %f, %f, %f\n", f1, f2, result); ROI[i]->result = result * 10; - printf("Result Analog%i: %f\n", i, ROI[i]->result); + 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; diff --git a/code/components/jomjol_flowcontroll/ClassFlowAnalog.h b/code/components/jomjol_flowcontroll/ClassFlowAnalog.h index 89f2f6e2..64de44e0 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowAnalog.h +++ b/code/components/jomjol_flowcontroll/ClassFlowAnalog.h @@ -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,14 +19,21 @@ 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* lfc); + bool ReadParameter(FILE* pfile, string& aktparamgraph); bool doFlow(string time); string getHTMLSingleStep(string host); - string getReadout(); + string getReadout(); + + void DrawROI(CImageBasis *_zw); bool doNeuralNetwork(string time); bool doAlignAndCut(string time); diff --git a/code/components/jomjol_flowcontroll/ClassFlowControll.cpp b/code/components/jomjol_flowcontroll/ClassFlowControll.cpp index 5734ef26..146652c5 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowControll.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowControll.cpp @@ -11,6 +11,9 @@ static const char* TAG = "flow_controll"; +bool flowcontrolldebugdetail = true; + + 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,6 +198,25 @@ bool ClassFlowControll::doFlow(string time) std::string zw_time; int repeat = 0; + +///////////////////////////////////////////////////// + int aInternalFreeHeapSizeAtEnd, aInternalFreeHeapSizeAtStart; + aInternalFreeHeapSizeAtStart = getInternalESPHeapSize(); + + if (flowcontrolldebugdetail){ + std::string aStartEspInfoStr = "ClassFlowAnalog::doFlow - Start: " + getESPHeapInfo(); + LogFile.WriteToFile(aStartEspInfoStr); + } + + aInternalFreeHeapSizeAtEnd = getInternalESPHeapSize(); + if (flowcontrolldebugdetail){ + std::string aStartEspInfoStr = "ClassFlowAnalog::doFlow - Now : " + getESPHeapInfo(); + LogFile.WriteToFile(aStartEspInfoStr); + + } + +///////////////////////////////////////////////////////// + for (int i = 0; i < FlowControll.size(); ++i) { zw_time = gettimestring("%Y%m%d-%H%M%S"); @@ -202,6 +238,14 @@ bool ClassFlowControll::doFlow(string time) { result = true; } + + aInternalFreeHeapSizeAtEnd = getInternalESPHeapSize(); + if (flowcontrolldebugdetail){ + std::string aStartEspInfoStr = "ClassFlowAnalog::doFlow - Now : " + getESPHeapInfo(); + LogFile.WriteToFile(aStartEspInfoStr); + + } + } zw_time = gettimestring("%Y%m%d-%H%M%S"); aktstatus = zw_time + ": Flow is done"; @@ -362,4 +406,68 @@ int ClassFlowControll::CleanTempFolder() { ESP_LOGI(TAG, "%d files deleted", deleted); return 0; +} + + +esp_err_t ClassFlowControll::SendRawJPG(httpd_req_t *req) +{ + return flowmakeimage->SendRawJPG(req); +} + + +ImageData* ClassFlowControll::GetJPGStream(std::string _fn) +{ + printf("ClassFlowControll::GetJPGStream %s\n", _fn.c_str()); + ImageData* ret = NULL; + + if (_fn == "alg.jpg") + { + return flowalignment->ImageBasis->writeToMemoryAsJPG(); + } + + if (_fn == "alg_roi.jpg") + { + CImageBasis* _imgzw = new CImageBasis(flowalignment->ImageBasis); + flowalignment->DrawRef(_imgzw); + if (flowdigit) flowdigit->DrawROI(_imgzw); + if (flowanalog) flowanalog->DrawROI(_imgzw); + ret = _imgzw->writeToMemoryAsJPG(); + delete _imgzw; + return ret; + } + + + std::vector htmlinfo; + htmlinfo = GetAllDigital(); + for (int i = 0; i < htmlinfo.size(); ++i) + { + if (_fn == htmlinfo[i]->filename) + { + if (htmlinfo[i]->image) + return htmlinfo[i]->image->writeToMemoryAsJPG(); + } + if (_fn == htmlinfo[i]->filename_org) + { + if (htmlinfo[i]->image_org) + return htmlinfo[i]->image_org->writeToMemoryAsJPG(); + } + } + + htmlinfo = GetAllAnalog(); + for (int i = 0; i < htmlinfo.size(); ++i) + { + if (_fn == htmlinfo[i]->filename) + { + if (htmlinfo[i]->image) + return htmlinfo[i]->image->writeToMemoryAsJPG(); + } + if (_fn == htmlinfo[i]->filename_org) + { + if (htmlinfo[i]->image_org) + return htmlinfo[i]->image_org->writeToMemoryAsJPG(); + } + } + + printf("Kein internes Bild gefunden - suche auf SD-Karte\n"); + return NULL; } \ No newline at end of file diff --git a/code/components/jomjol_flowcontroll/ClassFlowControll.h b/code/components/jomjol_flowcontroll/ClassFlowControll.h index adf7ef6a..0479fc59 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowControll.h +++ b/code/components/jomjol_flowcontroll/ClassFlowControll.h @@ -17,6 +17,10 @@ class ClassFlowControll : protected: std::vector 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); + ImageData* GetJPGStream(std::string _fn); + esp_err_t SendRawJPG(httpd_req_t *req); + std::string doSingleStep(std::string _stepname, std::string _host); bool isAutoStart(long &_intervall); diff --git a/code/components/jomjol_flowcontroll/ClassFlowDigit.cpp b/code/components/jomjol_flowcontroll/ClassFlowDigit.cpp index 90f02254..c712404a 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowDigit.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowDigit.cpp @@ -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* 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* 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,8 +116,17 @@ 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; + } + } return true; } @@ -133,60 +173,24 @@ 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); + CResizeImage *rs = caic->CutAndSave(ROI[i]->posx, ROI[i]->posy, ROI[i]->deltax, ROI[i]->deltay); + + if (ROI[i]->image_org) + free(ROI[i]->image_org); + ROI[i]->image_org = new CImageBasis((CImageBasis*) rs); + if (SaveAllFiles) rs->SaveToFile(FormatFileName("/sdcard/img_tmp/" + ROI[i]->name + ".jpg")); - 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; + if (SaveAllFiles) rs->SaveToFile(FormatFileName("/sdcard/img_tmp/" + ROI[i]->name + ".bmp")); - 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; + if (ROI[i]->image) + free(ROI[i]->image); + ROI[i]->image = rs; } 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 ClassFlowDigit::GetHTMLInfo() { @@ -241,10 +243,14 @@ std::vector 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; -} \ No newline at end of file +} + diff --git a/code/components/jomjol_flowcontroll/ClassFlowDigit.h b/code/components/jomjol_flowcontroll/ClassFlowDigit.h index 3546bb36..d3043642 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowDigit.h +++ b/code/components/jomjol_flowcontroll/ClassFlowDigit.h @@ -1,5 +1,6 @@ #pragma once #include "ClassFlowImage.h" +#include "ClassFlowAlignment.h" #include "Helper.h" #include @@ -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; 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* lfc); + ClassFlowDigit(std::vector* lfc, ClassFlow *_prev); bool ReadParameter(FILE* pfile, string& aktparamgraph); bool doFlow(string time); string getHTMLSingleStep(string host); string getReadout(); std::vector GetHTMLInfo(); + void DrawROI(CImageBasis *_zw); + string name(){return "ClassFlowDigit";}; }; diff --git a/code/components/jomjol_flowcontroll/ClassFlowImage.cpp b/code/components/jomjol_flowcontroll/ClassFlowImage.cpp index 5c09160e..24dc289d 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowImage.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowImage.cpp @@ -5,6 +5,7 @@ #include #include "time_sntp.h" #include "ClassLogFile.h" +#include "CFindTemplate.h" ClassFlowImage::ClassFlowImage(const char* logTag) { @@ -12,12 +13,19 @@ ClassFlowImage::ClassFlowImage(const char* logTag) isLogImage = false; } -ClassFlowImage::ClassFlowImage(std::vector * lfc, const char* logTag) : ClassFlow((std::vector*)lfc) +ClassFlowImage::ClassFlowImage(std::vector * lfc, const char* logTag) : ClassFlow(lfc) { this->logTag = logTag; isLogImage = false; } +ClassFlowImage::ClassFlowImage(std::vector * 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() diff --git a/code/components/jomjol_flowcontroll/ClassFlowImage.h b/code/components/jomjol_flowcontroll/ClassFlowImage.h index 23154c64..e3dacc35 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowImage.h +++ b/code/components/jomjol_flowcontroll/ClassFlowImage.h @@ -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 * lfc, const char* logTag); - + ClassFlowImage(std::vector * lfc, ClassFlow *_prev, const char* logTag); + void RemoveOldLogs(); }; diff --git a/code/components/jomjol_flowcontroll/ClassFlowMQTT.cpp b/code/components/jomjol_flowcontroll/ClassFlowMQTT.cpp index e96de968..3200e57f 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowMQTT.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowMQTT.cpp @@ -6,7 +6,7 @@ #include -ClassFlowMQTT::ClassFlowMQTT() +void ClassFlowMQTT::SetInitialParameter(void) { uri = ""; topic = ""; @@ -15,20 +15,35 @@ ClassFlowMQTT::ClassFlowMQTT() OldValue = ""; flowpostprocessing = NULL; user = ""; - password = ""; + password = ""; + previousElement = NULL; + ListFlowControll = NULL; +} + +ClassFlowMQTT::ClassFlowMQTT() +{ + SetInitialParameter(); } ClassFlowMQTT::ClassFlowMQTT(std::vector* 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* lfc, ClassFlow *_prev) +{ + SetInitialParameter(); + + previousElement = _prev; ListFlowControll = lfc; for (int i = 0; i < ListFlowControll->size(); ++i) @@ -38,9 +53,9 @@ ClassFlowMQTT::ClassFlowMQTT(std::vector* lfc) flowpostprocessing = (ClassFlowPostProcessing*) (*ListFlowControll)[i]; } } - } + bool ClassFlowMQTT::ReadParameter(FILE* pfile, string& aktparamgraph) { std::vector zerlegt; diff --git a/code/components/jomjol_flowcontroll/ClassFlowMQTT.h b/code/components/jomjol_flowcontroll/ClassFlowMQTT.h index 48e93f0f..2ac29135 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowMQTT.h +++ b/code/components/jomjol_flowcontroll/ClassFlowMQTT.h @@ -13,11 +13,13 @@ protected: std::string OldValue; ClassFlowPostProcessing* flowpostprocessing; std::string user, password; - + void SetInitialParameter(void); public: ClassFlowMQTT(); ClassFlowMQTT(std::vector* lfc); + ClassFlowMQTT(std::vector* lfc, ClassFlow *_prev); + bool ReadParameter(FILE* pfile, string& aktparamgraph); bool doFlow(string time); string name(){return "ClassFlowMQTT";}; diff --git a/code/components/jomjol_flowcontroll/ClassFlowMakeImage.cpp b/code/components/jomjol_flowcontroll/ClassFlowMakeImage.cpp index d1f4d78c..156544ab 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowMakeImage.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowMakeImage.cpp @@ -16,30 +16,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* 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 +61,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 +95,46 @@ 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; - - + takePictureWithFlash(flashdauer); - time(&TimeImageTaken); - localtime(&TimeImageTaken); - LogImage(logPath, "raw", NULL, NULL, zwtime); +// time(&TimeImageTaken); +// localtime(&TimeImageTaken); + LogImage(logPath, "raw", NULL, NULL, zwtime, rawImage); 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; +} + diff --git a/code/components/jomjol_flowcontroll/ClassFlowMakeImage.h b/code/components/jomjol_flowcontroll/ClassFlowMakeImage.h index febb2ab3..2edc544b 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowMakeImage.h +++ b/code/components/jomjol_flowcontroll/ClassFlowMakeImage.h @@ -20,19 +20,31 @@ 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 takePictureWithFlash(int flashdauer); + + void SetInitialParameter(void); public: - ClassFlowMakeImage(); + CImageBasis *rawImage; + ClassFlowMakeImage(std::vector* 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); }; diff --git a/code/components/jomjol_helper/Helper.cpp b/code/components/jomjol_helper/Helper.cpp index 00544c1e..0a32b30e 100644 --- a/code/components/jomjol_helper/Helper.cpp +++ b/code/components/jomjol_helper/Helper.cpp @@ -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) { diff --git a/code/components/jomjol_helper/Helper.h b/code/components/jomjol_helper/Helper.h index 3c65d222..5ecf2f5f 100644 --- a/code/components/jomjol_helper/Helper.h +++ b/code/components/jomjol_helper/Helper.h @@ -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(); + +///////////////////////////// diff --git a/code/components/jomjol_image_proc/CFindTemplate.cpp b/code/components/jomjol_image_proc/CFindTemplate.cpp index 69397e81..3a6317ef 100644 --- a/code/components/jomjol_image_proc/CFindTemplate.cpp +++ b/code/components/jomjol_image_proc/CFindTemplate.cpp @@ -14,60 +14,114 @@ using namespace std; #define GET_MEMORY malloc -/* -CResizeImage::CResizeImage(std::string _image, int _new_dx, int _new_dy) +void writejpghelp(void *context, void *data, int size) { - CImageBasis::CImageBasis(_image); +// 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; + + auto rv2 = stbi_write_jpg_to_func(writejpghelp, ii, width, height, channels, rgb_image, quality); + + return ii; +} + +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 = this->rgb_image + (this->channels * (y * this->width + x)); + p_source = rgb_image + (channels * (y * width + x)); return p_source[ch]; } void CResizeImage::Resize(int _new_dx, int _new_dy) { - int memsize = _new_dx * _new_dy * this->channels; + int memsize = _new_dx * _new_dy * 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); + stbir_resize_uint8(rgb_image, width, height, 0, odata, _new_dx, _new_dy, 0, channels); - stbi_image_free(this->rgb_image); - this->rgb_image = (unsigned char*)GET_MEMORY(memsize); + stbi_image_free(rgb_image); + rgb_image = (unsigned char*)GET_MEMORY(memsize); - this->memCopy(odata, this->rgb_image, memsize); - this->width = _new_dx; - this->height = _new_dy; + memCopy(odata, rgb_image, memsize); + width = _new_dx; + height = _new_dy; stbi_image_free(odata); } + +CRotate::CRotate(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 CRotate::Mirror(){ - int memsize = this->width * this->height * this->channels; - uint8_t* odata = (unsigned char*)GET_MEMORY(memsize); + 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 < this->width; ++x) - for (int y = 0; y < this->height; ++y) + for (int x = 0; x < width; ++x) + for (int y = 0; y < height; ++y) { - p_target = odata + (this->channels * (y * this->width + x)); + p_target = odata + (channels * (y * width + x)); - x_source = this->width - x; + x_source = 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]; + p_source = rgb_image + (channels * (y_source * width + x_source)); + for (int _channels = 0; _channels < 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); + // memcpy(rgb_image, odata, memsize); + memCopy(odata, rgb_image, memsize); + if (!ImageTMP) + { + stbi_image_free(odata); + } } void CRotate::Rotate(float _angle, int _centerx, int _centery) @@ -86,17 +140,26 @@ void CRotate::Rotate(float _angle, int _centerx, int _centery) 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 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 < this->width; ++x) - for (int y = 0; y < this->height; ++y) + for (int x = 0; x < width; ++x) + for (int y = 0; y < height; ++y) { - p_target = odata + (this->channels * (y * this->width + x)); + 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); @@ -104,94 +167,112 @@ void CRotate::Rotate(float _angle, int _centerx, int _centery) 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)) + if ((x_source >= 0) && (x_source < width) && (y_source >= 0) && (y_source < 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]; + 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 < this->channels; ++channels) - p_target[channels] = 255; + for (int _channels = 0; _channels < channels; ++_channels) + p_target[_channels] = 255; } } - // memcpy(this->rgb_image, odata, memsize); - this->memCopy(odata, this->rgb_image, memsize); - stbi_image_free(odata); + // memcpy(rgb_image, odata, memsize); + memCopy(odata, rgb_image, memsize); + + if (!ImageTMP) + { + stbi_image_free(odata); + } } void CRotate::Rotate(float _angle) { - this->Rotate(_angle, this->width / 2, this->height / 2); +// printf("width %d, height %d\n", width, height); + Rotate(_angle, width / 2, 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 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 < this->width; ++x) - for (int y = 0; y < this->height; ++y) + for (int x = 0; x < width; ++x) + for (int y = 0; y < height; ++y) { - p_target = odata + (this->channels * (y * this->width + x)); + p_target = odata + (channels * (y * 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)) + if ((x_source >= 0) && (x_source < width) && (y_source >= 0) && (y_source < 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]; + 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 < this->channels; ++channels) - p_target[channels] = 255; + for (int _channels = 0; _channels < channels; ++_channels) + p_target[_channels] = 255; } } - // memcpy(this->rgb_image, odata, memsize); - this->memCopy(odata, this->rgb_image, memsize); - stbi_image_free(odata); + // memcpy(rgb_image, odata, memsize); + memCopy(odata, rgb_image, memsize); + if (!ImageTMP) + { + 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); + channels = 1; + rgb_image = stbi_load(_image.c_str(), &(width), &(height), &(bpp), 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 +280,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 +303,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 +318,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,14 +326,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); } @@ -269,10 +350,10 @@ void CImageBasis::memCopy(uint8_t* _source, uint8_t* _target, int _size) bool CImageBasis::isInImage(int x, int y) { - if ((x < 0) || (x > this->width - 1)) + if ((x < 0) || (x > width - 1)) return false; - if ((y < 0) || (y > this->height- 1)) + if ((y < 0) || (y > height- 1)) return false; return true; @@ -282,9 +363,9 @@ 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 = rgb_image + (channels * (y * width + x)); p_source[0] = r; - if (this-> channels > 2) + if ( channels > 2) { p_source[1] = g; p_source[2] = b; @@ -383,7 +464,61 @@ void CImageBasis::drawCircle(int x1, int y1, int rad, int r, int g, int b, int t CImageBasis::CImageBasis() { - this->externalImage = false; + 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) +{ + 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); + 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(std::string _image) @@ -391,13 +526,19 @@ CImageBasis::CImageBasis(std::string _image) channels = 3; externalImage = false; filename = _image; -// long freebefore = esp_get_free_heap_size(); + long zwld = esp_get_free_heap_size(); + printf("freeheapsize before: %ld\n", zwld); 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); + 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(){ @@ -406,12 +547,12 @@ bool CImageBasis::ImageOkay(){ 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; + rgb_image = _rgb_image; + channels = _channels; + width = _width; + height = _height; + bpp = _bpp; + externalImage = true; } void CImageBasis::Contrast(float _contrast) //input range [-100..100] @@ -424,16 +565,16 @@ void CImageBasis::Contrast(float _contrast) //input range [-100..100] 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))); + 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 (!this->externalImage) - stbi_image_free(this->rgb_image); + if (!externalImage) + stbi_image_free(rgb_image); } void CImageBasis::SaveToFile(std::string _imageout) @@ -442,25 +583,44 @@ void CImageBasis::SaveToFile(std::string _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); + stbi_write_jpg(_imageout.c_str(), width, height, channels, 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_bmp(_imageout.c_str(), width, height, channels, 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); } +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(this->filename); +// CFindTemplate* ft = new CFindTemplate(filename); + CFindTemplate* ft = new CFindTemplate(rgb_image, channels, width, height, bpp); r0_x = ref0_x; r0_y = ref0_y; @@ -495,7 +655,7 @@ void CAlignAndCutImage::Align(std::string _template0, int ref0_x, int ref0_y, st if (imageROI.length() > 0) { - CImageBasis* imgzw = new CImageBasis(this->filename); + 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); @@ -504,14 +664,16 @@ void CAlignAndCutImage::Align(std::string _template0, int ref0_x, int ref0_y, st } 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); +// LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", zw); - CRotate rt(this->rgb_image, this->channels, this->width, this->height, this->bpp); + CRotate 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) { @@ -519,13 +681,13 @@ void CAlignAndCutImage::CutAndSave(std::string _template1, int x1, int y1, int d x2 = x1 + dx; y2 = y1 + dy; - x2 = min(x2, this->width - 1); - y2 = min(y2, this->height - 1); + x2 = min(x2, width - 1); + y2 = min(y2, height - 1); dx = x2 - x1; dy = y2 - y1; - int memsize = dx * dy * this->channels; + int memsize = dx * dy * channels; uint8_t* odata = (unsigned char*)GET_MEMORY(memsize); stbi_uc* p_target; @@ -534,14 +696,46 @@ void CAlignAndCutImage::CutAndSave(std::string _template1, int x1, int y1, int d 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]; + 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, this->channels, odata, 0); - stbi_write_bmp(_template1.c_str(), dx, dy, this->channels, odata); + // 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); } + +CResizeImage* CAlignAndCutImage::CutAndSave(int x1, int y1, int dx, int dy) +{ + int x2, y2; + + x2 = x1 + dx; + y2 = y1 + dy; + x2 = min(x2, width - 1); + y2 = 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]; + } + + CResizeImage* rs = new CResizeImage(odata, channels, dx, dy, bpp); + rs->SetIndepended(); + return rs; +} diff --git a/code/components/jomjol_image_proc/CFindTemplate.h b/code/components/jomjol_image_proc/CFindTemplate.h index 0023d666..15a187e8 100644 --- a/code/components/jomjol_image_proc/CFindTemplate.h +++ b/code/components/jomjol_image_proc/CFindTemplate.h @@ -15,12 +15,18 @@ #include "stb_image_resize.h" +#define MAX_JPG_SIZE 128000 + +struct ImageData +{ + uint8_t data[MAX_JPG_SIZE]; + size_t size = 0; +}; + + class CImageBasis { protected: - uint8_t* rgb_image; - int channels; - int width, height, bpp; bool externalImage; std::string filename; @@ -28,6 +34,10 @@ class CImageBasis 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;}; @@ -37,11 +47,22 @@ class CImageBasis 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(CImageBasis *_copyfrom); + + void LoadFromMemory(stbi_uc *_buffer, int len); + + ImageData* writeToMemoryAsJPG(const int quality = 90); + uint8_t GetPixelColor(int x, int y, int ch); ~CImageBasis(); @@ -53,7 +74,9 @@ 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); @@ -64,8 +87,10 @@ class CFindTemplate : public CImageBasis 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) {}; + CImageBasis *ImageTMP; + CRotate(std::string _image) : CImageBasis(_image) {ImageTMP = NULL;}; + CRotate(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp) : CImageBasis(_rgb_image, _channels, _width, _height, _bpp) {ImageTMP = NULL;}; + CRotate(CImageBasis *_org, CImageBasis *_temp); void Rotate(float _angle); void Rotate(float _angle, int _centerx, int _centery); @@ -74,25 +99,33 @@ class CRotate: public CImageBasis }; -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(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp) : CImageBasis(_rgb_image, _channels, _width, _height, _bpp) {}; + // CResizeImage(std::string _image, int _new_dx, int _new_dy); void Resize(int _new_dx, int _new_dy); }; + +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); + CResizeImage* CutAndSave(int x1, int y1, int dx, int dy); + void GetRefSize(int *ref_dx, int *ref_dy); +}; + + #endif diff --git a/code/components/jomjol_logfile/ClassLogFile.cpp b/code/components/jomjol_logfile/ClassLogFile.cpp index d134448b..83f08a21 100644 --- a/code/components/jomjol_logfile/ClassLogFile.cpp +++ b/code/components/jomjol_logfile/ClassLogFile.cpp @@ -19,7 +19,7 @@ void ClassLogFile::WriteToDedicatedFile(std::string _fn, std::string info, bool return; } - pFile = OpenFileAndWait(_fn.c_str(), "a+"); + pFile = OpenFileAndWait(_fn.c_str(), "a"); if (pFile!=NULL) { if (_time) @@ -80,12 +80,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; diff --git a/code/components/jomjol_tfliteclass/CTfLiteClass.cpp b/code/components/jomjol_tfliteclass/CTfLiteClass.cpp index 14458d38..054a1666 100644 --- a/code/components/jomjol_tfliteclass/CTfLiteClass.cpp +++ b/code/components/jomjol_tfliteclass/CTfLiteClass.cpp @@ -21,6 +21,18 @@ float CTfLiteClass::GetOutputValue(int nr) return output2->data.f[nr]; } +int CTfLiteClass::GetClassFromImageBasis(CImageBasis *rs) +{ +// printf("Before Load image %s\n", _fn.c_str()); + if (!LoadInputImageBasis(rs)) + return -1000; + + Invoke(); + printf("After Invoke \n"); + + return GetOutClassification(); +} + int CTfLiteClass::GetClassFromImage(std::string _fn) { @@ -33,7 +45,6 @@ int CTfLiteClass::GetClassFromImage(std::string _fn) printf("After Invoke %s\n", _fn.c_str()); return GetOutClassification(); -// return 0; } int CTfLiteClass::GetOutClassification() @@ -113,6 +124,46 @@ void CTfLiteClass::Invoke() } + +bool CTfLiteClass::LoadInputImageBasis(CImageBasis *rs) +{ + std::string zw = "ClassFlowAnalog::doNeuralNetwork nach LoadInputResizeImage: "; +// LogFile.WriteToFile(zw); + + + 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; + float* input_data_ptr = (interpreter->input(0))->data.f; + + for (int y = 0; y < h; ++y) + for (int x = 0; x < w; ++x) + { + 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"); + + return true; +} + + + bool CTfLiteClass::LoadInputImage(std::string _fn) { std::string zw = "ClassFlowAnalog::doNeuralNetwork nach Load Image: " + _fn; @@ -239,7 +290,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]; } diff --git a/code/components/jomjol_tfliteclass/CTfLiteClass.h b/code/components/jomjol_tfliteclass/CTfLiteClass.h index 1350a86a..927ecbd4 100644 --- a/code/components/jomjol_tfliteclass/CTfLiteClass.h +++ b/code/components/jomjol_tfliteclass/CTfLiteClass.h @@ -14,6 +14,8 @@ #include "esp_err.h" #include "esp_log.h" +#include "CFindTemplate.h" + #define SUPRESS_TFLITE_ERRORS // use, to avoid error messages from TFLITE @@ -59,10 +61,12 @@ class CTfLiteClass 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); diff --git a/code/components/jomjol_tfliteclass/server_tflite.cpp b/code/components/jomjol_tfliteclass/server_tflite.cpp index efe6ab21..a1deb573 100644 --- a/code/components/jomjol_tfliteclass/server_tflite.cpp +++ b/code/components/jomjol_tfliteclass/server_tflite.cpp @@ -29,6 +29,16 @@ bool flowisrunning = false; long auto_intervall = 0; bool auto_isrunning = false; +ImageData* GetJPG(std::string _filename) +{ + return tfliteflow.GetJPGStream(_filename); +} + +esp_err_t GetRawJPG(httpd_req_t *req) +{ + return tfliteflow.SendRawJPG(req); +} + bool isSetupModusActive() { return tfliteflow.getStatusSetupModus(); return false; @@ -171,7 +181,7 @@ esp_err_t handler_wasserzaehler(httpd_req_t *req) { string txt, zw; - txt = "

Aligned Image:

\n"; + txt = "

Aligned Image:

\n"; txt = txt + "Digital Counter:

"; httpd_resp_sendstr_chunk(req, txt.c_str()); diff --git a/code/components/jomjol_tfliteclass/server_tflite.h b/code/components/jomjol_tfliteclass/server_tflite.h index 68fc1dbc..4dc76340 100644 --- a/code/components/jomjol_tfliteclass/server_tflite.h +++ b/code/components/jomjol_tfliteclass/server_tflite.h @@ -1,6 +1,7 @@ #include #include +#include "CFindTemplate.h" //#include "ClassControllCamera.h" @@ -12,4 +13,8 @@ void KillTFliteTasks(); void TFliteDoAutoStart(); -bool isSetupModusActive(); \ No newline at end of file +bool isSetupModusActive(); + +ImageData* GetJPG(std::string _filename); + +esp_err_t GetRawJPG(httpd_req_t *req); \ No newline at end of file diff --git a/code/main/server_main.cpp b/code/main/server_main.cpp index 084dca5d..629fd5b7 100644 --- a/code/main/server_main.cpp +++ b/code/main/server_main.cpp @@ -144,6 +144,7 @@ esp_err_t hello_main_handler(httpd_req_t *req) 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,20 +183,8 @@ 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; @@ -214,28 +203,13 @@ esp_err_t img_tmp_handler(httpd_req_t *req) 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,6 +218,58 @@ esp_err_t img_tmp_handler(httpd_req_t *req) return ESP_OK; } +esp_err_t img_tmp_virtual_handler(httpd_req_t *req) +{ + 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); + } + + ImageData *zw = GetJPG(filetosend); + + if (zw) + { + ESP_LOGI(TAG, "Sending file : %s (%d bytes)...", filetosend.c_str(), zw->size); + set_content_type_from_file(req, filetosend.c_str()); + + if (httpd_resp_send_chunk(req, (char*) &(zw->data), zw->size) != ESP_OK) { + ESP_LOGE(TAG, "File sending failed!"); + httpd_resp_sendstr_chunk(req, NULL); + httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to send file"); + delete zw; + return ESP_FAIL; + } + ESP_LOGI(TAG, "File sending complete"); + /* Respond with an empty chunk to signal HTTP response completion */ + httpd_resp_send_chunk(req, NULL, 0); + + delete zw; + return ESP_OK; + } + + // File wird nicht intern bereit gestellt --> klassischer weg: + + return img_tmp_handler(req); +} + + + + + esp_err_t sysinfo_handler(httpd_req_t *req) { const char* resp_str; @@ -314,7 +340,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); diff --git a/code/main/version.cpp b/code/main/version.cpp index 74c9015a..7e19a341 100644 --- a/code/main/version.cpp +++ b/code/main/version.cpp @@ -1,4 +1,4 @@ -const char* GIT_REV="793f928"; +const char* GIT_REV="f5c2810"; const char* GIT_TAG=""; const char* GIT_BRANCH="rolling"; -const char* BUILD_TIME="2020-12-07 20:40"; \ No newline at end of file +const char* BUILD_TIME="2020-12-21 22:49"; \ No newline at end of file diff --git a/code/sdkconfig b/code/sdkconfig index dd11c44e..ef107863 100644 --- a/code/sdkconfig +++ b/code/sdkconfig @@ -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=0 +CONFIG_FATFS_TIMEOUT_MS=100 CONFIG_FATFS_PER_FILE_CACHE=y CONFIG_FATFS_ALLOC_PREFER_EXTRAM=y # end of FAT Filesystem support diff --git a/code/sdkconfig.old b/code/sdkconfig.old index 88827b07..7a1e76ca 100644 --- a/code/sdkconfig.old +++ b/code/sdkconfig.old @@ -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=0 +CONFIG_FATFS_TIMEOUT_MS=100 CONFIG_FATFS_PER_FILE_CACHE=y CONFIG_FATFS_ALLOC_PREFER_EXTRAM=y # end of FAT Filesystem support diff --git a/code/version.cpp b/code/version.cpp index 74c9015a..7e19a341 100644 --- a/code/version.cpp +++ b/code/version.cpp @@ -1,4 +1,4 @@ -const char* GIT_REV="793f928"; +const char* GIT_REV="f5c2810"; const char* GIT_TAG=""; const char* GIT_BRANCH="rolling"; -const char* BUILD_TIME="2020-12-07 20:40"; \ No newline at end of file +const char* BUILD_TIME="2020-12-21 22:49"; \ No newline at end of file diff --git a/firmware/bootloader.bin b/firmware/bootloader.bin index dc68b2b7..0aae7667 100644 Binary files a/firmware/bootloader.bin and b/firmware/bootloader.bin differ diff --git a/firmware/firmware.bin b/firmware/firmware.bin index c81a80d6..4e05867a 100644 Binary files a/firmware/firmware.bin and b/firmware/firmware.bin differ diff --git a/firmware/html.zip b/firmware/html.zip index 9d1ae20c..33a1c7ec 100644 Binary files a/firmware/html.zip and b/firmware/html.zip differ diff --git a/sd-card/html/edit_reference.html b/sd-card/html/edit_reference.html index 34e02678..0ea705dd 100644 --- a/sd-card/html/edit_reference.html +++ b/sd-card/html/edit_reference.html @@ -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();