Store preprocessed image with ROI to RAM (#1809)

* tflite model loading: error handling

* FlowAlignment: error handling

* CImageBasis+GetJPGStream : error handling

* store preprocessed ALG_ROI.jpg to memory

* Update
This commit is contained in:
Slider0007
2023-01-13 22:05:18 +01:00
committed by GitHub
parent defbd60ccf
commit f15347598a
9 changed files with 214 additions and 95 deletions

View File

@@ -1,6 +1,7 @@
#include "ClassFlowAlignment.h"
#include "ClassFlowMakeImage.h"
#include "ClassFlow.h"
#include "server_tflite.h"
#include "CRotateImage.h"
#include "esp_log.h"
@@ -29,6 +30,9 @@ void ClassFlowAlignment::SetInitialParameter(void)
AlignAndCutImage = NULL;
ImageBasis = NULL;
ImageTMP = NULL;
#ifdef ALGROI_LOAD_FROM_MEM_AS_JPG
AlgROI = (ImageData*)heap_caps_malloc(sizeof(ImageData), MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM);
#endif
previousElement = NULL;
disabled = false;
SAD_criteria = 0.05;
@@ -161,6 +165,25 @@ string ClassFlowAlignment::getHTMLSingleStep(string host)
bool ClassFlowAlignment::doFlow(string time)
{
#ifdef ALGROI_LOAD_FROM_MEM_AS_JPG
if (!AlgROI) // AlgROI needs to be allocated before ImageTMP to avoid heap fragmentation
{
AlgROI = (ImageData*)heap_caps_realloc(AlgROI, sizeof(ImageData), MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM);
if (!AlgROI)
{
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Can't allocate AlgROI");
LogFile.WriteHeapInfo("ClassFlowAlignment-doFlow");
tfliteflow.SetNewAlgROI(false); // continue flow only with alg.jpg (no ROIs available)
}
}
if (AlgROI)
{
ImageBasis->writeToMemoryAsJPG((ImageData*)AlgROI, 90);
tfliteflow.SetNewAlgROI(true);
}
#endif
if (!ImageTMP)
{
ImageTMP = new CImageBasis(ImageBasis);
@@ -214,8 +237,15 @@ bool ClassFlowAlignment::doFlow(string time)
SaveReferenceAlignmentValues();
}
if (SaveAllFiles) AlignAndCutImage->SaveToFile(FormatFileName("/sdcard/img_tmp/alg.jpg"));
#ifdef ALGROI_LOAD_FROM_MEM_AS_JPG
if (AlgROI) {
DrawRef(ImageTMP);
tfliteflow.DigitalDrawROI(ImageTMP);
tfliteflow.AnalogDrawROI(ImageTMP);
ImageTMP->writeToMemoryAsJPG((ImageData*)AlgROI, 90);
}
#endif
if (SaveAllFiles)
{
if (initialflip)
@@ -224,7 +254,8 @@ bool ClassFlowAlignment::doFlow(string time)
ImageTMP->width = ImageTMP->height;
ImageTMP->height = _zw;
}
DrawRef(ImageTMP);
AlignAndCutImage->SaveToFile(FormatFileName("/sdcard/img_tmp/alg.jpg"));
ImageTMP->SaveToFile(FormatFileName("/sdcard/img_tmp/alg_roi.jpg"));
}

View File

@@ -34,6 +34,9 @@ protected:
public:
CImageBasis *ImageBasis, *ImageTMP;
#ifdef ALGROI_LOAD_FROM_MEM_AS_JPG
ImageData *AlgROI;
#endif
ClassFlowAlignment(std::vector<ClassFlow*>* lfc);

View File

@@ -141,6 +141,27 @@ t_CNNType ClassFlowControll::GetTypeAnalog()
}
#ifdef ALGROI_LOAD_FROM_MEM_AS_JPG
void ClassFlowControll::DigitalDrawROI(CImageBasis *_zw)
{
if (flowdigit)
flowdigit->DrawROI(_zw);
}
void ClassFlowControll::AnalogDrawROI(CImageBasis *_zw)
{
if (flowanalog)
flowanalog->DrawROI(_zw);
}
void ClassFlowControll::SetNewAlgROI(bool _value)
{
bNewAlgROI = _value;
}
#endif
#ifdef ENABLE_MQTT
string ClassFlowControll::GetMQTTMainTopic()
@@ -667,25 +688,47 @@ esp_err_t ClassFlowControll::GetJPGStream(std::string _fn, httpd_req_t *req)
}
}
else if (_fn == "alg_roi.jpg") {
_send = new CImageBasis(flowalignment->ImageBasis);
if (_send->ImageOkay()) {
if (flowalignment) flowalignment->DrawRef(_send);
if (flowdigit) flowdigit->DrawROI(_send);
if (flowanalog) flowanalog->DrawROI(_send);
_sendDelete = true; // delete temporary _send element after sending
}
else {
LogFile.WriteToFile(ESP_LOG_WARN, TAG, "ClassFlowControll::GetJPGStream: Not enough memory to create alg_roi.jpg -> alg.jpg is going to be served!");
if (flowalignment && flowalignment->ImageBasis->ImageOkay()) {
_send = flowalignment->ImageBasis;
#ifdef ALGROI_LOAD_FROM_MEM_AS_JPG // no CImageBasis needed to create alg_roi.jpg (ca. 790kB less RAM)
if (bNewAlgROI) {
if (flowalignment && flowalignment->AlgROI) {
httpd_resp_set_type(req, "image/jpeg");
result = httpd_resp_send(req, (const char *)flowalignment->AlgROI->data, flowalignment->AlgROI->size);
}
else {
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "ClassFlowControll::GetJPGStream: alg_roi.jpg cannot be served");
return ESP_FAIL;
}
}
else {
httpd_resp_send(req, NULL, 0);
return ESP_OK;
if (flowalignment && flowalignment->ImageBasis->ImageOkay()) {
_send = flowalignment->ImageBasis;
}
else {
httpd_resp_send(req, NULL, 0);
return ESP_OK;
}
}
}
#else
_send = new CImageBasis(flowalignment->ImageBasis);
if (_send->ImageOkay()) {
if (flowalignment) flowalignment->DrawRef(_send);
if (flowdigit) flowdigit->DrawROI(_send);
if (flowanalog) flowanalog->DrawROI(_send);
_sendDelete = true; // delete temporary _send element after sending
}
else {
LogFile.WriteToFile(ESP_LOG_WARN, TAG, "ClassFlowControll::GetJPGStream: Not enough memory to create alg_roi.jpg -> alg.jpg is going to be served!");
if (flowalignment && flowalignment->ImageBasis->ImageOkay()) {
_send = flowalignment->ImageBasis;
}
else {
httpd_resp_send(req, NULL, 0);
return ESP_OK;
}
}
#endif
}
else {
std::vector<HTMLInfo*> htmlinfo;

View File

@@ -38,6 +38,9 @@ protected:
void SetInitialParameter(void);
std::string aktstatus;
int aktRunNr;
#ifdef ALGROI_LOAD_FROM_MEM_AS_JPG
bool bNewAlgROI = false;
#endif
public:
void InitFlow(std::string config);
@@ -51,11 +54,20 @@ public:
bool ReadParameter(FILE* pfile, string& aktparamgraph);
string getJSON();
string getNumbersName();
#ifdef ALGROI_LOAD_FROM_MEM_AS_JPG
void SetNewAlgROI(bool _value);
#endif
string TranslateAktstatus(std::string _input);
#ifdef ENABLE_MQTT
#ifdef ENABLE_MQTT
string GetMQTTMainTopic();
#endif //ENABLE_MQTT
#endif //ENABLE_MQTT
#ifdef ALGROI_LOAD_FROM_MEM_AS_JPG
void DigitalDrawROI(CImageBasis *_zw);
void AnalogDrawROI(CImageBasis *_zw);
#endif
esp_err_t GetJPGStream(std::string _fn, httpd_req_t *req);
esp_err_t SendRawJPG(httpd_req_t *req);
@@ -71,9 +83,10 @@ public:
t_CNNType GetTypeDigital();
t_CNNType GetTypeAnalog();
#ifdef ENABLE_MQTT
#ifdef ENABLE_MQTT
bool StartMQTTService();
#endif //ENABLE_MQTT
#endif //ENABLE_MQTT
int CleanTempFolder();