diff --git a/README.md b/README.md index c0a364bd..36dd4488 100644 --- a/README.md +++ b/README.md @@ -29,17 +29,24 @@ A 3d-printable housing can be found here: https://www.thingiverse.com/thing:4571 -##### Rolling - (2020-09-11) +##### Rolling - (2020-09-12) + +* Option for mirroring input image +* Update index.html + +2020-09-11 * Improved handling of PreValue -* Improved error handling for automated processflow (reduce spontaneous reboot - see Issues) + +* Improved error handling for automated process flow (reduce spontaneous reboot - see Issues) + * Support of spaces in WLan SSID or password 2020-09-10 * Optimization of "DELETE ALL" - Autoreload of directory after delete, protection of wlan.ini -* Internal Optimization (removal of unnessary error messages, restructure CTfLiteClass) +* Internal Optimization (removal of unnecessary error messages, restructure CTfLiteClass) * additional parameter in `wasserzahler.html?noerror=true` to suppress an potential error message in case of consitency check (is equal to `ErrorMessage` = False in `config.ini`) diff --git a/code/lib/jomjol_flowcontroll/ClassFlowAlignment.cpp b/code/lib/jomjol_flowcontroll/ClassFlowAlignment.cpp index 0618fa17..fa97aa7f 100644 --- a/code/lib/jomjol_flowcontroll/ClassFlowAlignment.cpp +++ b/code/lib/jomjol_flowcontroll/ClassFlowAlignment.cpp @@ -8,6 +8,7 @@ ClassFlowAlignment::ClassFlowAlignment() anz_ref = 0; suchex = 40; suchey = 40; + initialmirror = false; namerawimage = "/sdcard/img_tmp/raw.jpg"; ListFlowControll = NULL; } @@ -18,6 +19,7 @@ ClassFlowAlignment::ClassFlowAlignment(std::vector* lfc) anz_ref = 0; suchex = 40; suchey = 40; + initialmirror = false; namerawimage = "/sdcard/img_tmp/raw.jpg"; ListFlowControll = lfc; } @@ -38,7 +40,12 @@ bool ClassFlowAlignment::ReadParameter(FILE* pfile, string& aktparamgraph) while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph)) { zerlegt = this->ZerlegeZeile(aktparamgraph); - if ((zerlegt[0] == "InitalRotate") && (zerlegt.size() > 1)) + if ((zerlegt[0] == "InitialMirror") && (zerlegt.size() > 1)) + { + if (toUpper(zerlegt[1]) == "TRUE") + initialmirror = true; + } + if (((zerlegt[0] == "InitalRotate") || (zerlegt[0] == "InitialRotate")) && (zerlegt.size() > 1)) { this->initalrotate = std::stod(zerlegt[1]); } @@ -80,26 +87,38 @@ bool ClassFlowAlignment::doFlow(string time) 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"; input = FormatFileName(input); output = FormatFileName(output); output2 = FormatFileName(output2); + 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; + } + + if (initalrotate != 0) { - CRotate *rt; + 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; - LogFile.WriteToFile("ClassFlowAlignment::doFlow 1x reload."); - rt = new CRotate(input); - if (!rt->ImageOkay()){ - LogFile.WriteToFile("ClassFlowAlignment::doFlow Reload auch nicht erfolgreich!"); - delete rt; - return false; - } + return false; } rt->Rotate(this->initalrotate); rt->SaveToFile(output); diff --git a/code/lib/jomjol_flowcontroll/ClassFlowAlignment.h b/code/lib/jomjol_flowcontroll/ClassFlowAlignment.h index 14b5c75a..b34908bc 100644 --- a/code/lib/jomjol_flowcontroll/ClassFlowAlignment.h +++ b/code/lib/jomjol_flowcontroll/ClassFlowAlignment.h @@ -12,6 +12,7 @@ class ClassFlowAlignment : { protected: float initalrotate; + bool initialmirror; string reffilename[2]; int ref_x[2], ref_y[2]; int anz_ref; diff --git a/code/lib/jomjol_flowcontroll/ClassFlowPostProcessing.cpp b/code/lib/jomjol_flowcontroll/ClassFlowPostProcessing.cpp index e84c3ff9..c2bff2ff 100644 --- a/code/lib/jomjol_flowcontroll/ClassFlowPostProcessing.cpp +++ b/code/lib/jomjol_flowcontroll/ClassFlowPostProcessing.cpp @@ -12,7 +12,21 @@ string ClassFlowPostProcessing::GetPreValue() { - return to_string(PreValue); + std::string result; + result = to_string(PreValue); + + for (int i = 0; i < ListFlowControll->size(); ++i) + { + if (((*ListFlowControll)[i])->name().compare("ClassFlowAnalog") == 0) + { + int AnzahlNachkomma = ((ClassFlowAnalog*)(*ListFlowControll)[i])->AnzahlROIs(); + std::stringstream stream; + stream << std::fixed << std::setprecision(AnzahlNachkomma) << PreValue; + result = stream.str(); + } + } + + return result; } bool ClassFlowPostProcessing::LoadPreValue(void) diff --git a/code/lib/jomjol_image_proc/CFindTemplate.cpp b/code/lib/jomjol_image_proc/CFindTemplate.cpp index 9edaf088..ca93e8fc 100644 --- a/code/lib/jomjol_image_proc/CFindTemplate.cpp +++ b/code/lib/jomjol_image_proc/CFindTemplate.cpp @@ -44,6 +44,32 @@ void CResizeImage::Resize(int _new_dx, int _new_dy) stbi_image_free(odata); } +void CRotate::Mirror(){ + int memsize = this->width * this->height * this->channels; + uint8_t* odata = (unsigned char*)GET_MEMORY(memsize); + + int x_source, y_source; + stbi_uc* p_target; + stbi_uc* p_source; + + for (int x = 0; x < this->width; ++x) + for (int y = 0; y < this->height; ++y) + { + p_target = odata + (this->channels * (y * this->width + x)); + + x_source = this->width - x; + y_source = y; + + p_source = this->rgb_image + (this->channels * (y_source * this->width + x_source)); + for (int channels = 0; channels < this->channels; ++channels) + p_target[channels] = p_source[channels]; + } + + // memcpy(this->rgb_image, odata, memsize); + this->memCopy(odata, this->rgb_image, memsize); + stbi_image_free(odata); +} + void CRotate::Rotate(float _angle, int _centerx, int _centery) { float m[2][3]; diff --git a/code/lib/jomjol_image_proc/CFindTemplate.h b/code/lib/jomjol_image_proc/CFindTemplate.h index c7b525af..0023d666 100644 --- a/code/lib/jomjol_image_proc/CFindTemplate.h +++ b/code/lib/jomjol_image_proc/CFindTemplate.h @@ -70,6 +70,7 @@ class CRotate: public CImageBasis void Rotate(float _angle); void Rotate(float _angle, int _centerx, int _centery); void Translate(int _dx, int _dy); + void Mirror(); }; diff --git a/code/src/server_tflite.cpp b/code/src/server_tflite.cpp index 84720836..5e32afd7 100644 --- a/code/src/server_tflite.cpp +++ b/code/src/server_tflite.cpp @@ -397,7 +397,7 @@ esp_err_t handler_prevalue(httpd_req_t *req) } if (strlen(_size) == 0) - zw = "Actual PreValue: " + tfliteflow.GetPrevalue(); + zw = tfliteflow.GetPrevalue(); else zw = "SetPrevalue to " + tfliteflow.UpdatePrevalue(_size); diff --git a/firmware/firmware.bin b/firmware/firmware.bin index 96645355..5b19625c 100644 Binary files a/firmware/firmware.bin and b/firmware/firmware.bin differ diff --git a/firmware/html.zip b/firmware/html.zip index 58f56b55..75da32f1 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 ed3b78f0..797f15fa 100644 --- a/sd-card/html/edit_reference.html +++ b/sd-card/html/edit_reference.html @@ -26,6 +26,17 @@ + + + + + + + + + + + Pre-rotate Angle @@ -85,10 +96,13 @@ url = basepath + "/fileserver/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(); document.getElementById("finerotate").disabled = false; document.getElementById("prerotateangle").disabled = false; document.getElementById("updatereferenceimage").disabled = false; document.getElementById("take").disabled = false; + document.getElementById("mirror").disabled = false; + // document.getElementById("ButtonRotate").disabled = false; isActReference = false; loadCanvas(url); @@ -103,7 +117,8 @@ document.getElementById("prerotateangle").disabled = true; document.getElementById("updatereferenceimage").disabled = true; document.getElementById("take").disabled = true; -// document.getElementById("ButtonRotate").disabled = true; + document.getElementById("mirror").disabled = true; + isActReference = true; loadCanvas(url); ParseConfig(); @@ -122,7 +137,8 @@ function SaveReference(){ if (confirm("Are you sure you want to update the reference image?")) { setPreRotate(document.getElementById("prerotateangle").value); - UpdateConfigFile(basepath); + setMirror(document.getElementById("mirror").checked); + UpdateConfigFileReferenceChange(basepath); var canvas = document.getElementById("canvas"); drawRotated(false); SaveCanvasToImage(canvas, "/config/reference.jpg", true, basepath); @@ -162,12 +178,15 @@ canvas.addEventListener('mousemove', mouseMove, false); basepath = getbasepath(); loadConfig(basepath); + ParseConfig(); showReference(); } function drawRotated(_grid = true){ finerot= parseFloat(document.getElementById("finerotate").value); prerot = parseFloat(document.getElementById("prerotateangle").value); + mirror = document.getElementById("mirror").checked; + if (finerot == 1) { prerot+=1 finerot = 0 @@ -185,9 +204,19 @@ context.clearRect(0,0,imageObj.width,imageObj.height); context.save(); - context.translate(imageObj.width/2,imageObj.height/2); - context.rotate(degrees*Math.PI/180); - context.drawImage(imageObj,-imageObj.width/2,-imageObj.height/2); + + if (mirror) { + context.scale(-1, 1); + context.translate(-imageObj.width/2,imageObj.height/2); + context.rotate(-degrees*Math.PI/180); + context.drawImage(imageObj, imageObj.width/2,-imageObj.height/2, -imageObj.width, imageObj.height); + } + else { + context.translate(imageObj.width/2,imageObj.height/2); + context.rotate(degrees*Math.PI/180); + context.drawImage(imageObj,-imageObj.width/2,-imageObj.height/2); + } + context.restore(); if (_grid == true && !isActReference){ drawGrid(); diff --git a/sd-card/html/readconfig.js b/sd-card/html/readconfig.js index 88e13e85..8ed63055 100644 --- a/sd-card/html/readconfig.js +++ b/sd-card/html/readconfig.js @@ -38,7 +38,13 @@ function ParseConfigAlignment(_aktline){ while ((akt_ref < 2) && (_aktline < config_split.length) && (config_split[_aktline][0] != "[")) { var linesplit = ZerlegeZeile(config_split[_aktline]); - if ((linesplit[0] == "InitalRotate") && (linesplit.length > 1)) + if ((linesplit[0].toUpperCase() == "INITIALMIRROR") && (linesplit.length > 1)) + { + initalrotate["mirror"] = linesplit[1].toUpperCase().localeCompare("TRUE") == 0; + initalrotate["pos_config_mirror"] = _aktline; + } + + if (((linesplit[0].toUpperCase() == "INITALROTATE") || (linesplit[0].toUpperCase() == "INITIALROTATE")) && (linesplit.length > 1)) { initalrotate["angle"] = parseInt(linesplit[1]); initalrotate["pos_config"] = _aktline; @@ -131,7 +137,7 @@ function SaveROIToConfig(_ROIInfo, _typeROI, _basepath){ config_split.push(zw); for (var j = config_split.length-2; j > _pos + 1; --j){ config_split[j] = config_split[j-1]; - } + } } for (i = targetROI.length-1; i > _ROIInfo.length-1; --i){ @@ -159,16 +165,16 @@ function ParseConfig() { var aktline = 0; while (aktline < config_split.length){ - if (config_split[aktline].trim() == "[Alignment]") { + if (config_split[aktline].trim().toUpperCase() == "[ALIGNMENT]") { aktline = ParseConfigAlignment(aktline); continue; } - if (config_split[aktline].trim() == "[Digits]") { + if (config_split[aktline].trim().toUpperCase() == "[DIGITS]") { aktline = ParseConfigDigit(aktline); continue; } - if (config_split[aktline].trim() == "[Analog]") { + if (config_split[aktline].trim().toUpperCase() == "[ANALOG]") { aktline = ParseConfigAnalog(aktline); continue; } @@ -185,6 +191,17 @@ function setPreRotate(_prerotate){ initalrotate["angle"] = _prerotate; } +function getMirror(){ + if (initalrotate.hasOwnProperty("mirror")) { + return initalrotate["mirror"]; + } + return false; +} + +function setMirror(_mirror){ + initalrotate["mirror"] = _mirror; +} + function SaveCanvasToImage(_canvas, _filename, _delete = true, _basepath = ""){ var JPEG_QUALITY=0.8; var dataUrl = _canvas.toDataURL('image/jpeg', JPEG_QUALITY); @@ -198,7 +215,11 @@ function SaveCanvasToImage(_canvas, _filename, _delete = true, _basepath = ""){ } function SaveConfigToServer(_basepath){ - FileDeleteOnServer("/config/config.ini", _basepath); + // leere Zeilen am Ende löschen + var zw = config_split.length - 1; + while (config_split[zw] == "") { + config_split.pop(); + } var config_gesamt = ""; for (var i = 0; i < config_split.length; ++i) @@ -206,20 +227,60 @@ function SaveConfigToServer(_basepath){ config_gesamt = config_gesamt + config_split[i] + "\n"; } + FileDeleteOnServer("/config/config.ini", _basepath); + FileSendContent(config_gesamt, "/config/config.ini", _basepath); } -function UpdateConfigFile(_basepath){ +function UpdateConfigFileReferenceChange(_basepath){ for (var _index = 0; _index < ref.length; ++_index){ var zeile = ref[_index]["name"] + " " + ref[_index]["x"] + ", " + ref[_index]["y"]; var _pos = ref[_index]["pos_ref"]; config_split[_pos] = zeile; } - zeile = "InitalRotate=" + initalrotate["angle"]; + zeile = "InitialRotate = " + initalrotate["angle"]; var _pos = initalrotate["pos_config"]; config_split[_pos] = zeile; + var mirror = false; + if (initalrotate.hasOwnProperty("mirror")) { + mirror = initalrotate["mirror"]; + } + var mirror_pos = -1; + if (initalrotate.hasOwnProperty("pos_config_mirror")) { + mirror_pos = initalrotate["pos_config_mirror"]; + } + if (mirror_pos > -1) { + if (mirror) { + config_split[mirror_pos] = "InitialMirror = True"; + } + else { + config_split[mirror_pos] = "InitialMirror = False"; + } + } + else { + if (mirror) { // neue Zeile muss an der richtigen Stelle eingefügt werden - hier direct nach [Alignment] + var aktline = 0; + + while (aktline < config_split.length){ + if (config_split[aktline].trim() == "[Alignment]") { + break; + } + aktline++ + } + + // fuege neue Zeile in config_split ein + var zw = config_split[config_split.length-1]; + config_split.push(zw); + for (var j = config_split.length-2; j > aktline + 1; --j){ + config_split[j] = config_split[j-1]; + } + + config_split[aktline + 1] = "InitialMirror = True" + } + } + SaveConfigToServer(_basepath); } diff --git a/sd-card/html/wasserzaehler_roi.html b/sd-card/html/wasserzaehler_roi.html index bc7dd835..20c01fba 100644 --- a/sd-card/html/wasserzaehler_roi.html +++ b/sd-card/html/wasserzaehler_roi.html @@ -66,7 +66,7 @@ function includeHTML() { - Current Value: + Checked Value: