Files
AI-on-the-edge-device/sd-card/html/edit_digits.html
CaCO3 ca01f5a38f Prepare next release (#3267)
* Create dig-cont_0640_s3_q.tflite

* Update edit_reference.html (#2924)

Zoom-Einstellungen ausblenden, wenn zoom deaktiviert ist

* Update edit_config_template.html (#2925)

Zoom-Einstellungen ausblenden, wenn zoom deaktiviert ist +
Kameraeinstellungen nicht nur in der config.ini speichern, sondern auch setzen

* The parameter "negative" is processed on the MCU

* Renamed menu entry Alignment -> References

* renamed model file to make naming consistent

* Fix test (#2933)

* always reset change absolute (#2956)

* Create dig-class11_1701_s2.tflite

* Update tflite

* Update tflite

* Camera settings (#3029)

* Add files via upload

* Add files via upload

* Add files via upload

* Add files via upload

* Add files via upload

* Add files via upload

* Add files via upload

* Add files via upload

* Fix minor typo and harmonize spaces (#3030)

* Update edit_digits.html

* Update edit_analog.html

* Update overview.html

* Update edit_reference.html

---------

Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>

* Source code formatting, ClassFlowPostProcessing.cpp

* fix edit_config_template.html

Unfortunately, I didn't take out some entries from other experiments because I overlooked/forgot them^^

* fix readconfigparam.js

Unfortunately, I didn't take out some entries from other experiments because I overlooked/forgot them^^

* fix edit_config_template.html

TakeImage_CamZoomMode_value1 was replaced by TakeImage_CamZoomSize_value1, but not deleted.
This caused problems when saving the camera settings.

* Update info.html

function loadWLANSSID() was present three times

* Update overview.html

CamFrameSize is no longer needed/used for zoom

* Update reply-bot.yaml

* homeassistant service discovery: derive node_id when using nested topics (#3088)

* derive correct node_id for homeassistant service discovery in nested topics (fixes #1792)

* explicit use of std::string

* move nodeId creation to separate function
add unit-tests

* add documentation about node_id generation for Home Assistant MQTT Service Discovery

* add Prometheus/OpenMetrics exporter (#3081)

* add prometheus endpoint

* refine metrics implementation

* move metrics generator to ClassFlowControll

* add more metrics
align prefix

* add more metrics
clean up

* refine documentation

* revert dependencies change

* sanitize labels

* create separate module for openmetrics

* move openmetrics to separate folder

* clean up

* add basic unit-tests

* work with const numbers
add replaceAll for string replacement
avoid opening std namespace
adapt unit-tests

* Update code/main/server_main.cpp

---------

Co-authored-by: CaCO3 <caco3@ruinelli.ch>

* Typo

* update platformIO to 6.7.0 (ESP IDF 5.2.1) (#3098)

* update to platformio/espressif32 @ 6.7.0

* remove unused getReadout() as it throws errors (error: 'virtual std::string ClassFlow::getReadout()' was hidden).

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Update reply-bot.yaml (#3107)

* Fix actions-label-commenter

* Update Helper.cpp

* Update Helper.h

* Update Helper.cpp

* Update readconfigparam.js

fix for:
In the selected field the value '1' in the section 'TakeImage' in the field 'CamGainceiling' is invalid. PLEASE CHECK BEFORE SAVING!

* proposal for renaming and documentation (#3115)

* Update server_camera.cpp

 Fix building with -D DEBUG_DETAIL_ON 

better alternative to:
https://github.com/jomjol/AI-on-the-edge-device/pull/3160

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowAlignment.cpp

* Fix building with `-D DEBUG_DETAIL_ON` (#3160)

Building with `-D DEBUG_DETAIL_ON` has been broken since #3029.

Co-authored-by: CaCO3 <caco3@ruinelli.ch>

* Handle empty prevalue.ini gracefully (#3162)

Fixes #2149.

* Bugfix for boot loop (#3175)

* Add files via upload

* Add files via upload

* Add files via upload

* Delete param-docs/parameter-pages/TakeImage/Aec2.md

has been replaced by CamAec2.md

* Delete param-docs/parameter-pages/TakeImage/AutoExposureLevel.md

has been replaced by CamAeLevel.md

* Delete param-docs/parameter-pages/TakeImage/Brightness.md

has been replaced by CamBrightness.md

* Delete param-docs/parameter-pages/TakeImage/Contrast.md

has been replaced by CamContrast.md

* Delete param-docs/parameter-pages/TakeImage/Grayscale.md

has been replaced by CamSpecialEffect.md

* Delete param-docs/parameter-pages/TakeImage/Negative.md

has been replaced by CamSpecialEffect.md

* Delete param-docs/parameter-pages/TakeImage/Saturation.md

has been replaced by CamSaturation.md

* Delete param-docs/parameter-pages/TakeImage/Sharpness.md

has been replaced by CamSharpness.md

* Delete param-docs/parameter-pages/TakeImage/ImageQuality.md

has been replaced by CamQuality.md

* Delete param-docs/parameter-pages/TakeImage/Zoom.md

has been replaced by CamZoom.md

* Delete param-docs/parameter-pages/TakeImage/ZoomMode.md

has been replaced by CamZoomSize.md

* Delete param-docs/parameter-pages/TakeImage/ZoomOffsetX.md

has been replaced by CamZoomOffsetX.md

* Delete param-docs/parameter-pages/TakeImage/ZoomOffsetY.md

has been replaced by CamZoomOffsetY.md

* Delete param-docs/parameter-pages/TakeImage/ImageSize.md

has been replaced by CamZoomSize.md

* Delete param-docs/parameter-pages/TakeImage/FixedExposure.md

has been replaced by CamAec.md

* Delete param-docs/parameter-pages/Alignment/FlipImageSize.md

has been replaced by CamVflip.md

* Delete param-docs/parameter-pages/Alignment/InitialMirror.md

has been replaced by CamHmirror.md

* CamParameter documentation update

https://github.com/jomjol/AI-on-the-edge-device/issues/3185

* typo

* add Webhook #3148 (#3163)

* WIP add Webhook

* fix config html for webhook
add tooltips for webhook

* webhook: fix not enabling webhook

* send webhook as json

* Update ApiKey.md

* webhook: fix only sending last "Number"

* webhook JSON is now closer to the data log in CSV format

* webhook: drop timeStampTimeUTC and switch from timeStamp to lastvalue like lokal csv to fix no timestamp on error

---------

Co-authored-by: CaCO3 <caco3@ruinelli.ch>

* Bugfix for time stamp (#3180)

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowDefineTypes.h

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowPostProcessing.cpp

* Update interface_webhook.cpp

* Update readconfigcommon.js

fix for: The same message("Image Contrast got enhanced") came up with "Update Marker" and "Enhance Image Contrast".

* fix svg favicon 

The svg one got added in 33893eb566 but does not work on Firefox

* Update platformIO to 6.8.1 (Contains ESP IDF 5.3) (#3196)

* Update platformIO to 6.8.1 (ESP IDF 5.3)

* removed now redundant typedef

* updated IDF manifest hash

* Add files via upload

so it should work now

* Update server_main.cpp

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: michael <Heinrich-Tuning@web.de>

* Update MainFlowControl.cpp

* Add support for OV5640 camera (#3063)

* Add support for OV5640 camera

* clean up sharpness handling

* limit sharpness range to -2 and +2

* refactor

* Fix OV3660 sharpness handling

* refactor sharpness handling

* fix OV3660 zoom mode

* reinstate aspect ratio via imageSize

* Changed OV5640 full frame size to match datasheet

* various fixes

* add denoise config and general clean up

* fix line endings to LF

* Support enabling red blue swap via web interface

* update jpeg quality limits

* remove color swap config; color swap workaround dependent on vflip

* fix missing commit

* fix gain ceiling

* Update cam vflip param page

* fix typo: camdenoise, not camsdenoise

* fix compile errors

* Update MainFlowControl.cpp

* Add rate threshold parameter (#3195)

* still needs to be tested

https://github.com/jomjol/AI-on-the-edge-device/issues/3143

* Update ClassFlowPostProcessing.cpp

code formatting

* Update ClassFlowDefineTypes.h

code formatting

* Update ClassFlowPostProcessing.h

code formatting

* Update edit_config_template.html

* fix

* Update config.ini

* Update edit_config_template.html

* Updated param doc

* Rename parameters

* Update edit_config_template.html

* Update NUMBER.ChangeRateThreshold.md

* Update NUMBER.ChangeRateThreshold.md

---------

Co-authored-by: CaCO3 <caco3@ruinelli.ch>

* Update main.cpp

* Update config.ini

Adjusted camera settings to make the image brighter.

* Update readconfigparam.js

Adjusted camera settings to make the image brighter.

* add optional ImageUpload for Webhook (#3174)

* WIP add Webhook

* fix config html for webhook
add tooltips for webhook

* webhook: fix not enabling webhook

* send webhook as json

* Update ApiKey.md

* webhook: fix only sending last "Number"

* webhook JSON is now closer to the data log in CSV format

* webhook: add img upload

* webhoop added config for imgupload

* webhook html fixes

* webhook: drop timeStampTimeUTC and switch from timeStamp to lastvalue like lokal csv to fix no timestamp on error

* add checkbox for Webhook_UploadImg

* Update sd-card/html/edit_config_template.html

* Update edit_config_template.html

* Update edit_config_template.html

* Update edit_config_template.html

* added a long timestamp to both webhook requests

---------

Co-authored-by: CaCO3 <caco3@ruinelli.ch>

* Add files via upload (#3207)

* Update ClassFlowPostProcessing.cpp

deleted some unnecessary double entries
RateType renamed to MaxRateType

* Update ClassFlowDefineTypes.h

RateType renamed to MaxRateType

* Update text on recognition page

* Update digital CNN

* add a Delay between the WiFi reconnections (#3068)

* add a Delay between the WiFi reconnections

* log the delay between the WiFi reconnections

move the delay after the log

* cleanup

* cleanup

* cleanup

* Update edit_alignment.html

* cleanup

* cleanup

* Update platformIO to 6.9.0 (Contains ESP IDF 5.3.1)

* Handle crash on corrupted model (#3220)

* Upgrade esp-tflite-micro to 1.3.1

* Added log message to hint in case it crashes on loading a corrupted model

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* new dig-class100-173-s2-q on 23.800 images (#3257)

* new dig-class100-173-s2-q on 23.800 images

* platformio/espressif32 @ 6.8.1 for esp32cam-dev

* Revert "platformio/espressif32 @ 6.8.1 for esp32cam-dev"

This reverts commit cc9297d483.

* not using platformio 6.1.16

* Revert "not using platformio 6.1.16"

This reverts commit ef18e4fae7.

* moved number edit box styles into new file edit_style.css (#3262)

changed input[type=number] from 60px to 3em, to show 3 digits with current font size.

* added note about only TLS 1.2 is supported (#3213)

* Renamed digital to digit (#3219)

* renamed Digital to Digit

* added param migration

* Update .github/label-commenter-config.yaml

* renamed AnalogDigitTransition* to AnalogToDigitTransition*

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Update Changelog.md

* Update Changelog.md

---------

Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>
Co-authored-by: michael <Heinrich-Tuning@web.de>
Co-authored-by: Frank Haverland <fspapaping@googlemail.com>
Co-authored-by: kub3let <95883234+kub3let@users.noreply.github.com>
Co-authored-by: Marco H <myxor@users.noreply.github.com>
Co-authored-by: Henry Thasler <henrythasler@users.noreply.github.com>
Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: Sebastian Lövdahl <slovdahl@hibox.fi>
Co-authored-by: Raphael Hehl <raphael@rhehl.de>
Co-authored-by: jasaw <jasaw@dius.com.au>
Co-authored-by: Francesco Carnielli <hex7c0@gmail.com>
Co-authored-by: kalwados <kalwados@gmx.de>
2024-09-29 23:22:33 +02:00

1002 lines
36 KiB
HTML

<!DOCTYPE html>
<html lang="en" xml:lang="en">
<head>
<meta charset="UTF-8" />
<title>Digit ROI</title>
<link href="edit_style.css" rel="stylesheet">
<link href="firework.css?v=$COMMIT_HASH" rel="stylesheet">
<script type="text/javascript" src="common.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="jquery-3.6.0.min.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="firework.js?v=$COMMIT_HASH"></script>
</head>
<body style="font-family: arial; padding: 0px 10px;">
<h2>Digit ROI</h2>
<details id="desc_details" style="font-size:16px">
<summary><b>CLICK HERE</b> for usage description. More infos in documentation:
<a href=https://jomjol.github.io/AI-on-the-edge-device-docs/ROI-Configuration/ target=_blank>ROI Configuration</a>
</summary>
<p>
<b>R</b>egion <b>O</b>f <b>I</b>nterest (ROI) for digit numbers can be defined on this page. If no digit numbers need to be processed,
disable digit processing by deselecting <b>"Digit ROI Processing"</b>.
</p>
<p>
By default one number sequence (a number seqence contains of 1-x digit ROIs + 1-x analog counter ROIs which are processed together) is
predefined and already selected in the drop down <b>"Number sequence"</b>. If you need more than one number sequence additional
one's can be added with the buttons next to the drop down. Each number sequence will be processed separately.
</p>
<p>
Using drag and drop by mouse of by manually entering the parameters into the given fields the digit ROIs can be positined to the digit numbers
on the reference image. To have proper ROI definition please check the documentation:
<a href=https://jomjol.github.io/AI-on-the-edge-device-docs/ROI-Configuration/ target=_blank>ROI Configuration</a>. It's very important to be
really precise to have reliable processing. With the drop down <b>"ROI"</b> you can change between the different ROIs in the selected
number sequence. To create new ROIs use <b>"New ROI"</b>.
</p>
<p>
The order of the ROIs defines the position (and therefore the multiplication factor) within the reading sequence. The position
in the number sequence can be changed with the buttons <b>"Move ROI Lower"</b> and <b>"Move ROI Higher"</b>. The multiplication factor which is
shown below the ROI drop down is the multiplication factor of pure position/order in number sequence and the factor right-hand side to this is
the additionally corrected by decimal shift setting (configuration, expert parameter, default: 0).
</p>
<p>
After definition of digit ROIs is completed don't forget to save with the <b>"Save Config"</b> button!<br>
<b>NOTE:</b> There is no need to perform a reboot after every saving or step. It's sufficient to reboot after all configuration steps
(reference image, alignment, ROI configuration) are completed to activate new configuration.
</p>
</details>
<hr />
<p>
<input type="checkbox" id="Category_Digits_enabled" value="1" onclick = 'EnDisableDigits()' checked>
<label style="font-weight: bold; font-size: larger;" for="Category_Digits_enabled">Digit ROI Processing</label>
</p>
<div id="div1">
<table>
<colgroup>
<col span="1" style="width: 22%;">
<col span="1" style="width: 26%;">
<col span="1" style="width: 26%;">
<col span="1" style="width: 26%;">
</colgroup>
<tr>
<td colspan="4" style="padding: 0px"><class id="Numbers_text" style="color:black;">Number Sequence:</class></td>
</tr>
<tr>
<td>
<select id="Numbers_value1" onchange="numberChanged()">
</select>
</td>
<td>
<input class="button" type="submit" id="newNumber" name="newNumber" onclick="newNumber()" value="New Sequence">
</td>
<td>
<input class="button" type="submit" id="renameNumber" name="renameNumber" onclick="renameNumber()" value="Rename Sequence">
</td>
<td>
<input class="button" type="submit" id="removeNumber" name="removeNumber" onclick="removeNumber()" value="Delete Sequence">
</td>
</tr>
</table>
<hr />
<table>
<colgroup>
<col span="1" style="width: 22%;">
<col span="1" style="width: 26%;">
<col span="1" style="width: 26%;">
<col span="1" style="width: 26%;">
</colgroup>
<tr>
<td style="padding: 0px">ROI:</td>
</tr>
<tr>
<td>
<select id="index" name="index" onchange="ChangeSelection()" tabindex=1></select>
</td>
<td>
<input class="button" type="submit" id="newROI" name="newROI" onclick="newROI()" value="New ROI">
</td>
<td>
<input class="button" type="submit" id="renameROI" name="renameROI" onclick="renameROI()" value="Rename ROI">
</td>
<td>
<input class="button" type="submit" id="deleteROI" name="deleteROI" onclick="deleteROI()" value="Delete ROI">
</td>
</tr>
<tr>
<td class="multiplier">Multiplier: <output type="text" id="multiplier" name="multiplier"></output><br>
(only based on order)
</td>
<td class="multiplier">Multiplier: <output type="text" id="multiplier_decshift" name="multiplier_decshift"></output><br>
(order + decimal shift: <output type="text" id="decimalShift" name="decimalShift"></output>)
</td>
<td>
<input class="button" type="submit" id="movePrevious" onclick="movePrevious()" value="Move ROI Higher">
</td>
<td>
<input class="button" type="submit" id="moveNext" onclick="moveNext()" value="Move ROI Lower">
</td>
</tr>
</table>
<table>
<colgroup>
<col span="1" style="width: 18%;">
<col span="1" style="width: 18%;">
<col span="1" style="width: 64%;">
</colgroup>
<tr>
<td>x: <input type="number" name="refx" id="refx" step=1 onchange="valuemanualchanged()" tabindex=2></td>
<td>Δx: <input type="number" name="refdx" id="refdx" step=1 onchange="valuemanualchangeddx()" tabindex=4></td>
</tr>
<tr>
<td>y: <input type="number" name="refy" id="refy" step=1 onchange="valuemanualchanged()" tabindex=3></td>
<td>Δy: <input type="number" name="refdy" id="refdy" step=1 onchange="valuemanualchanged()" tabindex=5></td>
</tr>
</table>
</div>
<hr>
The following settings are only used for easier setup, they are <b>not</b> persisted on the device:<br>
<input type="checkbox" id="showall" name="showall" value="1" onclick="draw()" checked tabindex=10><label for="showall">Show all ROIs</label><br>
<input type="checkbox" id="lockAspectRatio" name="lockAspectRatio" value="1" onclick="changelockAspectRatio()" checked tabindex=6><label for="lockAspectRatio"> Lock aspect ratio </label><br>
<input type="checkbox" id="lockSizes" name="lockSizes" value="1" onclick="changelockSizes()" checked tabindex=7><label for="lockSizes"> Synchronize y, Δx and Δy between ROIs</label><br>
<input type="checkbox" id="lockSpaceEquidistant" name="lockSpaceEquidistant" value="1" onclick="changeLockSpaceEquidistant()" checked tabindex=8>
<label for="lockSpaceEquidistant">Keep equidistance of <input type="number" name="space" id="space" maxlength="2" max=99 step=1 onchange="valuemanualchangedspace()" tabindex=9> between all ROIs</label><br>
<hr>
<table>
<colgroup>
<col span="1" style="width: 22%;">
<col span="1" style="width: 26%;">
<col span="1" style="width: 26%;">
<col span="1" style="width: 26%;">
</colgroup>
<tr>
<td colspan="3" style="vertical-align: bottom;"><b>Reference Image:</b></td>
<td>
<input style="font-weight:bold;" class="button" type="submit" id="saveroi" name="saveroi" onclick="SaveToConfig()" value="Save Config" tabindex=11>
</td>
</tr>
<tr>
<td colspan="4"><canvas id="canvas" crossorigin></canvas></td>
</tr>
</table>
<script type="text/javascript" src="readconfigparam.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="readconfigcommon.js?v=$COMMIT_HASH"></script>
<script type="text/javascript">
var canvas = document.getElementById('canvas'),
imageObj = new Image(),
rect = {},
drag = false,
aktindex = 0,
ROIInfo,
cofcat,
param,
_roialt = "dig",
enhanceCon = false,
lockAspectRatio = true,
lockSizes = false,
lockSpaceEquidistant = true,
space = 3,
domainname = getDomainname();
function doReboot() {
if (confirm("Are you sure you want to reboot? Did you save your changes?")) {
var stringota = getDomainname() + "/reboot";
window.location = stringota;
window.location.href = stringota;
window.location.assign(stringota);
window.location.replace(stringota);
}
}
function EnDisableDigits() {
isEnabled = document.getElementById("Category_Digits_enabled").checked;
$("#div2").attr("disabled", "disabled").off('click');
var x1=$("#div2").hasClass("disabledDiv");
if (isEnabled) {
$("#div2").removeClass("disabledDiv");
}
else {
$("#div2").addClass("disabledDiv");
}
sah1(document.getElementById("div1"), !isEnabled);
cofcat["Digits"]["enabled"] = isEnabled;
document.getElementById("saveroi").disabled = false;
if (isEnabled) {
UpdateROIs();
}
}
function sah1(el, _target) {
try {
el.disabled = _target;
} catch (E) {}
if (el.childNodes && el.childNodes.length > 0) {
for (var x = 0; x < el.childNodes.length; x++) {
sah1(el.childNodes[x], _target);
}
}
}
function onNameChange() {
ROIInfo[aktindex]["name"] = document.getElementById("name").value;
UpdateROIs();
}
function deleteROI() {
if (!confirm("Delete the selected ROI?")) {
return; //break out of the function early because prompt was aborted
}
ROIInfo.splice(aktindex, 1);
if (aktindex > ROIInfo.length - 1){
aktindex = ROIInfo.length - 1;
}
UpdateROIs();
draw();
}
function newROI() {
var sel = document.getElementById("Numbers_value1");
var _number= sel.options[sel.selectedIndex].text;
sel = document.getElementById("index");
if (ROIInfo.length > 0) {
_roialt = sel.options[sel.selectedIndex].text;
}
else {
_roialt = "dig";
}
var _roinew = prompt("Please enter a name for the new ROI", _roialt);
if (_roinew === null) {
return; //break out of the function early because prompt was aborted
}
if (ROIInfo.length > 0) {
if (ROIInfo.length > 1) {
space = ROIInfo[1].x - parseInt(ROIInfo[0].x) - parseInt(ROIInfo[0].dx);
}
erg = CreateROI(_number, "digit", sel.selectedIndex, _roinew, parseInt(ROIInfo[sel.selectedIndex].x) + parseInt(ROIInfo[sel.selectedIndex].dx) + space,
parseInt(ROIInfo[sel.selectedIndex].y), ROIInfo[aktindex]["dx"], ROIInfo[aktindex]["dy"], 0);
}
else {
erg = CreateROI(_number, "digit", sel.selectedIndex, _roinew, 15, 30, 30, 51, 0);
}
if (erg != "") {
firework.launch(erg, 'danger', 30000);
}
else {
UpdateROIs(_roinew);
// Shift all ROIs on right side to the right
for (var _nb = sel.selectedIndex + 1; _nb < ROIInfo.length; _nb++) {
ROIInfo[_nb].x = parseInt(ROIInfo[_nb].x) + parseInt(ROIInfo[_nb].dx) + space;
}
draw();
}
}
function movePrevious() {
var zw = ROIInfo[aktindex];
ROIInfo[aktindex] = ROIInfo[aktindex-1];
ROIInfo[aktindex-1] = zw;
aktindex--;
UpdateROIs();
valuemanualchanged();
}
function moveNext() {
var zw = ROIInfo[aktindex];
ROIInfo[aktindex] = ROIInfo[aktindex+1];
ROIInfo[aktindex+1] = zw;
aktindex++;
UpdateROIs();
valuemanualchanged();
}
function changelockAspectRatio() {
lockAspectRatio = document.getElementById("lockAspectRatio").checked;
}
function changelockSizes() {
lockSizes = document.getElementById("lockSizes").checked;
UpdateROIs();
valuemanualchangedspace();
if (!lockSizes) {
firework.launch("In most cases it's advised to keep the y, Δx and Δy identical!", 'warning', 10000);
}
}
function changeLockSpaceEquidistant() {
lockSpaceEquidistant = document.getElementById("lockSpaceEquidistant").checked;
if (!lockSpaceEquidistant) {
document.getElementById("space").disabled = true;
}
else {
document.getElementById("space").disabled = false;
}
UpdateROIs();
}
function ChangeSelection() {
aktindex = parseInt(document.getElementById("index").value);
//lockAspectRatio = true;
UpdateROIs();
}
function SaveToConfig() {
if (confirm("Are you sure you want to save the new digit ROI configuration?")) {
// _zwcat = getConfigCategory();
cofcat["Digits"]["enabled"] = document.getElementById("Category_Digits_enabled").checked;
WriteConfigININew();
SaveConfigToServer(domainname);
UpdateROIs();
document.getElementById("saveroi").disabled = true;
firework.launch('Configuration saved. It will get applied after next reboot', 'success', 5000);
}
}
function ShowMultiplier() {
var decimalShift = 0;
var multiplier;
var multiplier_decshift;
var fixedDecimals_decshift;
var NumberInfo = getNUMBERInfo();
var sel = document.getElementById("Numbers_value1");
var _number= sel.options[sel.selectedIndex].text;
document.getElementById("decimalShift").value = 0;
for (var i = 0; i < NumberInfo.length; ++i) {
if (NumberInfo[i]["name"] == _number) {
if (NumberInfo[i]["PostProcessing"]["DecimalShift"]["enabled"]) {
decimalShift = NumberInfo[i]["PostProcessing"]["DecimalShift"]["value1"];
document.getElementById("decimalShift").value = decimalShift;
}
}
}
multiplier = ROIInfo.length - 1 - aktindex;
multiplier_decshift = fixedDecimals_decshift = multiplier + Number(decimalShift);
if (multiplier_decshift > 0) {
fixedDecimals_decshift = 0;
}
if (fixedDecimals_decshift < 0) {
fixedDecimals_decshift = -1*fixedDecimals_decshift;
}
document.getElementById("multiplier").value="x" + Number(10 ** multiplier).toFixed(0);
document.getElementById("multiplier_decshift").value="x" + Number(10 ** multiplier_decshift).toFixed(fixedDecimals_decshift);
}
function UpdateROIs(_sel){
document.getElementById("Category_Digits_enabled").checked = true;
var sel = document.getElementById("Numbers_value1");
var _number = sel.options[sel.selectedIndex].text;
ROIInfo = getROIInfo("digit", _number);
// _catzw = getConfigCategory();
if (cofcat["Digits"]["enabled"] == false) {
document.getElementById("Category_Digits_enabled").checked = false;
EnDisableDigits();
firework.launch('Digit ROI processing is disabled. Activate with checkbox if needed', 'warning', 10000);
return;
}
if (ROIInfo.length == 0){
firework.launch('No digit ROIs defined in selected number sequence', 'warning', 10000);
document.getElementById("newROI").disabled = false;
document.getElementById("deleteROI").disabled = true;
document.getElementById("renameROI").disabled = true;
document.getElementById("index").disabled = true;
document.getElementById("multiplier").style.display = "none";
document.getElementById("multiplier_decshift").style.display = "none";
document.getElementById("refx").disabled = true;
document.getElementById("refdx").disabled = true;
document.getElementById("refy").disabled = true;
document.getElementById("refdy").disabled = true;
document.getElementById("lockSizes").disabled = true;
document.getElementById("lockAspectRatio").disabled = true;
document.getElementById("showall").disabled = true;
document.getElementById("lockSpaceEquidistant").disabled = true;
document.getElementById("moveNext").disabled = true;
document.getElementById("movePrevious").disabled = true;
document.getElementById("saveroi").disabled = false;
return;
}
else {
document.getElementById("newROI").disabled = false;
document.getElementById("deleteROI").disabled = false;
document.getElementById("renameROI").disabled = false;
document.getElementById("index").disabled = false;
document.getElementById("multiplier").style.display = "";
document.getElementById("multiplier_decshift").style.display = "";
document.getElementById("refx").disabled = false;
document.getElementById("refdx").disabled = false;
document.getElementById("refy").disabled = false;
document.getElementById("refdy").disabled = false;
document.getElementById("lockSizes").disabled = false;
document.getElementById("showall").disabled = false;
document.getElementById("lockAspectRatio").disabled = false;
document.getElementById("lockSpaceEquidistant").disabled = false;
document.getElementById("saveroi").disabled = false;
}
var _index = document.getElementById("index");
while (_index.length){
_index.remove(0);
}
if (aktindex > ROIInfo.length) {
aktindex = ROIInfo.length-1;
}
for (var i = 0; i < ROIInfo.length; ++i){
var option = document.createElement("option");
option.text = ROIInfo[i]["name"];
option.value = i;
_index.add(option);
if (typeof _sel !== 'undefined') {
if (option.text == _sel) {
aktindex = i;
}
}
}
_index.selectedIndex = aktindex;
document.getElementById("movePrevious").disabled = false;
if (aktindex == 0){
document.getElementById("movePrevious").disabled = true;
}
document.getElementById("moveNext").disabled = false;
if (aktindex == (ROIInfo.length-1)){
document.getElementById("moveNext").disabled = true;
}
ShowMultiplier();
document.getElementById("lockAspectRatio").checked = lockAspectRatio;
document.getElementById("lockSizes").checked = lockSizes;
document.getElementById("lockSpaceEquidistant").checked = lockSpaceEquidistant;
document.getElementById("space").value = space;
if (!lockSpaceEquidistant) {
document.getElementById("space").disabled = true;
}
else {
document.getElementById("space").disabled = false;
}
document.getElementById("refx").value = ROIInfo[aktindex]["x"];
document.getElementById("refy").value = ROIInfo[aktindex]["y"];
document.getElementById("refdx").value = ROIInfo[aktindex]["dx"];
document.getElementById("refdy").value = ROIInfo[aktindex]["dy"];
rect.startX = ROIInfo[aktindex]["x"];
rect.startY = ROIInfo[aktindex]["y"];
rect.w = ROIInfo[aktindex]["dx"];
rect.h = ROIInfo[aktindex]["dy"];
draw();
}
function loadCanvas(dataURL) {
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
imageObj.onload = function() {
canvas.width = this.width;
canvas.height = this.height;
drawImage();
draw();
};
imageObj.src = dataURL;
}
function getCoords(elem) {
// crossbrowser version
var box = elem.getBoundingClientRect();
var body = document.body;
var docEl = document.documentElement;
var scrollTop = window.pageYOffset || docEl.scrollTop || body.scrollTop;
var scrollLeft = window.pageXOffset || docEl.scrollLeft || body.scrollLeft;
var clientTop = docEl.clientTop || body.clientTop || 0;
var clientLeft = docEl.clientLeft || body.clientLeft || 0;
var top = box.top + scrollTop - clientTop;
var left = box.left + scrollLeft - clientLeft;
return { top: Math.round(top), left: Math.round(left) };
}
/* hash #description open the details part of the page */
function openDescription() {
if(window.location.hash) {
var hash = window.location.hash.substring(1); //Puts hash in variable, and removes the # character
if(hash == 'description') {
document.getElementById("desc_details").open = false;
}
}
}
function init() {
openDescription();
domainname = getDomainname();
if (!loadConfig(domainname)) {
firework.launch('Configuration could not be loaded! Please reload the page!', 'danger', 30000);
return;
}
ParseConfig();
param = getConfigParameters();
cofcat = getConfigCategory();
canvas.addEventListener('mousedown', mouseDown, false);
canvas.addEventListener('mouseup', mouseUp, false);
canvas.addEventListener('mousemove', mouseMove, false);
loadCanvas(domainname + "/fileserver/config/reference.jpg");
UpdateNUMBERS();
/* Check if the ROIs are equidistant. Only if not, untick the checkbox */
if (ROIInfo.length > 1) {
var distanceROI0_to_ROI1 = parseInt(ROIInfo[1].x) - (parseInt(ROIInfo[0].x) + parseInt(ROIInfo[0].dx)); // Distance between 1st and 2nd ROI
//console.log("0->1: " + distanceROI0_to_ROI1);
for (var i = 1; i < (ROIInfo.length - 1); ++i) { // 2nd .. 2nd-last ROI
//console.log(i + "->" + i+1 + ": " + (parseInt(ROIInfo[i+1].x) - (parseInt(ROIInfo[i].x) + parseInt(ROIInfo[i].dx))));
if (distanceROI0_to_ROI1 != (parseInt(ROIInfo[i+1].x) - (parseInt(ROIInfo[i].x) + parseInt(ROIInfo[i].dx)))) {
console.log("Not equidistant, unticking the checkbox!");
lockSpaceEquidistant = false;
document.getElementById("lockSpaceEquidistant").checked = lockSpaceEquidistant;
if (!lockSpaceEquidistant) {
document.getElementById("space").disabled = true;
}
else {
document.getElementById("space").disabled = false;
}
break;
}
}
}
/* Check if the ROIs have same y, dy and dx. If so, tick the sync checkbox */
var all_y_dx_dy_Identical = true;
if (ROIInfo.length > 1) {
for (var i = 1; i < (ROIInfo.length); ++i) { // 2nd .. last ROI
if (parseInt(ROIInfo[i].y) != parseInt(ROIInfo[0].y) ||
parseInt(ROIInfo[i].dx) != parseInt(ROIInfo[0].dx) ||
parseInt(ROIInfo[i].dy) != parseInt(ROIInfo[0].dy)) {
all_y_dx_dy_Identical = false;
break;
}
}
}
if (all_y_dx_dy_Identical) {
lockSizes = true;
console.log("All ROI have the same Y, dX and dY, ticking the sync checkbox!");
document.getElementById("lockSizes").checked = lockSizes;
}
else {
console.log("Not all ROI have the same Y, dX and dY, unticking the sync checkbox!");
}
if (ROIInfo.length > 1) {
space = ROIInfo[1].x - parseInt(ROIInfo[0].x) - parseInt(ROIInfo[0].dx);
document.getElementById("space").value = space;
}
document.getElementById("saveroi").disabled = true;
drawImage();
draw();
}
function drawImage() {
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
context.clearRect(0,0,imageObj.width,imageObj.height);
context.save();
context.drawImage(imageObj, 0, 0);
// context.restore();
}
function UpdateNUMBERS(_sel) {
zw = getNUMBERInfo();
index = 0;
var _index = document.getElementById("Numbers_value1");
while (_index.length){
_index.remove(0);
}
for (var i = 0; i < zw.length; ++i) {
var option = document.createElement("option");
option.text = zw[i]["name"];
option.value = i;
_index.add(option);
if (typeof _sel !== 'undefined') {
if (zw[i]["name"] == _sel) {
index = i;
}
}
}
_index.selectedIndex = index;
UpdateROIs();
}
function renameNumber() {
var sel = document.getElementById("Numbers_value1");
var _delete= sel.options[sel.selectedIndex].text;
var _numbernew = prompt("Please enter a new name for the selected number sequence", _delete);
if (_numbernew === null) {
return; //break out of the function early because prompt was aborted
}
erg = RenameNUMBER(_delete, _numbernew);
if (erg != "") {
firework.launch(erg, 'danger', 30000);
}
else {
UpdateNUMBERS(_numbernew);
}
}
function newNumber() {
var _numbernew = prompt("Please enter a name for the new number sequence", "name");
if (_numbernew === null) {
return; //break out of the function early because prompt was aborted
}
erg = CreateNUMBER(_numbernew);
if (erg != "") {
firework.launch(erg, 'danger', 30000);
}
else {
UpdateNUMBERS(_numbernew);
}
}
function removeNumber() {
if (confirm("The entire number sequence will be removed (digit + analog parts). " +
"To remove single ROI of the number sequence, use \"Delete ROI\" instead.\n" +
"Do you really want to proceed?")) {
var sel = document.getElementById("Numbers_value1");
var _delete= sel.options[sel.selectedIndex].text;
erg = DeleteNUMBER(_delete);
if (erg != "") {
firework.launch(erg, 'danger', 30000);
}
UpdateNUMBERS();
}
}
function drawTextBG(context, txt, x, y, padding) {
context.font = "15px Arial";
context.textAlign = "center";
context.fillStyle = 'rgba(255, 0, 0, 0.5)';
var width = context.measureText(txt).width;
context.fillRect(x-(width+padding)/2, y-12, width + padding*2, parseInt(context.font, 10) + padding);
context.fillStyle = "black";
context.fillText(txt, x + padding / 2, y + padding / 2);
}
function draw() {
if (typeof ROIInfo === 'undefined') { // During init, ROIInfo is not defined yet
return;
}
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
context.drawImage(imageObj, 0, 0);
if (ROIInfo.length == 0) {
return;
}
if (document.getElementById("Category_Digits_enabled").checked) {
var sel = document.getElementById("index");
var _number = sel.selectedIndex;
if (lockSizes) {
// Synchronize Y, dx and dy
for (var _nb = 0; _nb < ROIInfo.length; _nb++) {
if (_nb != _number) {
ROIInfo[_nb].y = rect.startY;
ROIInfo[_nb].dy = rect.h;
ROIInfo[_nb].dx = rect.w;
}
}
}
if (document.getElementById("showall").checked) {
for (var _nb = 0; _nb < ROIInfo.length; _nb++) {
if (_nb != _number) {
lw = 2;
context.lineWidth = lw;
context.strokeStyle = "#990000";
var x0 = parseInt(ROIInfo[_nb].x) - parseInt(lw/2);
var y0 = parseInt(ROIInfo[_nb].y) - parseInt(lw/2);
var dx = parseInt(ROIInfo[_nb].dx) + parseInt(lw);
var dy = parseInt(ROIInfo[_nb].dy) + parseInt(lw);
context.strokeRect(x0, y0, dx, dy);
drawTextBG(context, ROIInfo[_nb]["name"], x0+dx/2, y0-12, 5);
lw = 1
var x0 = parseInt(ROIInfo[_nb].x) - parseInt(lw/2);
var y0 = parseInt(ROIInfo[_nb].y) - parseInt(lw/2);
var dx = parseInt(ROIInfo[_nb].dx) + parseInt(lw);
var dy = parseInt(ROIInfo[_nb].dy) + parseInt(lw);
context.lineWidth = lw;
context.beginPath();
context.moveTo(x0, y0+dy/2);
context.lineTo(x0+dx, y0+dy/2);
context.stroke();
context.strokeRect(x0+dx*0.2, y0+dy*0.2, dx*0.6, dy*0.6);
}
}
}
lw = 4
context.lineWidth = lw;
context.strokeStyle = "#FF0000";
var x0 = parseInt(rect.startX) - parseInt(lw/2);
var y0 = parseInt(rect.startY) - parseInt(lw/2);
var dx = parseInt(rect.w) + parseInt(lw);
var dy = parseInt(rect.h) + parseInt(lw);
context.strokeRect(x0, y0, dx, dy);
drawTextBG(context, ROIInfo[aktindex]["name"], x0+dx/2, y0-11, 5);
context.lineWidth = 1;
context.strokeRect(x0+dx*0.2, y0+dy*0.2, dx*0.6, dy*0.6);
context.lineWidth = 2;
context.beginPath();
context.moveTo(x0, y0+dy/2);
context.lineTo(x0+dx, y0+dy/2);
context.stroke();
ROIInfo[aktindex]["x"] = rect.startX;
ROIInfo[aktindex]["y"] = rect.startY;
ROIInfo[aktindex]["dx"] = rect.w;
ROIInfo[aktindex]["dy"] = rect.h;
}
}
function mouseDown(e) {
zw = getCoords(this)
rect.startX = e.pageX - zw.left;
rect.startY = e.pageY - zw.top;
document.getElementById("refx").value = rect.startX;
document.getElementById("refy").value = rect.startY;
drag = true;
}
function mouseUp() {
drag = false;
if (rect.w < 0) {
rect.w = -rect.w
rect.startX-=rect.w
}
if (rect.h < 0) {
rect.h = -rect.h
rect.startY-=rect.h
}
document.getElementById("refdx").value = rect.w;
document.getElementById("refdy").value = rect.h;
document.getElementById("refx").value = rect.startX;
document.getElementById("refy").value = rect.startY;
}
function mouseMove(e) {
if (drag) {
zw = getCoords(this)
if (ROIInfo.length == 0) {
return;
}
if (lockAspectRatio) {
rect.h = (e.pageY - zw.top) - rect.startY;
rect.w = Math.round(rect.h * ROIInfo[aktindex]["ar"]);
}
else {
rect.w = (e.pageX - zw.left) - rect.startX;
rect.h = (e.pageY - zw.top) - rect.startY;
}
document.getElementById("refdx").value = rect.w;
document.getElementById("refdy").value = rect.h;
draw();
}
else {
draw();
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
zw = getCoords(this);
x = e.pageX - zw.left;
y = e.pageY - zw.top;
context.lineWidth = 2;
context.strokeStyle = "#00FF00";
context.beginPath();
context.moveTo(0,y);
context.lineTo(canvas.width, y);
context.moveTo(x, 0);
context.lineTo(x, canvas.height);
context.stroke();
}
}
function valuemanualchanged() {
if (ROIInfo.length == 0) {
return;
}
if (!drag) {
rect.w = document.getElementById("refdx").value;
rect.h = document.getElementById("refdy").value;
if (lockAspectRatio) {
rect.w = Math.round(rect.h * ROIInfo[aktindex]["ar"]);
document.getElementById("refdx").value = rect.w;
}
rect.startX = document.getElementById("refx").value;
rect.startY = document.getElementById("refy").value;
if (lockSpaceEquidistant) {
makeX_SpaceEquidistant();
}
draw();
}
document.getElementById("saveroi").disabled = false;
}
function valuemanualchangeddx() {
if (ROIInfo.length == 0) {
return;
}
if (!drag) {
rect.w = document.getElementById("refdx").value;
rect.h = document.getElementById("refdy").value;
if (lockAspectRatio) {
rect.h = Math.round(rect.w / ROIInfo[aktindex]["ar"]);
document.getElementById("refdy").value = rect.h;
}
rect.startX = document.getElementById("refx").value;
rect.startY = document.getElementById("refy").value;
if (lockSpaceEquidistant) {
makeX_SpaceEquidistant();
}
draw();
}
document.getElementById("saveroi").disabled = false;
}
function valuemanualchangedspace() {
if (!drag) {
space = document.getElementById("space").value;
valuemanualchanged();
draw();
}
}
// Make all X spaces equidistant
function makeX_SpaceEquidistant() {
if (ROIInfo.length <= 1) { // Only one or no number
return;
}
var sel = document.getElementById("index");
var _number = sel.selectedIndex;
if (_number == 0) { // First number
for (var _nb = 1; _nb < ROIInfo.length; _nb++) {
ROIInfo[_nb].x = parseInt(ROIInfo[_nb-1].x) + parseInt(ROIInfo[_nb-1].dx) + parseInt(space);
}
}
else { // In between
for (var _nb = _number - 1; _nb >= 0 ; _nb--) { // left side
ROIInfo[_nb].x = parseInt(ROIInfo[_nb+1].x) - parseInt(ROIInfo[_nb].dx) - parseInt(space);
}
for (var _nb = _number + 1; _nb < ROIInfo.length; _nb++) { // right side
ROIInfo[_nb].x = parseInt(ROIInfo[_nb-1].x) + parseInt(ROIInfo[_nb-1].dx) + parseInt(space);
}
}
}
function renameROI() {
var sel = document.getElementById("Numbers_value1");
var _number= sel.options[sel.selectedIndex].text;
sel = document.getElementById("index");
_roialt= sel.options[sel.selectedIndex].text;
var _roinew = prompt("Please enter a new name for the selected ROI", _roialt);
if (_roinew === null) {
return; //break out of the function early because prompt was aborted
}
erg = RenameROI(_number, "digit", _roialt, _roinew);
if (erg != "") {
firework.launch(erg, 'danger', 30000);
}
else {
UpdateROIs(_roinew);
}
}
function numberChanged() {
aktindex = 0;
UpdateROIs();
}
init();
</script>
</body>
</html>