mirror of
https://github.com/jomjol/AI-on-the-edge-device.git
synced 2025-12-18 13:38:15 +03:00
Compare commits
64 Commits
low-power-
...
v15.7.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0d0b0187f4 | ||
|
|
4cf9ea6c45 | ||
|
|
1b76e0f449 | ||
|
|
d4a0ad20ff | ||
|
|
df72445e79 | ||
|
|
456cb93809 | ||
|
|
d968a7adc6 | ||
|
|
9a52b8b2f3 | ||
|
|
8caa852bbf | ||
|
|
4faca4c46c | ||
|
|
238fc5fae3 | ||
|
|
c32ca5a23c | ||
|
|
827d9d1700 | ||
|
|
0ea4b3b3ce | ||
|
|
3e26c6c743 | ||
|
|
fa5c99b3cb | ||
|
|
6feae4e239 | ||
|
|
ef64be3888 | ||
|
|
cc89d625f2 | ||
|
|
08ba754b88 | ||
|
|
6b38e44d7f | ||
|
|
141aea7fa7 | ||
|
|
bcd07761b6 | ||
|
|
fe4d861e15 | ||
|
|
71322c9fbe | ||
|
|
f8b4881a50 | ||
|
|
438d5696e4 | ||
|
|
0d391c8780 | ||
|
|
59de6319a1 | ||
|
|
3805687219 | ||
|
|
c6a789dc45 | ||
|
|
246f9cfc31 | ||
|
|
b2d8c60bb1 | ||
|
|
1d573cd18a | ||
|
|
b2e5cdd8a3 | ||
|
|
f7fde7c430 | ||
|
|
2c19080a66 | ||
|
|
35663c5fd4 | ||
|
|
5b449d5c45 | ||
|
|
3a5f3496d5 | ||
|
|
00434d01c3 | ||
|
|
3e0bb81e32 | ||
|
|
4f57f9eafd | ||
|
|
f24ec581e6 | ||
|
|
0d78bb78ea | ||
|
|
47aea007b3 | ||
|
|
284b3f428e | ||
|
|
92d45c7971 | ||
|
|
ff1d9d3b4f | ||
|
|
2b57dd0853 | ||
|
|
dd8f5eea22 | ||
|
|
60c5305378 | ||
|
|
8b1c65a38a | ||
|
|
4f5933c4f2 | ||
|
|
06c9bfb0de | ||
|
|
69f1a99b55 | ||
|
|
a8fb88a35d | ||
|
|
d418d22155 | ||
|
|
53e8cf49f9 | ||
|
|
ac4f823cbf | ||
|
|
444dc0fa39 | ||
|
|
5053a31245 | ||
|
|
44cf8933d4 | ||
|
|
35de56be04 |
@@ -1,5 +1,5 @@
|
||||
# Reply Bot
|
||||
# It uses the configuration in .github/label-commenter-config.yml
|
||||
# It uses the configuration in .github/label-commenter-config.yaml
|
||||
# See https://github.com/peaceiris/actions-label-commenter
|
||||
|
||||
name: Reply-Bot
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
|
||||
####################################################################
|
||||
## Remove labels again (issues only)
|
||||
## Make sure to also add the reply message to .github/label-commenter-config.yml!
|
||||
## Make sure to also add the reply message to .github/label-commenter-config.yaml!
|
||||
## This currently seems no longer to work due to changes on the actions-cool/issues-helper!
|
||||
####################################################################
|
||||
# - name: Remove 'Logfile' label again (issues only)
|
||||
@@ -74,6 +74,7 @@ jobs:
|
||||
## Write the response
|
||||
####################################################################
|
||||
- name: Write Response
|
||||
uses: peaceiris/actions-label-commenter@c2d00660c86f2b9ed0fb35b372c451558eba85b3
|
||||
uses: peaceiris/actions-label-commenter@v1
|
||||
with:
|
||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
github_token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
config_file: .github/label-commenter-config.yaml
|
||||
17
Changelog.md
17
Changelog.md
@@ -1,3 +1,18 @@
|
||||
## [15.7.0] - 2024-02-17
|
||||
|
||||
For a full list of changes see [Full list of changes](https://github.com/jomjol/AI-on-the-edge-device/compare/v15.6.0...v15.7.0)
|
||||
|
||||
#### Core Changes
|
||||
- Added new camera settings (See `Settings > Alignment > Reference Image and Camera Settings`). You might need to re-create the reference image and alignment marks. Note worthy:
|
||||
- You can now crop the image
|
||||
- Support to configure sharpness, grayscale, negatoive and exposure
|
||||
- Enhanced various WebUI pages with better explanations and usability
|
||||
- Add Firmware Version to MQTT
|
||||
|
||||
#### Bug Fixes
|
||||
- Reverted "Implemented late analog / digital transition [#2778](https://github.com/jomjol/AI-on-the-edge-device/pull/2778) (introduced in `v15.5`) as is seems to cause issues for many users.
|
||||
|
||||
|
||||
## [15.6.0] - 2024-02-09
|
||||
|
||||
For a full list of changes see [Full list of changes](https://github.com/jomjol/AI-on-the-edge-device/compare/v15.5.0...v15.6.0)
|
||||
@@ -43,6 +58,8 @@ For a full list of changes see [Full list of changes](https://github.com/jomjol/
|
||||
- dig-class11_1700_s2.tflite
|
||||
- ana-cont_1208_s2_q.tflite
|
||||
|
||||
- Added config entries for MQTT TLS
|
||||
|
||||
|
||||
#### Fixed
|
||||
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
#include "driver/ledc.h"
|
||||
#include "MainFlowControl.h"
|
||||
|
||||
#include "ov2640_sharpness.h"
|
||||
|
||||
#if (ESP_IDF_VERSION_MAJOR >= 5)
|
||||
#include "soc/periph_defs.h"
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
@@ -53,6 +55,10 @@ static const char* _STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary="
|
||||
static const char* _STREAM_BOUNDARY = "\r\n--" PART_BOUNDARY "\r\n";
|
||||
static const char* _STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: %u\r\n\r\n";
|
||||
|
||||
// OV2640 Camera SDE Indirect Register Access
|
||||
#define OV2640_IRA_BPADDR 0x7C
|
||||
#define OV2640_IRA_BPDATA 0x7D
|
||||
|
||||
|
||||
static camera_config_t camera_config = {
|
||||
.pin_pwdn = CAM_PIN_PWDN,
|
||||
@@ -166,18 +172,49 @@ static size_t jpg_encode_stream(void * arg, size_t index, const void* data, size
|
||||
}
|
||||
|
||||
|
||||
bool CCamera::SetBrightnessContrastSaturation(int _brightness, int _contrast, int _saturation)
|
||||
bool CCamera::SetBrightnessContrastSaturation(int _brightness, int _contrast, int _saturation, int _autoExposureLevel, bool _grayscale, bool _negative, bool _aec2, int _sharpnessLevel)
|
||||
{
|
||||
_brightness = min(2, max(-2, _brightness));
|
||||
_contrast = min(2, max(-2, _contrast));
|
||||
_saturation = min(2, max(-2, _saturation));
|
||||
_autoExposureLevel = min(2, max(-2, _autoExposureLevel));
|
||||
bool _autoSharpness = false;
|
||||
if (_sharpnessLevel <= -4)
|
||||
_autoSharpness = true;
|
||||
_sharpnessLevel = min(3, max(-3, _sharpnessLevel));
|
||||
|
||||
sensor_t * s = esp_camera_sensor_get();
|
||||
if (s) {
|
||||
// camera gives precedence to negative over grayscale, so it's easier to do negative ourselves.
|
||||
// if (_negative) {
|
||||
// s->set_special_effect(s, 1); // 0 - no effect, 1 - negative, 2 - grayscale, 3 - reddish, 4 - greenish, 5 - blue, 6 - retro
|
||||
// }
|
||||
if (_grayscale) {
|
||||
s->set_special_effect(s, 2); // 0 - no effect, 1 - negative, 2 - grayscale, 3 - reddish, 4 - greenish, 5 - blue, 6 - retro
|
||||
}
|
||||
|
||||
// auto exposure controls
|
||||
s->set_aec2(s, _aec2 ? 1 : 0);
|
||||
s->set_ae_level(s, _autoExposureLevel); // -2 to 2
|
||||
s->set_gainceiling(s, GAINCEILING_2X); // GAINCEILING_2X 4X 8X 16X 32X 64X 128X
|
||||
|
||||
// post processing
|
||||
if (_autoSharpness) {
|
||||
s->set_sharpness(s, 0); // auto-sharpness is not officially supported, default to 0
|
||||
}
|
||||
s->set_saturation(s, _saturation);
|
||||
s->set_contrast(s, _contrast);
|
||||
s->set_brightness(s, _brightness);
|
||||
|
||||
camera_sensor_info_t *sensor_info = esp_camera_sensor_get_info(&(s->id));
|
||||
if (sensor_info != NULL) {
|
||||
if (sensor_info->model == CAMERA_OV2640) {
|
||||
if (_autoSharpness) {
|
||||
ov2640_enable_auto_sharpness(s);
|
||||
} else {
|
||||
ov2640_set_sharpness(s, _sharpnessLevel);
|
||||
}
|
||||
|
||||
/* Workaround - bug in cam library - enable bits are set without using bitwise OR logic -> only latest enable setting is used */
|
||||
/* Library version: https://github.com/espressif/esp32-camera/commit/5c8349f4cf169c8a61283e0da9b8cff10994d3f3 */
|
||||
/* Reference: https://esp32.com/viewtopic.php?f=19&t=14376#p93178 */
|
||||
@@ -205,9 +242,23 @@ bool CCamera::SetBrightnessContrastSaturation(int _brightness, int _contrast, in
|
||||
|
||||
//s->set_reg(s, 0x7C, 0xFF, 2); // Optional feature - hue setting: Select byte 2 in register 0x7C to set hue value
|
||||
//s->set_reg(s, 0x7D, 0xFF, 0); // Optional feature - hue setting: Hue value 0 - 255
|
||||
int indirectReg0 = 0x07; // Set bit 0, 1, 2 to enable saturation, contrast, brightness and hue control
|
||||
if (_grayscale) {
|
||||
indirectReg0 |= 0x18;
|
||||
}
|
||||
// camera gives precedence to negative over grayscale, so it's easier to do negative ourselves.
|
||||
// if (_negative) {
|
||||
// indirectReg0 |= 0x40;
|
||||
// }
|
||||
// Indirect register access
|
||||
s->set_reg(s, 0xFF, 0x01, 0); // Select DSP bank
|
||||
s->set_reg(s, 0x7C, 0xFF, 0); // Select byte 0 in register 0x7C
|
||||
s->set_reg(s, 0x7D, 7, 7); // Set bit 0, 1, 2 in register 0x7D to enable saturation, contrast, brightness and hue control
|
||||
s->set_reg(s, OV2640_IRA_BPADDR, 0xFF, 0x00); // Address 0x00
|
||||
s->set_reg(s, OV2640_IRA_BPDATA, 0xFF, indirectReg0);
|
||||
s->set_reg(s, OV2640_IRA_BPADDR, 0xFF, 0x05); // Address 0x05
|
||||
s->set_reg(s, OV2640_IRA_BPDATA, 0xFF, 0x80);
|
||||
s->set_reg(s, OV2640_IRA_BPDATA, 0xFF, 0x80);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "SetBrightnessContrastSaturation: Failed to get control structure");
|
||||
@@ -219,29 +270,32 @@ bool CCamera::SetBrightnessContrastSaturation(int _brightness, int _contrast, in
|
||||
brightness = _brightness;
|
||||
contrast = _contrast;
|
||||
saturation = _saturation;
|
||||
autoExposureLevel = _autoExposureLevel;
|
||||
imageGrayscale = _grayscale;
|
||||
imageNegative = _negative;
|
||||
imageAec2 = _aec2;
|
||||
imageAutoSharpness = _autoSharpness;
|
||||
imageSharpnessLevel = _sharpnessLevel;
|
||||
|
||||
ESP_LOGD(TAG, "brightness %d, contrast: %d, saturation %d", brightness, contrast, saturation);
|
||||
ESP_LOGD(TAG, "brightness %d, contrast: %d, saturation %d, autoExposureLevel %d, grayscale %d", brightness, contrast, saturation, autoExposureLevel, (int)imageGrayscale);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void CCamera::SetQualitySize(int qual, framesize_t resol)
|
||||
/*
|
||||
* resolution = 0 \\ 1600 x 1200
|
||||
* resolution = 1 \\ 800 x 600
|
||||
* resolution = 2 \\ 400 x 296
|
||||
*/
|
||||
void CCamera::SetCamWindow(sensor_t *s, int resolution, int xOffset, int yOffset, int xLength, int yLength)
|
||||
{
|
||||
qual = min(63, max(8, qual)); // Limit quality from 8..63 (values lower than 8 tent to be unstable)
|
||||
s->set_res_raw(s, resolution, 0, 0, 0, xOffset, yOffset, xLength, yLength, xLength, yLength, false, false);
|
||||
}
|
||||
|
||||
sensor_t * s = esp_camera_sensor_get();
|
||||
if (s) {
|
||||
s->set_quality(s, qual);
|
||||
s->set_framesize(s, resol);
|
||||
}
|
||||
else {
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "SetQualitySize: Failed to get control structure");
|
||||
}
|
||||
|
||||
ActualResolution = resol;
|
||||
ActualQuality = qual;
|
||||
|
||||
void CCamera::SetImageWidthHeightFromResolution(framesize_t resol)
|
||||
{
|
||||
if (resol == FRAMESIZE_QVGA)
|
||||
{
|
||||
image_height = 240;
|
||||
@@ -252,6 +306,92 @@ void CCamera::SetQualitySize(int qual, framesize_t resol)
|
||||
image_height = 480;
|
||||
image_width = 640;
|
||||
}
|
||||
else if (resol == FRAMESIZE_SVGA)
|
||||
{
|
||||
image_height = 600;
|
||||
image_width = 800;
|
||||
}
|
||||
else if (resol == FRAMESIZE_XGA)
|
||||
{
|
||||
image_height = 768;
|
||||
image_width = 1024;
|
||||
}
|
||||
else if (resol == FRAMESIZE_HD)
|
||||
{
|
||||
image_height = 720;
|
||||
image_width = 1280;
|
||||
}
|
||||
else if (resol == FRAMESIZE_SXGA)
|
||||
{
|
||||
image_height = 1024;
|
||||
image_width = 1280;
|
||||
}
|
||||
else if (resol == FRAMESIZE_UXGA)
|
||||
{
|
||||
image_height = 1200;
|
||||
image_width = 1600;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CCamera::SetZoom(bool zoomEnabled, int zoomMode, int zoomOffsetX, int zoomOffsetY)
|
||||
{
|
||||
imageZoomEnabled = zoomEnabled;
|
||||
imageZoomMode = zoomMode;
|
||||
imageZoomOffsetX = zoomOffsetX;
|
||||
imageZoomOffsetY = zoomOffsetY;
|
||||
|
||||
sensor_t *s = esp_camera_sensor_get();
|
||||
if (s) {
|
||||
if (imageZoomEnabled) {
|
||||
int z = imageZoomMode;
|
||||
int x = imageZoomOffsetX;
|
||||
int y = imageZoomOffsetY;
|
||||
if (z > 1)
|
||||
z = 1;
|
||||
if (image_width >= 800 || image_height >= 600) {
|
||||
z = 0;
|
||||
}
|
||||
int maxX = 1600 - image_width;
|
||||
int maxY = 1200 - image_height;
|
||||
if (z == 1) {
|
||||
maxX = 800 - image_width;
|
||||
maxY = 600 - image_height;
|
||||
}
|
||||
if (x > maxX)
|
||||
x = maxX;
|
||||
if (y > maxY)
|
||||
y = maxY;
|
||||
SetCamWindow(s, z, x, y, image_width, image_height);
|
||||
} else {
|
||||
s->set_framesize(s, ActualResolution);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CCamera::SetQualitySize(int qual, framesize_t resol, bool zoomEnabled, int zoomMode, int zoomOffsetX, int zoomOffsetY)
|
||||
{
|
||||
qual = min(63, max(8, qual)); // Limit quality from 8..63 (values lower than 8 tent to be unstable)
|
||||
|
||||
ActualResolution = resol;
|
||||
ActualQuality = qual;
|
||||
|
||||
imageZoomEnabled = zoomEnabled;
|
||||
imageZoomMode = zoomMode;
|
||||
imageZoomOffsetX = zoomOffsetX;
|
||||
imageZoomOffsetY = zoomOffsetY;
|
||||
|
||||
SetImageWidthHeightFromResolution(resol);
|
||||
|
||||
sensor_t * s = esp_camera_sensor_get();
|
||||
if (s) {
|
||||
s->set_quality(s, qual);
|
||||
SetZoom(zoomEnabled, zoomMode, zoomOffsetX, zoomOffsetY);
|
||||
}
|
||||
else {
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "SetQualitySize: Failed to get control structure");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -358,6 +498,14 @@ esp_err_t CCamera::CaptureToBasisImage(CImageBasis *_Image, int delay)
|
||||
LogFile.WriteHeapInfo("CaptureToBasisImage - After LoadFromMemory");
|
||||
#endif
|
||||
|
||||
if (_zwImage == NULL) {
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
if (imageNegative) {
|
||||
_zwImage->Negative();
|
||||
}
|
||||
|
||||
stbi_uc* p_target;
|
||||
stbi_uc* p_source;
|
||||
int channels = 3;
|
||||
@@ -375,9 +523,9 @@ esp_err_t CCamera::CaptureToBasisImage(CImageBasis *_Image, int delay)
|
||||
{
|
||||
p_target = _Image->rgb_image + (channels * (y * width + x));
|
||||
p_source = _zwImage->rgb_image + (channels * (y * width + x));
|
||||
p_target[0] = p_source[0];
|
||||
p_target[1] = p_source[1];
|
||||
p_target[2] = p_source[2];
|
||||
for (int c = 0; c < channels; c++) {
|
||||
p_target[c] = p_source[c];
|
||||
}
|
||||
}
|
||||
|
||||
delete _zwImage;
|
||||
@@ -505,7 +653,6 @@ esp_err_t CCamera::CaptureToHTTP(httpd_req_t *req, int delay)
|
||||
}
|
||||
|
||||
LEDOnOff(false);
|
||||
|
||||
res = httpd_resp_set_type(req, "image/jpeg");
|
||||
if(res == ESP_OK){
|
||||
res = httpd_resp_set_hdr(req, "Content-Disposition", "inline; filename=raw.jpg");
|
||||
@@ -662,49 +809,89 @@ void CCamera::LEDOnOff(bool status)
|
||||
}
|
||||
|
||||
|
||||
void CCamera::GetCameraParameter(httpd_req_t *req, int &qual, framesize_t &resol)
|
||||
void CCamera::GetCameraParameter(httpd_req_t *req, int &qual, framesize_t &resol, bool &zoomEnabled, int &zoomMode, int &zoomOffsetX, int &zoomOffsetY)
|
||||
{
|
||||
char _query[100];
|
||||
char _qual[10];
|
||||
char _size[10];
|
||||
char _value[10];
|
||||
|
||||
resol = ActualResolution;
|
||||
qual = ActualQuality;
|
||||
|
||||
zoomEnabled = imageZoomEnabled;
|
||||
zoomMode = imageZoomMode;
|
||||
zoomOffsetX = imageZoomOffsetX;
|
||||
zoomOffsetY = imageZoomOffsetY;
|
||||
|
||||
if (httpd_req_get_url_query_str(req, _query, 100) == ESP_OK)
|
||||
{
|
||||
ESP_LOGD(TAG, "Query: %s", _query);
|
||||
if (httpd_query_key_value(_query, "size", _size, 10) == ESP_OK)
|
||||
if (httpd_query_key_value(_query, "size", _value, sizeof(_value)) == ESP_OK)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Size: %s", _size);
|
||||
#endif
|
||||
if (strcmp(_size, "QVGA") == 0)
|
||||
if (strcmp(_value, "QVGA") == 0)
|
||||
resol = FRAMESIZE_QVGA; // 320x240
|
||||
else if (strcmp(_size, "VGA") == 0)
|
||||
else if (strcmp(_value, "VGA") == 0)
|
||||
resol = FRAMESIZE_VGA; // 640x480
|
||||
else if (strcmp(_size, "SVGA") == 0)
|
||||
else if (strcmp(_value, "SVGA") == 0)
|
||||
resol = FRAMESIZE_SVGA; // 800x600
|
||||
else if (strcmp(_size, "XGA") == 0)
|
||||
else if (strcmp(_value, "XGA") == 0)
|
||||
resol = FRAMESIZE_XGA; // 1024x768
|
||||
else if (strcmp(_size, "SXGA") == 0)
|
||||
else if (strcmp(_value, "SXGA") == 0)
|
||||
resol = FRAMESIZE_SXGA; // 1280x1024
|
||||
else if (strcmp(_size, "UXGA") == 0)
|
||||
else if (strcmp(_value, "UXGA") == 0)
|
||||
resol = FRAMESIZE_UXGA; // 1600x1200
|
||||
}
|
||||
if (httpd_query_key_value(_query, "quality", _qual, 10) == ESP_OK)
|
||||
if (httpd_query_key_value(_query, "quality", _value, sizeof(_value)) == ESP_OK)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Quality: %s", _qual);
|
||||
#endif
|
||||
qual = atoi(_qual);
|
||||
|
||||
qual = atoi(_value);
|
||||
if (qual > 63) // Limit to max. 63
|
||||
qual = 63;
|
||||
else if (qual < 8) // Limit to min. 8
|
||||
qual = 8;
|
||||
}
|
||||
if (httpd_query_key_value(_query, "z", _value, sizeof(_value)) == ESP_OK)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Zoom: %s", _value);
|
||||
#endif
|
||||
if (atoi(_value) != 0)
|
||||
zoomEnabled = true;
|
||||
else
|
||||
zoomEnabled = false;
|
||||
}
|
||||
if (httpd_query_key_value(_query, "zm", _value, sizeof(_value)) == ESP_OK)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Zoom mode: %s", _value);
|
||||
#endif
|
||||
zoomMode = atoi(_value);
|
||||
if (zoomMode > 2)
|
||||
zoomMode = 2;
|
||||
else if (zoomMode < 0)
|
||||
zoomMode = 0;
|
||||
}
|
||||
if (httpd_query_key_value(_query, "x", _value, sizeof(_value)) == ESP_OK)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "X offset: %s", _value);
|
||||
#endif
|
||||
zoomOffsetX = atoi(_value);
|
||||
if (zoomOffsetX < 0)
|
||||
zoomOffsetX = 0;
|
||||
}
|
||||
if (httpd_query_key_value(_query, "y", _value, sizeof(_value)) == ESP_OK)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Y offset: %s", _value);
|
||||
#endif
|
||||
zoomOffsetY = atoi(_value);
|
||||
if (zoomOffsetY < 0)
|
||||
zoomOffsetY = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ class CCamera {
|
||||
protected:
|
||||
int ActualQuality;
|
||||
framesize_t ActualResolution;
|
||||
int brightness, contrast, saturation;
|
||||
int brightness, contrast, saturation, autoExposureLevel;
|
||||
bool isFixedExposure;
|
||||
int waitbeforepicture_org;
|
||||
int led_intensity = 4095;
|
||||
@@ -31,8 +31,24 @@ class CCamera {
|
||||
bool loadNextDemoImage(camera_fb_t *fb);
|
||||
long GetFileSize(std::string filename);
|
||||
|
||||
void SetCamWindow(sensor_t *s, int resolution, int xOffset, int yOffset, int xLength, int yLength);
|
||||
void SetImageWidthHeightFromResolution(framesize_t resol);
|
||||
|
||||
public:
|
||||
int image_height, image_width;
|
||||
bool imageZoomEnabled = false;
|
||||
int imageZoomMode = 0;
|
||||
int imageZoomOffsetX = 0;
|
||||
int imageZoomOffsetY = 0;
|
||||
bool imageNegative = false;
|
||||
bool imageAec2 = false;
|
||||
bool imageAutoSharpness = false;
|
||||
int imageSharpnessLevel = 0;
|
||||
#ifdef GRAYSCALE_AS_DEFAULT
|
||||
bool imageGrayscale = true;
|
||||
#else
|
||||
bool imageGrayscale = false;
|
||||
#endif
|
||||
|
||||
CCamera();
|
||||
esp_err_t InitCam();
|
||||
@@ -41,9 +57,10 @@ class CCamera {
|
||||
void LEDOnOff(bool status);
|
||||
esp_err_t CaptureToHTTP(httpd_req_t *req, int delay = 0);
|
||||
esp_err_t CaptureToStream(httpd_req_t *req, bool FlashlightOn);
|
||||
void SetQualitySize(int qual, framesize_t resol);
|
||||
bool SetBrightnessContrastSaturation(int _brightness, int _contrast, int _saturation);
|
||||
void GetCameraParameter(httpd_req_t *req, int &qual, framesize_t &resol);
|
||||
void SetQualitySize(int qual, framesize_t resol, bool zoomEnabled, int zoomMode, int zoomOffsetX, int zoomOffsetY);
|
||||
bool SetBrightnessContrastSaturation(int _brightness, int _contrast, int _saturation, int _autoExposureLevel, bool _grayscale, bool _negative, bool _aec2, int _sharpnessLevel);
|
||||
void SetZoom(bool zoomEnabled, int zoomMode, int zoomOffsetX, int zoomOffsetY);
|
||||
void GetCameraParameter(httpd_req_t *req, int &qual, framesize_t &resol, bool &zoomEnabled, int &zoomMode, int &zoomOffsetX, int &zoomOffsetY);
|
||||
void SetLEDIntensity(float _intrel);
|
||||
bool testCamera(void);
|
||||
void EnableAutoExposure(int flash_duration);
|
||||
|
||||
124
code/components/jomjol_controlcamera/ov2640_sharpness.cpp
Normal file
124
code/components/jomjol_controlcamera/ov2640_sharpness.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
#include <stdint.h>
|
||||
#include "esp_camera.h"
|
||||
#include "ov2640_sharpness.h"
|
||||
|
||||
|
||||
#define OV2640_MAXLEVEL_SHARPNESS 6
|
||||
|
||||
const static uint8_t OV2640_SHARPNESS_AUTO[]=
|
||||
{
|
||||
0xFF, 0x00, 0xff,
|
||||
0x92, 0x01, 0xff,
|
||||
0x93, 0x20, 0x20,
|
||||
0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
const static uint8_t OV2640_SHARPNESS_MANUAL[]=
|
||||
{
|
||||
0xFF, 0x00, 0xff,
|
||||
0x92, 0x01, 0xff,
|
||||
0x93, 0x00, 0x20,
|
||||
0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
const static uint8_t OV2640_SHARPNESS_LEVEL0[]=
|
||||
{
|
||||
0xFF, 0x00, 0xff,
|
||||
0x92, 0x01, 0xff,
|
||||
0x93, 0xc0, 0x1f,
|
||||
0x00, 0x00, 0x00
|
||||
};
|
||||
const static uint8_t OV2640_SHARPNESS_LEVEL1[]=
|
||||
{
|
||||
0xFF, 0x00, 0xff,
|
||||
0x92, 0x01, 0xff,
|
||||
0x93, 0xc1, 0x1f,
|
||||
0x00, 0x00, 0x00
|
||||
};
|
||||
const static uint8_t OV2640_SHARPNESS_LEVEL2[]=
|
||||
{
|
||||
0xFF, 0x00, 0xff,
|
||||
0x92, 0x01, 0xff,
|
||||
0x93, 0xc2, 0x1f,
|
||||
0x00, 0x00, 0x00
|
||||
};
|
||||
const static uint8_t OV2640_SHARPNESS_LEVEL3[]=
|
||||
{
|
||||
0xFF, 0x00, 0xff,
|
||||
0x92, 0x01, 0xff,
|
||||
0x93, 0xc4, 0x1f,
|
||||
0x00, 0x00, 0x00
|
||||
};
|
||||
const static uint8_t OV2640_SHARPNESS_LEVEL4[]=
|
||||
{
|
||||
0xFF, 0x00, 0xff,
|
||||
0x92, 0x01, 0xff,
|
||||
0x93, 0xc8, 0x1f,
|
||||
0x00, 0x00, 0x00
|
||||
};
|
||||
const static uint8_t OV2640_SHARPNESS_LEVEL5[]=
|
||||
{
|
||||
0xFF, 0x00, 0xff,
|
||||
0x92, 0x01, 0xff,
|
||||
0x93, 0xd0, 0x1f,
|
||||
0x00, 0x00, 0x00
|
||||
};
|
||||
const static uint8_t OV2640_SHARPNESS_LEVEL6[]=
|
||||
{
|
||||
0xFF, 0x00, 0xff,
|
||||
0x92, 0x01, 0xff,
|
||||
0x93, 0xdf, 0x1f,
|
||||
0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
const static uint8_t *OV2640_SETTING_SHARPNESS[]=
|
||||
{
|
||||
OV2640_SHARPNESS_LEVEL0, // -3 sharpness
|
||||
OV2640_SHARPNESS_LEVEL1,
|
||||
OV2640_SHARPNESS_LEVEL2,
|
||||
OV2640_SHARPNESS_LEVEL3,
|
||||
OV2640_SHARPNESS_LEVEL4,
|
||||
OV2640_SHARPNESS_LEVEL5,
|
||||
OV2640_SHARPNESS_LEVEL6 // +3 sharpness
|
||||
};
|
||||
|
||||
static int table_mask_write(sensor_t *sensor, const uint8_t* ptab)
|
||||
{
|
||||
uint8_t address;
|
||||
uint8_t value;
|
||||
uint8_t orgval;
|
||||
uint8_t mask;
|
||||
const uint8_t *pdata = ptab;
|
||||
|
||||
if (pdata == NULL)
|
||||
return -1;
|
||||
|
||||
while (1)
|
||||
{
|
||||
address = *pdata++;
|
||||
value = *pdata++;
|
||||
mask = *pdata++;
|
||||
if ((address == 0) && (value == 0) && (mask == 0))
|
||||
break;
|
||||
sensor->set_reg(sensor, address, mask, value);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ov2640_enable_auto_sharpness(sensor_t *sensor)
|
||||
{
|
||||
table_mask_write(sensor, OV2640_SHARPNESS_AUTO);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int ov2640_set_sharpness(sensor_t *sensor, int sharpness)
|
||||
{
|
||||
if ((sharpness < -3) || (sharpness > OV2640_MAXLEVEL_SHARPNESS - 3))
|
||||
return -1;
|
||||
|
||||
table_mask_write(sensor, OV2640_SHARPNESS_MANUAL);
|
||||
table_mask_write(sensor, OV2640_SETTING_SHARPNESS[sharpness + 3]);
|
||||
return 0;
|
||||
}
|
||||
11
code/components/jomjol_controlcamera/ov2640_sharpness.h
Normal file
11
code/components/jomjol_controlcamera/ov2640_sharpness.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef OV2640_SHARPNESS_H
|
||||
#define OV2640_SHARPNESS_H
|
||||
|
||||
#include "esp_camera.h"
|
||||
|
||||
int ov2640_enable_auto_sharpness(sensor_t *sensor);
|
||||
int ov2640_set_sharpness(sensor_t *sensor, int sharpness); // -3 to +3, -4 for auto-sharpness
|
||||
|
||||
#endif
|
||||
@@ -97,14 +97,18 @@ esp_err_t handler_capture(httpd_req_t *req)
|
||||
{
|
||||
int quality;
|
||||
framesize_t res;
|
||||
bool zoomEnabled;
|
||||
int zoomMode;
|
||||
int zoomOffsetX;
|
||||
int zoomOffsetY;
|
||||
|
||||
Camera.GetCameraParameter(req, quality, res);
|
||||
Camera.GetCameraParameter(req, quality, res, zoomEnabled, zoomMode, zoomOffsetX, zoomOffsetY);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Size: %d, Quality: %d", res, quality);
|
||||
#endif
|
||||
|
||||
Camera.SetQualitySize(quality, res);
|
||||
Camera.SetQualitySize(quality, res, zoomEnabled, zoomMode, zoomOffsetX, zoomOffsetY);
|
||||
|
||||
esp_err_t result;
|
||||
result = Camera.CaptureToHTTP(req);
|
||||
@@ -136,6 +140,10 @@ esp_err_t handler_capture_with_light(httpd_req_t *req)
|
||||
|
||||
int quality;
|
||||
framesize_t res;
|
||||
bool zoomEnabled;
|
||||
int zoomMode;
|
||||
int zoomOffsetX;
|
||||
int zoomOffsetY;
|
||||
int delay = 2500;
|
||||
|
||||
if (httpd_req_get_url_query_str(req, _query, 100) == ESP_OK)
|
||||
@@ -153,13 +161,13 @@ esp_err_t handler_capture_with_light(httpd_req_t *req)
|
||||
}
|
||||
}
|
||||
|
||||
Camera.GetCameraParameter(req, quality, res);
|
||||
Camera.GetCameraParameter(req, quality, res, zoomEnabled, zoomMode, zoomOffsetX, zoomOffsetY);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Size: %d, Quality: %d", res, quality);
|
||||
#endif
|
||||
|
||||
Camera.SetQualitySize(quality, res);
|
||||
Camera.SetQualitySize(quality, res, zoomEnabled, zoomMode, zoomOffsetX, zoomOffsetY);
|
||||
Camera.LightOnOff(true);
|
||||
const TickType_t xDelay = delay / portTICK_PERIOD_MS;
|
||||
vTaskDelay( xDelay );
|
||||
@@ -200,6 +208,10 @@ esp_err_t handler_capture_save_to_file(httpd_req_t *req)
|
||||
|
||||
int quality;
|
||||
framesize_t res;
|
||||
bool zoomEnabled;
|
||||
int zoomMode;
|
||||
int zoomOffsetX;
|
||||
int zoomOffsetY;
|
||||
|
||||
if (httpd_req_get_url_query_str(req, _query, 100) == ESP_OK)
|
||||
{
|
||||
@@ -228,11 +240,11 @@ esp_err_t handler_capture_save_to_file(httpd_req_t *req)
|
||||
else
|
||||
fn.append("noname.jpg");
|
||||
|
||||
Camera.GetCameraParameter(req, quality, res);
|
||||
Camera.GetCameraParameter(req, quality, res, zoomEnabled, zoomMode, zoomOffsetX, zoomOffsetY);
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Size: %d, Quality: %d", res, quality);
|
||||
#endif
|
||||
Camera.SetQualitySize(quality, res);
|
||||
Camera.SetQualitySize(quality, res, zoomEnabled, zoomMode, zoomOffsetX, zoomOffsetY);
|
||||
|
||||
esp_err_t result;
|
||||
result = Camera.CaptureToFile(fn, delay);
|
||||
|
||||
@@ -19,7 +19,7 @@ static const char *TAG = "ALIGN";
|
||||
|
||||
void ClassFlowAlignment::SetInitialParameter(void)
|
||||
{
|
||||
initalrotate = 0;
|
||||
initialrotate = 0;
|
||||
anz_ref = 0;
|
||||
initialmirror = false;
|
||||
use_antialiasing = false;
|
||||
@@ -91,9 +91,9 @@ bool ClassFlowAlignment::ReadParameter(FILE* pfile, string& aktparamgraph)
|
||||
if (toUpper(splitted[1]) == "TRUE")
|
||||
initialmirror = true;
|
||||
}
|
||||
if (((toUpper(splitted[0]) == "INITALROTATE") || (toUpper(splitted[0]) == "INITIALROTATE")) && (splitted.size() > 1))
|
||||
if (((toUpper(splitted[0]) == "initialrotate") || (toUpper(splitted[0]) == "INITIALROTATE")) && (splitted.size() > 1))
|
||||
{
|
||||
this->initalrotate = std::stod(splitted[1]);
|
||||
this->initialrotate = std::stod(splitted[1]);
|
||||
}
|
||||
if ((toUpper(splitted[0]) == "SEARCHFIELDX") && (splitted.size() > 1))
|
||||
{
|
||||
@@ -229,12 +229,12 @@ bool ClassFlowAlignment::doFlow(string time)
|
||||
AlignAndCutImage->SaveToFile(FormatFileName("/sdcard/img_tmp/mirror.jpg"));
|
||||
}
|
||||
|
||||
if ((initalrotate != 0) || initialflip)
|
||||
if ((initialrotate != 0) || initialflip)
|
||||
{
|
||||
if (use_antialiasing)
|
||||
rt.RotateAntiAliasing(initalrotate);
|
||||
rt.RotateAntiAliasing(initialrotate);
|
||||
else
|
||||
rt.Rotate(initalrotate);
|
||||
rt.Rotate(initialrotate);
|
||||
|
||||
if (SaveAllFiles)
|
||||
AlignAndCutImage->SaveToFile(FormatFileName("/sdcard/img_tmp/rot.jpg"));
|
||||
|
||||
@@ -16,7 +16,7 @@ class ClassFlowAlignment :
|
||||
public ClassFlow
|
||||
{
|
||||
protected:
|
||||
float initalrotate;
|
||||
float initialrotate;
|
||||
bool initialmirror;
|
||||
bool initialflip;
|
||||
bool use_antialiasing;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -5,7 +5,6 @@
|
||||
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <cassert>
|
||||
|
||||
#include <time.h>
|
||||
|
||||
@@ -727,130 +726,6 @@ string ClassFlowPostProcessing::ShiftDecimal(string in, int _decShift){
|
||||
return zw;
|
||||
}
|
||||
|
||||
|
||||
float wrapAround(float val)
|
||||
{
|
||||
return fmod(val, 10.);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks whether val is in the range [min, max]
|
||||
*
|
||||
* Note, this function also handles the wrap around case,
|
||||
* in which min could be larger than max in case of
|
||||
* a circular range
|
||||
*
|
||||
* @param val The value to be checked
|
||||
* @param min Minimal bound of the range
|
||||
* @param max Maximum bound of the range
|
||||
* @return True, if val is in the range
|
||||
*/
|
||||
bool inRange(float val, float min, float max)
|
||||
{
|
||||
assert(min >= 0. && min < 10.0);
|
||||
assert(max >= 0. && max <= 10.0);
|
||||
assert(val >= 0. && val < 10.0);
|
||||
|
||||
if (min <= max)
|
||||
{
|
||||
return min <= val && val <= max;
|
||||
}
|
||||
else
|
||||
{
|
||||
// e.g. between 8 and 2 (of the next round)
|
||||
return (min <= val && val < 10.) || (0. <= val && val <= max);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Synchronizes a potential misalignment between analog and digital part
|
||||
*
|
||||
* @param The current value assembled from digits (pre comma) and analogs (post comma)
|
||||
* @param digitalPrecision The post-comma value of the last digit ([0...9])
|
||||
* @param analogDigitalShift The value of the 0.1 analog, when the digital precision == 5 in [0, 9.9]
|
||||
*
|
||||
* We define 3 phases:
|
||||
* - Pre transition: analog post comma < analogDigitalShift && not in transition
|
||||
* - Transition: Digital Precision in range 1...9
|
||||
* - Post transition: analog post comma > analogDigitalShift && not in transition
|
||||
*
|
||||
* @return The synchronized values as a string
|
||||
*/
|
||||
std::string syncDigitalAnalog(const std::string& value, const std::string& digitalPrecision,
|
||||
double analogDigitalShift)
|
||||
{
|
||||
if (digitalPrecision.empty())
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
const auto pos = value.find('.');
|
||||
if (pos == std::string::npos)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
// disassemble value into pre and post comma part
|
||||
const auto preComma = value.substr(0, pos);
|
||||
|
||||
// memorize, to be able to assemble right numbers of leading zeros
|
||||
const size_t nPreComma = preComma.size();
|
||||
const auto postComma = value.substr(pos+1);
|
||||
|
||||
const float digitalPostComma = std::atof(digitalPrecision.c_str());
|
||||
int digitalPreComma = std::atoi(preComma.c_str());
|
||||
const float analogPostComma = std::atof(("0." + postComma).c_str());
|
||||
|
||||
// Determine phase
|
||||
const bool inTransition = digitalPostComma > 0. && digitalPostComma < 10.;
|
||||
const bool postTransition = !inTransition && inRange(analogPostComma*10., analogDigitalShift, wrapAround(analogDigitalShift + 5.));
|
||||
const bool preTransition = !inTransition && inRange(analogPostComma*10., 0, analogDigitalShift);
|
||||
|
||||
|
||||
if (inRange(analogDigitalShift, 0.5, 5.))
|
||||
{
|
||||
// late transition, last digit starts transition, when analog is between [0.5, 5)
|
||||
if (inTransition || preTransition)
|
||||
{
|
||||
ESP_LOGD("syncDigitalAnalog", "Late digital transition. Increase digital value by 1.");
|
||||
digitalPreComma += 1;
|
||||
}
|
||||
}
|
||||
else if (inRange(analogDigitalShift, 5., 9.5))
|
||||
{
|
||||
// early transition
|
||||
if (postTransition && analogPostComma*10 > analogDigitalShift)
|
||||
{
|
||||
ESP_LOGD("syncDigitalAnalog", "Early digital transition. Decrease digital value by 1.");
|
||||
digitalPreComma -= 1;
|
||||
}
|
||||
|
||||
// transition has not finished, but we are already at the new cycle
|
||||
// this also should handle hanging digits
|
||||
if (inTransition && analogPostComma < 0.5) {
|
||||
digitalPreComma += 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
// assemble result into string again, pad with zeros
|
||||
auto preCommaNew = std::to_string(digitalPreComma);
|
||||
for (size_t i = preCommaNew.size(); i < nPreComma; ++i)
|
||||
preCommaNew = "0" + preCommaNew;
|
||||
|
||||
const std::string result = preCommaNew + "." + postComma;
|
||||
|
||||
#if debugSync
|
||||
ESP_LOGD("syncDigitalAnalog", "result: %s", result.c_str());
|
||||
#endif
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
bool ClassFlowPostProcessing::doFlow(string zwtime)
|
||||
{
|
||||
string result = "";
|
||||
@@ -894,8 +769,6 @@ bool ClassFlowPostProcessing::doFlow(string zwtime)
|
||||
|
||||
int previous_value = -1;
|
||||
|
||||
// ------------------- start processing analog values --------------------------//
|
||||
|
||||
if (NUMBERS[j]->analog_roi)
|
||||
{
|
||||
NUMBERS[j]->ReturnRawValue = flowAnalog->getReadout(j, NUMBERS[j]->isExtendedResolution);
|
||||
@@ -909,38 +782,19 @@ bool ClassFlowPostProcessing::doFlow(string zwtime)
|
||||
#ifdef SERIAL_DEBUG
|
||||
ESP_LOGD(TAG, "After analog->getReadout: ReturnRaw %s", NUMBERS[j]->ReturnRawValue.c_str());
|
||||
#endif
|
||||
if (NUMBERS[j]->digit_roi && NUMBERS[j]->analog_roi)
|
||||
NUMBERS[j]->ReturnRawValue = "." + NUMBERS[j]->ReturnRawValue;
|
||||
|
||||
// ----------------- start processing digital values --------------------------//
|
||||
|
||||
// we need the precision of the digital values to determine transition phase
|
||||
std::string digitalPrecision = {"0"};
|
||||
if (NUMBERS[j]->digit_roi && NUMBERS[j]->analog_roi) {
|
||||
// we have nachkommad and vorkomman part!
|
||||
|
||||
std::string analogValues = NUMBERS[j]->ReturnRawValue;
|
||||
std::string digitValues = flowDigit->getReadout(j, true, previous_value, NUMBERS[j]->analog_roi->ROI[0]->result_float, 0.);
|
||||
|
||||
if (flowDigit->getCNNType() != Digital)
|
||||
{
|
||||
// The digital type does not provide an extended resolution, so we cannot extract it
|
||||
digitalPrecision = digitValues.substr(digitValues.size() - 1);
|
||||
digitValues = digitValues.substr(0, digitValues.size() - 1);
|
||||
}
|
||||
|
||||
NUMBERS[j]->ReturnRawValue = digitValues + "." + analogValues;
|
||||
}
|
||||
|
||||
|
||||
if (NUMBERS[j]->digit_roi && !NUMBERS[j]->analog_roi)
|
||||
if (NUMBERS[j]->digit_roi)
|
||||
{
|
||||
if (NUMBERS[j]->analog_roi)
|
||||
NUMBERS[j]->ReturnRawValue = flowDigit->getReadout(j, false, previous_value, NUMBERS[j]->analog_roi->ROI[0]->result_float, NUMBERS[j]->AnalogDigitalTransitionStart) + NUMBERS[j]->ReturnRawValue;
|
||||
else
|
||||
NUMBERS[j]->ReturnRawValue = flowDigit->getReadout(j, NUMBERS[j]->isExtendedResolution, previous_value); // Extended Resolution only if there are no analogue digits
|
||||
}
|
||||
#ifdef SERIAL_DEBUG
|
||||
ESP_LOGD(TAG, "After digital->getReadout: ReturnRaw %s", NUMBERS[j]->ReturnRawValue.c_str());
|
||||
#endif
|
||||
|
||||
// ------------------ start corrections --------------------------//
|
||||
|
||||
NUMBERS[j]->ReturnRawValue = ShiftDecimal(NUMBERS[j]->ReturnRawValue, NUMBERS[j]->DecimalShift);
|
||||
|
||||
#ifdef SERIAL_DEBUG
|
||||
@@ -973,13 +827,6 @@ bool ClassFlowPostProcessing::doFlow(string zwtime)
|
||||
continue; // there is no number because there is still an N.
|
||||
}
|
||||
}
|
||||
|
||||
if (NUMBERS[j]->digit_roi && NUMBERS[j]->analog_roi)
|
||||
{
|
||||
// Synchronize potential misalignment between analog and digital part
|
||||
NUMBERS[j]->ReturnValue = syncDigitalAnalog(NUMBERS[j]->ReturnValue, digitalPrecision, NUMBERS[j]->AnalogDigitalTransitionStart);
|
||||
}
|
||||
|
||||
#ifdef SERIAL_DEBUG
|
||||
ESP_LOGD(TAG, "After findDelimiterPos: ReturnValue %s", NUMBERS[j]->ReturnRawValue.c_str());
|
||||
#endif
|
||||
|
||||
@@ -50,6 +50,17 @@ void ClassFlowTakeImage::SetInitialParameter(void)
|
||||
ImageQuality = 5;
|
||||
rawImage = NULL;
|
||||
ImageSize = FRAMESIZE_VGA;
|
||||
ZoomEnabled = false;
|
||||
ZoomMode = 0;
|
||||
zoomOffsetX = 0;
|
||||
zoomOffsetY = 0;
|
||||
ImageNegative = false;
|
||||
ImageAec2 = false;
|
||||
#ifdef GRAYSCALE_AS_DEFAULT
|
||||
ImageGrayscale = true;
|
||||
#else
|
||||
ImageGrayscale = false;
|
||||
#endif
|
||||
SaveAllFiles = false;
|
||||
disabled = false;
|
||||
FixedExposure = false;
|
||||
@@ -70,9 +81,11 @@ bool ClassFlowTakeImage::ReadParameter(FILE* pfile, string& aktparamgraph)
|
||||
std::vector<string> splitted;
|
||||
|
||||
aktparamgraph = trim(aktparamgraph);
|
||||
int _brightness = -100;
|
||||
int _contrast = -100;
|
||||
int _saturation = -100;
|
||||
int _brightness = 0;
|
||||
int _contrast = 0;
|
||||
int _saturation = 0;
|
||||
int _sharpness = 0;
|
||||
int _autoExposureLevel = 0;
|
||||
|
||||
if (aktparamgraph.size() == 0)
|
||||
if (!this->GetNextParagraph(pfile, aktparamgraph))
|
||||
@@ -92,6 +105,43 @@ bool ClassFlowTakeImage::ReadParameter(FILE* pfile, string& aktparamgraph)
|
||||
if ((toUpper(splitted[0]) == "IMAGEQUALITY") && (splitted.size() > 1))
|
||||
ImageQuality = std::stod(splitted[1]);
|
||||
|
||||
if ((toUpper(splitted[0]) == "ZOOM") && (splitted.size() > 1))
|
||||
{
|
||||
if (toUpper(splitted[1]) == "TRUE")
|
||||
ZoomEnabled = true;
|
||||
else if (toUpper(splitted[1]) == "FALSE")
|
||||
ZoomEnabled = false;
|
||||
}
|
||||
if ((toUpper(splitted[0]) == "ZOOMMODE") && (splitted.size() > 1))
|
||||
ZoomMode = std::stod(splitted[1]);
|
||||
if ((toUpper(splitted[0]) == "ZOOMOFFSETX") && (splitted.size() > 1))
|
||||
zoomOffsetX = std::stod(splitted[1]);
|
||||
if ((toUpper(splitted[0]) == "ZOOMOFFSETY") && (splitted.size() > 1))
|
||||
zoomOffsetY = std::stod(splitted[1]);
|
||||
if ((toUpper(splitted[0]) == "GRAYSCALE") && (splitted.size() > 1))
|
||||
{
|
||||
if (toUpper(splitted[1]) == "TRUE")
|
||||
ImageGrayscale = true;
|
||||
else if (toUpper(splitted[1]) == "FALSE")
|
||||
ImageGrayscale = false;
|
||||
}
|
||||
if ((toUpper(splitted[0]) == "NEGATIVE") && (splitted.size() > 1))
|
||||
{
|
||||
if (toUpper(splitted[1]) == "TRUE")
|
||||
ImageNegative = true;
|
||||
else if (toUpper(splitted[1]) == "FALSE")
|
||||
ImageNegative = false;
|
||||
}
|
||||
if ((toUpper(splitted[0]) == "AEC2") && (splitted.size() > 1))
|
||||
{
|
||||
if (toUpper(splitted[1]) == "TRUE")
|
||||
ImageAec2 = true;
|
||||
else if (toUpper(splitted[1]) == "FALSE")
|
||||
ImageAec2 = false;
|
||||
}
|
||||
if ((toUpper(splitted[0]) == "AUTOEXPOSURELEVEL") && (splitted.size() > 1))
|
||||
_autoExposureLevel = std::stod(splitted[1]);
|
||||
|
||||
if ((toUpper(splitted[0]) == "IMAGESIZE") && (splitted.size() > 1))
|
||||
{
|
||||
ImageSize = Camera.TextToFramesize(splitted[1].c_str());
|
||||
@@ -129,6 +179,11 @@ bool ClassFlowTakeImage::ReadParameter(FILE* pfile, string& aktparamgraph)
|
||||
_saturation = stoi(splitted[1]);
|
||||
}
|
||||
|
||||
if ((toUpper(splitted[0]) == "SHARPNESS") && (splitted.size() > 1))
|
||||
{
|
||||
_sharpness = stoi(splitted[1]);
|
||||
}
|
||||
|
||||
if ((toUpper(splitted[0]) == "FIXEDEXPOSURE") && (splitted.size() > 1))
|
||||
{
|
||||
if (toUpper(splitted[1]) == "TRUE")
|
||||
@@ -150,8 +205,8 @@ bool ClassFlowTakeImage::ReadParameter(FILE* pfile, string& aktparamgraph)
|
||||
}
|
||||
}
|
||||
|
||||
Camera.SetBrightnessContrastSaturation(_brightness, _contrast, _saturation);
|
||||
Camera.SetQualitySize(ImageQuality, ImageSize);
|
||||
Camera.SetBrightnessContrastSaturation(_brightness, _contrast, _saturation, _autoExposureLevel, ImageGrayscale, ImageNegative, ImageAec2, _sharpness);
|
||||
Camera.SetQualitySize(ImageQuality, ImageSize, ZoomEnabled, ZoomMode, zoomOffsetX, zoomOffsetY);
|
||||
|
||||
image_width = Camera.image_width;
|
||||
image_height = Camera.image_height;
|
||||
|
||||
@@ -17,6 +17,13 @@ protected:
|
||||
float waitbeforepicture_store;
|
||||
framesize_t ImageSize;
|
||||
bool isImageSize;
|
||||
bool ZoomEnabled = false;
|
||||
int ZoomMode = 0;
|
||||
int zoomOffsetX = 0;
|
||||
int zoomOffsetY = 0;
|
||||
bool ImageGrayscale;
|
||||
bool ImageNegative;
|
||||
bool ImageAec2;
|
||||
int ImageQuality;
|
||||
time_t TimeImageTaken;
|
||||
string namerawimage;
|
||||
|
||||
@@ -48,13 +48,12 @@ bool isPlannedReboot = false;
|
||||
|
||||
static const char *TAG = "MAINCTRL";
|
||||
|
||||
|
||||
//#define DEBUG_DETAIL_ON
|
||||
|
||||
|
||||
void CheckIsPlannedReboot()
|
||||
{
|
||||
void CheckIsPlannedReboot() {
|
||||
FILE *pfile;
|
||||
|
||||
if ((pfile = fopen("/sdcard/reboot.txt", "r")) == NULL) {
|
||||
//LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Initial boot or not a planned reboot");
|
||||
isPlannedReboot = false;
|
||||
@@ -67,32 +66,27 @@ void CheckIsPlannedReboot()
|
||||
}
|
||||
|
||||
|
||||
bool getIsPlannedReboot()
|
||||
{
|
||||
bool getIsPlannedReboot() {
|
||||
return isPlannedReboot;
|
||||
}
|
||||
|
||||
|
||||
int getCountFlowRounds()
|
||||
{
|
||||
int getCountFlowRounds() {
|
||||
return countRounds;
|
||||
}
|
||||
|
||||
|
||||
esp_err_t GetJPG(std::string _filename, httpd_req_t *req)
|
||||
{
|
||||
esp_err_t GetJPG(std::string _filename, httpd_req_t *req) {
|
||||
return flowctrl.GetJPGStream(_filename, req);
|
||||
}
|
||||
|
||||
|
||||
esp_err_t GetRawJPG(httpd_req_t *req)
|
||||
{
|
||||
esp_err_t GetRawJPG(httpd_req_t *req) {
|
||||
return flowctrl.SendRawJPG(req);
|
||||
}
|
||||
|
||||
|
||||
bool isSetupModusActive()
|
||||
{
|
||||
bool isSetupModusActive() {
|
||||
return flowctrl.getStatusSetupModus();
|
||||
}
|
||||
|
||||
@@ -102,19 +96,19 @@ void DeleteMainFlowTask()
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "DeleteMainFlowTask: xHandletask_autodoFlow: %ld", (long) xHandletask_autodoFlow);
|
||||
#endif
|
||||
if( xHandletask_autodoFlow != NULL )
|
||||
{
|
||||
|
||||
if( xHandletask_autodoFlow != NULL ) {
|
||||
vTaskDelete(xHandletask_autodoFlow);
|
||||
xHandletask_autodoFlow = NULL;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Killed: xHandletask_autodoFlow");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void doInit(void)
|
||||
{
|
||||
void doInit() {
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Start flowctrl.InitFlow(config);");
|
||||
#endif
|
||||
@@ -132,8 +126,7 @@ void doInit(void)
|
||||
}
|
||||
|
||||
|
||||
bool doflow(void)
|
||||
{
|
||||
bool doflow() {
|
||||
std::string zw_time = getCurrentTimeString(LOGFILE_TIME_FORMAT);
|
||||
ESP_LOGD(TAG, "doflow - start %s", zw_time.c_str());
|
||||
flowisrunning = true;
|
||||
@@ -148,8 +141,7 @@ bool doflow(void)
|
||||
}
|
||||
|
||||
|
||||
esp_err_t handler_get_heap(httpd_req_t *req)
|
||||
{
|
||||
esp_err_t handler_get_heap(httpd_req_t *req) {
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_get_heap - Start");
|
||||
ESP_LOGD(TAG, "handler_get_heap uri: %s", req->uri);
|
||||
@@ -172,12 +164,10 @@ esp_err_t handler_get_heap(httpd_req_t *req)
|
||||
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
|
||||
if (zw.length() > 0)
|
||||
{
|
||||
if (zw.length() > 0) {
|
||||
httpd_resp_send(req, zw.c_str(), zw.length());
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
httpd_resp_send(req, NULL, 0);
|
||||
}
|
||||
|
||||
@@ -189,8 +179,7 @@ esp_err_t handler_get_heap(httpd_req_t *req)
|
||||
}
|
||||
|
||||
|
||||
esp_err_t handler_init(httpd_req_t *req)
|
||||
{
|
||||
esp_err_t handler_init(httpd_req_t *req) {
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_init - Start");
|
||||
ESP_LOGD(TAG, "handler_doinit uri: %s", req->uri);
|
||||
@@ -213,8 +202,7 @@ esp_err_t handler_init(httpd_req_t *req)
|
||||
}
|
||||
|
||||
|
||||
esp_err_t handler_stream(httpd_req_t *req)
|
||||
{
|
||||
esp_err_t handler_stream(httpd_req_t *req) {
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_stream - Start");
|
||||
ESP_LOGD(TAG, "handler_stream uri: %s", req->uri);
|
||||
@@ -224,18 +212,17 @@ esp_err_t handler_stream(httpd_req_t *req)
|
||||
char _value[10];
|
||||
bool flashlightOn = false;
|
||||
|
||||
if (httpd_req_get_url_query_str(req, _query, 50) == ESP_OK)
|
||||
{
|
||||
if (httpd_req_get_url_query_str(req, _query, 50) == ESP_OK) {
|
||||
// ESP_LOGD(TAG, "Query: %s", _query);
|
||||
if (httpd_query_key_value(_query, "flashlight", _value, 10) == ESP_OK)
|
||||
{
|
||||
if (httpd_query_key_value(_query, "flashlight", _value, 10) == ESP_OK) {
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "flashlight is found%s", _value);
|
||||
#endif
|
||||
if (strlen(_value) > 0)
|
||||
if (strlen(_value) > 0) {
|
||||
flashlightOn = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Camera.CaptureToStream(req, flashlightOn);
|
||||
|
||||
@@ -279,20 +266,17 @@ esp_err_t handler_flow_start(httpd_req_t *req) {
|
||||
|
||||
#ifdef ENABLE_MQTT
|
||||
esp_err_t MQTTCtrlFlowStart(std::string _topic) {
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("MQTTCtrlFlowStart - Start");
|
||||
#endif
|
||||
|
||||
ESP_LOGD(TAG, "MQTTCtrlFlowStart: topic %s", _topic.c_str());
|
||||
|
||||
if (autostartIsEnabled)
|
||||
{
|
||||
if (autostartIsEnabled) {
|
||||
xTaskAbortDelay(xHandletask_autodoFlow); // Delay will be aborted if task is in blocked (waiting) state. If task is already running, no action
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Flow start triggered by MQTT topic " + _topic);
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
LogFile.WriteToFile(ESP_LOG_WARN, TAG, "Flow start triggered by MQTT topic " + _topic + ", but flow is not active!");
|
||||
}
|
||||
|
||||
@@ -305,31 +289,26 @@ esp_err_t MQTTCtrlFlowStart(std::string _topic) {
|
||||
#endif //ENABLE_MQTT
|
||||
|
||||
|
||||
esp_err_t handler_json(httpd_req_t *req)
|
||||
{
|
||||
esp_err_t handler_json(httpd_req_t *req) {
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_json - Start");
|
||||
#endif
|
||||
|
||||
ESP_LOGD(TAG, "handler_JSON uri: %s", req->uri);
|
||||
|
||||
if (bTaskAutoFlowCreated)
|
||||
{
|
||||
if (bTaskAutoFlowCreated) {
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
httpd_resp_set_type(req, "application/json");
|
||||
|
||||
std::string zw = flowctrl.getJSON();
|
||||
if (zw.length() > 0)
|
||||
{
|
||||
if (zw.length() > 0) {
|
||||
httpd_resp_send(req, zw.c_str(), zw.length());
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
httpd_resp_send(req, NULL, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
httpd_resp_send_err(req, HTTPD_403_FORBIDDEN, "Flow not (yet) started: REST API /json not yet available!");
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
@@ -342,14 +321,12 @@ esp_err_t handler_json(httpd_req_t *req)
|
||||
}
|
||||
|
||||
|
||||
esp_err_t handler_wasserzaehler(httpd_req_t *req)
|
||||
{
|
||||
esp_err_t handler_wasserzaehler(httpd_req_t *req) {
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler water counter - Start");
|
||||
#endif
|
||||
|
||||
if (bTaskAutoFlowCreated)
|
||||
{
|
||||
if (bTaskAutoFlowCreated) {
|
||||
bool _rawValue = false;
|
||||
bool _noerror = false;
|
||||
bool _all = false;
|
||||
@@ -361,34 +338,30 @@ esp_err_t handler_wasserzaehler(httpd_req_t *req)
|
||||
char _query[100];
|
||||
char _size[10];
|
||||
|
||||
if (httpd_req_get_url_query_str(req, _query, 100) == ESP_OK)
|
||||
{
|
||||
if (httpd_req_get_url_query_str(req, _query, 100) == ESP_OK) {
|
||||
// ESP_LOGD(TAG, "Query: %s", _query);
|
||||
if (httpd_query_key_value(_query, "all", _size, 10) == ESP_OK)
|
||||
{
|
||||
if (httpd_query_key_value(_query, "all", _size, 10) == ESP_OK) {
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "all is found%s", _size);
|
||||
#endif
|
||||
_all = true;
|
||||
}
|
||||
|
||||
if (httpd_query_key_value(_query, "type", _size, 10) == ESP_OK)
|
||||
{
|
||||
if (httpd_query_key_value(_query, "type", _size, 10) == ESP_OK) {
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "all is found: %s", _size);
|
||||
#endif
|
||||
_type = std::string(_size);
|
||||
}
|
||||
|
||||
if (httpd_query_key_value(_query, "rawvalue", _size, 10) == ESP_OK)
|
||||
{
|
||||
if (httpd_query_key_value(_query, "rawvalue", _size, 10) == ESP_OK) {
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "rawvalue is found: %s", _size);
|
||||
#endif
|
||||
_rawValue = true;
|
||||
}
|
||||
if (httpd_query_key_value(_query, "noerror", _size, 10) == ESP_OK)
|
||||
{
|
||||
|
||||
if (httpd_query_key_value(_query, "noerror", _size, 10) == ESP_OK) {
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "noerror is found: %s", _size);
|
||||
#endif
|
||||
@@ -398,37 +371,42 @@ esp_err_t handler_wasserzaehler(httpd_req_t *req)
|
||||
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
|
||||
if (_all)
|
||||
{
|
||||
if (_all) {
|
||||
httpd_resp_set_type(req, "text/plain");
|
||||
ESP_LOGD(TAG, "TYPE: %s", _type.c_str());
|
||||
int _intype = READOUT_TYPE_VALUE;
|
||||
if (_type == "prevalue")
|
||||
_intype = READOUT_TYPE_PREVALUE;
|
||||
if (_type == "raw")
|
||||
_intype = READOUT_TYPE_RAWVALUE;
|
||||
if (_type == "error")
|
||||
_intype = READOUT_TYPE_ERROR;
|
||||
|
||||
if (_type == "prevalue") {
|
||||
_intype = READOUT_TYPE_PREVALUE;
|
||||
}
|
||||
|
||||
if (_type == "raw") {
|
||||
_intype = READOUT_TYPE_RAWVALUE;
|
||||
}
|
||||
|
||||
if (_type == "error") {
|
||||
_intype = READOUT_TYPE_ERROR;
|
||||
}
|
||||
|
||||
zw = flowctrl.getReadoutAll(_intype);
|
||||
ESP_LOGD(TAG, "ZW: %s", zw.c_str());
|
||||
if (zw.length() > 0)
|
||||
|
||||
if (zw.length() > 0) {
|
||||
httpd_resp_send(req, zw.c_str(), zw.length());
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
std::string *status = flowctrl.getActStatus();
|
||||
string query = std::string(_query);
|
||||
// ESP_LOGD(TAG, "Query: %s, query.c_str());
|
||||
if (query.find("full") != std::string::npos)
|
||||
{
|
||||
if (query.find("full") != std::string::npos) {
|
||||
string txt;
|
||||
txt = "<body style=\"font-family: arial\">";
|
||||
|
||||
if ((countRounds <= 1) && (*status != std::string("Flow finished"))) { // First round not completed yet
|
||||
if ((countRounds <= 1) && (*status != std::string("Flow finished"))) {
|
||||
// First round not completed yet
|
||||
txt += "<h3>Please wait for the first round to complete!</h3><h3>Current state: " + *status + "</h3>\n";
|
||||
}
|
||||
else {
|
||||
@@ -439,15 +417,16 @@ esp_err_t handler_wasserzaehler(httpd_req_t *req)
|
||||
}
|
||||
|
||||
zw = flowctrl.getReadout(_rawValue, _noerror, 0);
|
||||
if (zw.length() > 0)
|
||||
|
||||
if (zw.length() > 0) {
|
||||
httpd_resp_sendstr_chunk(req, zw.c_str());
|
||||
}
|
||||
|
||||
|
||||
if (query.find("full") != std::string::npos)
|
||||
{
|
||||
if (query.find("full") != std::string::npos) {
|
||||
string txt, zw;
|
||||
|
||||
if ((countRounds <= 1) && (*status != std::string("Flow finished"))) { // First round not completed yet
|
||||
if ((countRounds <= 1) && (*status != std::string("Flow finished"))) {
|
||||
// First round not completed yet
|
||||
// Nothing to do
|
||||
}
|
||||
else {
|
||||
@@ -459,23 +438,26 @@ esp_err_t handler_wasserzaehler(httpd_req_t *req)
|
||||
std::vector<HTMLInfo*> htmlinfodig;
|
||||
htmlinfodig = flowctrl.GetAllDigital();
|
||||
|
||||
for (int i = 0; i < htmlinfodig.size(); ++i)
|
||||
{
|
||||
if (flowctrl.GetTypeDigital() == Digital)
|
||||
{
|
||||
if (htmlinfodig[i]->val == 10)
|
||||
for (int i = 0; i < htmlinfodig.size(); ++i) {
|
||||
if (flowctrl.GetTypeDigital() == Digital) {
|
||||
if (htmlinfodig[i]->val >= 10) {
|
||||
zw = "NaN";
|
||||
else
|
||||
}
|
||||
else {
|
||||
zw = to_string((int) htmlinfodig[i]->val);
|
||||
}
|
||||
|
||||
txt += "<td style=\"width: 100px\"><h4>" + zw + "</h4><p><img src=\"/img_tmp/" + htmlinfodig[i]->filename + "\"></p></td>\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
std::stringstream stream;
|
||||
stream << std::fixed << std::setprecision(1) << htmlinfodig[i]->val;
|
||||
zw = stream.str();
|
||||
|
||||
if (std::stod(zw) >= 10) {
|
||||
zw = "NaN";
|
||||
}
|
||||
|
||||
txt += "<td style=\"width: 100px\"><h4>" + zw + "</h4><p><img src=\"/img_tmp/" + htmlinfodig[i]->filename + "\"></p></td>\n";
|
||||
}
|
||||
delete htmlinfodig[i];
|
||||
@@ -486,31 +468,35 @@ esp_err_t handler_wasserzaehler(httpd_req_t *req)
|
||||
txt += "</tr></table>\n";
|
||||
httpd_resp_sendstr_chunk(req, txt.c_str());
|
||||
|
||||
|
||||
/* Analog ROIs */
|
||||
txt = "<hr><h3>Recognized Analog ROIs (previous round)</h3>\n";
|
||||
txt += "<table style=\"border-spacing: 5px\"><tr style=\"text-align: center; vertical-align: top;\">\n";
|
||||
|
||||
std::vector<HTMLInfo*> htmlinfoana;
|
||||
htmlinfoana = flowctrl.GetAllAnalog();
|
||||
for (int i = 0; i < htmlinfoana.size(); ++i)
|
||||
{
|
||||
|
||||
for (int i = 0; i < htmlinfoana.size(); ++i) {
|
||||
std::stringstream stream;
|
||||
stream << std::fixed << std::setprecision(1) << htmlinfoana[i]->val;
|
||||
zw = stream.str();
|
||||
|
||||
if (std::stod(zw) >= 10) {
|
||||
zw = "NaN";
|
||||
}
|
||||
|
||||
txt += "<td style=\"width: 150px;\"><h4>" + zw + "</h4><p><img src=\"/img_tmp/" + htmlinfoana[i]->filename + "\"></p></td>\n";
|
||||
delete htmlinfoana[i];
|
||||
}
|
||||
|
||||
htmlinfoana.clear();
|
||||
|
||||
txt += "</tr>\n</table>\n";
|
||||
httpd_resp_sendstr_chunk(req, txt.c_str());
|
||||
|
||||
|
||||
/* Full Image
|
||||
* Only show it after the image got taken and aligned */
|
||||
txt = "<hr><h3>Aligned Image (current round)</h3>\n";
|
||||
|
||||
if ((*status == std::string("Initialization")) ||
|
||||
(*status == std::string("Initialization (delayed)")) ||
|
||||
(*status == std::string("Take Image"))) {
|
||||
@@ -526,8 +512,7 @@ esp_err_t handler_wasserzaehler(httpd_req_t *req)
|
||||
/* Respond with an empty chunk to signal HTTP response completion */
|
||||
httpd_resp_sendstr_chunk(req, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
httpd_resp_send_err(req, HTTPD_403_FORBIDDEN, "Flow not (yet) started: REST API /value not available!");
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
@@ -540,8 +525,7 @@ esp_err_t handler_wasserzaehler(httpd_req_t *req)
|
||||
}
|
||||
|
||||
|
||||
esp_err_t handler_editflow(httpd_req_t *req)
|
||||
{
|
||||
esp_err_t handler_editflow(httpd_req_t *req) {
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_editflow - Start");
|
||||
#endif
|
||||
@@ -552,10 +536,8 @@ esp_err_t handler_editflow(httpd_req_t *req)
|
||||
char _valuechar[30];
|
||||
string _task;
|
||||
|
||||
if (httpd_req_get_url_query_str(req, _query, 200) == ESP_OK)
|
||||
{
|
||||
if (httpd_query_key_value(_query, "task", _valuechar, 30) == ESP_OK)
|
||||
{
|
||||
if (httpd_req_get_url_query_str(req, _query, 200) == ESP_OK) {
|
||||
if (httpd_query_key_value(_query, "task", _valuechar, 30) == ESP_OK) {
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "task is found: %s", _valuechar);
|
||||
#endif
|
||||
@@ -563,27 +545,22 @@ esp_err_t handler_editflow(httpd_req_t *req)
|
||||
}
|
||||
}
|
||||
|
||||
if (_task.compare("namenumbers") == 0)
|
||||
{
|
||||
if (_task.compare("namenumbers") == 0) {
|
||||
ESP_LOGD(TAG, "Get NUMBER list");
|
||||
return get_numbers_file_handler(req);
|
||||
}
|
||||
|
||||
if (_task.compare("data") == 0)
|
||||
{
|
||||
if (_task.compare("data") == 0) {
|
||||
ESP_LOGD(TAG, "Get data list");
|
||||
return get_data_file_handler(req);
|
||||
}
|
||||
|
||||
if (_task.compare("tflite") == 0)
|
||||
{
|
||||
if (_task.compare("tflite") == 0) {
|
||||
ESP_LOGD(TAG, "Get tflite list");
|
||||
return get_tflite_file_handler(req);
|
||||
}
|
||||
|
||||
|
||||
if (_task.compare("copy") == 0)
|
||||
{
|
||||
if (_task.compare("copy") == 0) {
|
||||
string in, out, zw;
|
||||
|
||||
httpd_query_key_value(_query, "in", _valuechar, 30);
|
||||
@@ -605,9 +582,7 @@ esp_err_t handler_editflow(httpd_req_t *req)
|
||||
httpd_resp_send(req, zw.c_str(), zw.length());
|
||||
}
|
||||
|
||||
|
||||
if (_task.compare("cutref") == 0)
|
||||
{
|
||||
if (_task.compare("cutref") == 0) {
|
||||
string in, out, zw;
|
||||
int x, y, dx, dy;
|
||||
bool enhance = false;
|
||||
@@ -643,11 +618,9 @@ esp_err_t handler_editflow(httpd_req_t *req)
|
||||
ESP_LOGD(TAG, "dy: %s", zw.c_str());
|
||||
#endif
|
||||
|
||||
if (httpd_query_key_value(_query, "enhance", _valuechar, 10) == ESP_OK)
|
||||
{
|
||||
if (httpd_query_key_value(_query, "enhance", _valuechar, 10) == ESP_OK) {
|
||||
zw = string(_valuechar);
|
||||
if (zw.compare("true") == 0)
|
||||
{
|
||||
if (zw.compare("true") == 0) {
|
||||
enhance = true;
|
||||
}
|
||||
}
|
||||
@@ -665,8 +638,7 @@ esp_err_t handler_editflow(httpd_req_t *req)
|
||||
delete caic;
|
||||
|
||||
CImageBasis *cim = new CImageBasis("cutref", out2);
|
||||
if (enhance)
|
||||
{
|
||||
if (enhance) {
|
||||
cim->Contrast(90);
|
||||
}
|
||||
|
||||
@@ -674,8 +646,6 @@ esp_err_t handler_editflow(httpd_req_t *req)
|
||||
delete cim;
|
||||
|
||||
psram_deinit_shared_memory_for_take_image_step();
|
||||
|
||||
|
||||
zw = "CutImage Done";
|
||||
}
|
||||
else {
|
||||
@@ -686,55 +656,128 @@ esp_err_t handler_editflow(httpd_req_t *req)
|
||||
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
httpd_resp_send(req, zw.c_str(), zw.length());
|
||||
|
||||
}
|
||||
|
||||
if (_task.compare("test_take") == 0)
|
||||
{
|
||||
if ((_task.compare("test_take") == 0) || (_task.compare("cam_settings") == 0)) {
|
||||
std::string _zw = "";
|
||||
std::string _host = "";
|
||||
std::string _bri = "";
|
||||
std::string _con = "";
|
||||
std::string _sat = "";
|
||||
std::string _int = "";
|
||||
int bri = -100;
|
||||
int sat = -100;
|
||||
int con = -100;
|
||||
int intens = -100;
|
||||
int aelevel = 0;
|
||||
int zoommode = 0;
|
||||
int zoomoffsetx = 0;
|
||||
int zoomoffsety = 0;
|
||||
bool zoom = false;
|
||||
bool negative = false;
|
||||
bool aec2 = false;
|
||||
int sharpnessLevel = 0;
|
||||
#ifdef GRAYSCALE_AS_DEFAULT
|
||||
bool grayscale = true;
|
||||
#else
|
||||
bool grayscale = false;
|
||||
#endif
|
||||
|
||||
if (httpd_query_key_value(_query, "host", _valuechar, 30) == ESP_OK) {
|
||||
_host = std::string(_valuechar);
|
||||
}
|
||||
if (httpd_query_key_value(_query, "int", _valuechar, 30) == ESP_OK) {
|
||||
_int = std::string(_valuechar);
|
||||
std::string _int = std::string(_valuechar);
|
||||
intens = stoi(_int);
|
||||
}
|
||||
if (httpd_query_key_value(_query, "bri", _valuechar, 30) == ESP_OK) {
|
||||
_bri = std::string(_valuechar);
|
||||
std::string _bri = std::string(_valuechar);
|
||||
bri = stoi(_bri);
|
||||
}
|
||||
if (httpd_query_key_value(_query, "con", _valuechar, 30) == ESP_OK) {
|
||||
_con = std::string(_valuechar);
|
||||
std::string _con = std::string(_valuechar);
|
||||
con = stoi(_con);
|
||||
}
|
||||
if (httpd_query_key_value(_query, "sat", _valuechar, 30) == ESP_OK) {
|
||||
_sat = std::string(_valuechar);
|
||||
std::string _sat = std::string(_valuechar);
|
||||
sat = stoi(_sat);
|
||||
}
|
||||
|
||||
if (httpd_query_key_value(_query, "ae", _valuechar, 30) == ESP_OK) {
|
||||
std::string _ae = std::string(_valuechar);
|
||||
aelevel = stoi(_ae);
|
||||
}
|
||||
if (httpd_query_key_value(_query, "sh", _valuechar, 30) == ESP_OK) {
|
||||
std::string _sh = std::string(_valuechar);
|
||||
sharpnessLevel = stoi(_sh);
|
||||
}
|
||||
if (httpd_query_key_value(_query, "gs", _valuechar, 30) == ESP_OK) {
|
||||
std::string _gr = std::string(_valuechar);
|
||||
if (stoi(_gr) != 0) {
|
||||
grayscale = true;
|
||||
}
|
||||
else {
|
||||
grayscale = false;
|
||||
}
|
||||
}
|
||||
if (httpd_query_key_value(_query, "ne", _valuechar, 30) == ESP_OK) {
|
||||
std::string _ne = std::string(_valuechar);
|
||||
if (stoi(_ne) != 0) {
|
||||
negative = true;
|
||||
}
|
||||
else {
|
||||
negative = false;
|
||||
}
|
||||
}
|
||||
if (httpd_query_key_value(_query, "a2", _valuechar, 30) == ESP_OK) {
|
||||
std::string _a2 = std::string(_valuechar);
|
||||
if (stoi(_a2) != 0) {
|
||||
aec2 = true;
|
||||
}
|
||||
else {
|
||||
aec2 = false;
|
||||
}
|
||||
}
|
||||
if (httpd_query_key_value(_query, "z", _valuechar, 30) == ESP_OK) {
|
||||
std::string _zoom = std::string(_valuechar);
|
||||
if (stoi(_zoom) != 0) {
|
||||
zoom = true;
|
||||
}
|
||||
else {
|
||||
zoom = false;
|
||||
}
|
||||
}
|
||||
if (httpd_query_key_value(_query, "zm", _valuechar, 30) == ESP_OK) {
|
||||
std::string _zm = std::string(_valuechar);
|
||||
zoommode = stoi(_zm);
|
||||
}
|
||||
if (httpd_query_key_value(_query, "x", _valuechar, 30) == ESP_OK) {
|
||||
std::string _x = std::string(_valuechar);
|
||||
zoomoffsetx = stoi(_x);
|
||||
}
|
||||
if (httpd_query_key_value(_query, "y", _valuechar, 30) == ESP_OK) {
|
||||
std::string _y = std::string(_valuechar);
|
||||
zoomoffsety = stoi(_y);
|
||||
}
|
||||
|
||||
// ESP_LOGD(TAG, "Parameter host: %s", _host.c_str());
|
||||
// string zwzw = "Do " + _task + " start\n"; ESP_LOGD(TAG, zwzw.c_str());
|
||||
Camera.SetBrightnessContrastSaturation(bri, con, sat);
|
||||
Camera.SetZoom(zoom, zoommode, zoomoffsetx, zoomoffsety);
|
||||
Camera.SetBrightnessContrastSaturation(bri, con, sat, aelevel, grayscale, negative, aec2, sharpnessLevel);
|
||||
Camera.SetLEDIntensity(intens);
|
||||
ESP_LOGD(TAG, "test_take - vor TakeImage");
|
||||
std::string zw = flowctrl.doSingleStep("[TakeImage]", _host);
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
httpd_resp_send(req, zw.c_str(), zw.length());
|
||||
|
||||
if (_task.compare("cam_settings") == 0)
|
||||
{
|
||||
ESP_LOGD(TAG, "Cam Settings set");
|
||||
_zw = "Cam Settings set";
|
||||
}
|
||||
|
||||
|
||||
if (_task.compare("test_align") == 0)
|
||||
else
|
||||
{
|
||||
ESP_LOGD(TAG, "test_take - vor TakeImage");
|
||||
_zw = flowctrl.doSingleStep("[TakeImage]", _host);
|
||||
}
|
||||
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
httpd_resp_send(req, _zw.c_str(), _zw.length());
|
||||
}
|
||||
|
||||
if (_task.compare("test_align") == 0) {
|
||||
std::string _host = "";
|
||||
if (httpd_query_key_value(_query, "host", _valuechar, 30) == ESP_OK) {
|
||||
_host = std::string(_valuechar);
|
||||
@@ -755,8 +798,7 @@ esp_err_t handler_editflow(httpd_req_t *req)
|
||||
}
|
||||
|
||||
|
||||
esp_err_t handler_statusflow(httpd_req_t *req)
|
||||
{
|
||||
esp_err_t handler_statusflow(httpd_req_t *req) {
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_statusflow - Start");
|
||||
#endif
|
||||
@@ -764,8 +806,7 @@ esp_err_t handler_statusflow(httpd_req_t *req)
|
||||
const char* resp_str;
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
|
||||
if (bTaskAutoFlowCreated)
|
||||
{
|
||||
if (bTaskAutoFlowCreated) {
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "handler_statusflow: %s", req->uri);
|
||||
#endif
|
||||
@@ -775,8 +816,7 @@ esp_err_t handler_statusflow(httpd_req_t *req)
|
||||
|
||||
httpd_resp_send(req, resp_str, HTTPD_RESP_USE_STRLEN);
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
resp_str = "Flow task not yet created";
|
||||
httpd_resp_send(req, resp_str, HTTPD_RESP_USE_STRLEN);
|
||||
}
|
||||
@@ -789,8 +829,7 @@ esp_err_t handler_statusflow(httpd_req_t *req)
|
||||
}
|
||||
|
||||
|
||||
esp_err_t handler_cputemp(httpd_req_t *req)
|
||||
{
|
||||
esp_err_t handler_cputemp(httpd_req_t *req) {
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_cputemp - Start");
|
||||
#endif
|
||||
@@ -806,19 +845,16 @@ esp_err_t handler_cputemp(httpd_req_t *req)
|
||||
}
|
||||
|
||||
|
||||
esp_err_t handler_rssi(httpd_req_t *req)
|
||||
{
|
||||
esp_err_t handler_rssi(httpd_req_t *req) {
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_rssi - Start");
|
||||
#endif
|
||||
|
||||
if (getWIFIisConnected())
|
||||
{
|
||||
if (getWIFIisConnected()) {
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
httpd_resp_send(req, std::to_string(get_WIFI_RSSI()).c_str(), HTTPD_RESP_USE_STRLEN);
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
httpd_resp_send_err(req, HTTPD_403_FORBIDDEN, "WIFI not (yet) connected: REST API /rssi not available!");
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
@@ -831,9 +867,7 @@ esp_err_t handler_rssi(httpd_req_t *req)
|
||||
}
|
||||
|
||||
|
||||
esp_err_t handler_uptime(httpd_req_t *req)
|
||||
{
|
||||
|
||||
esp_err_t handler_uptime(httpd_req_t *req) {
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_uptime - Start");
|
||||
#endif
|
||||
@@ -851,8 +885,7 @@ esp_err_t handler_uptime(httpd_req_t *req)
|
||||
}
|
||||
|
||||
|
||||
esp_err_t handler_prevalue(httpd_req_t *req)
|
||||
{
|
||||
esp_err_t handler_prevalue(httpd_req_t *req) {
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_prevalue - Start");
|
||||
ESP_LOGD(TAG, "handler_prevalue: %s", req->uri);
|
||||
@@ -881,7 +914,8 @@ esp_err_t handler_prevalue(httpd_req_t *req)
|
||||
ESP_LOGD(TAG, "Query: %s", _query);
|
||||
#endif
|
||||
|
||||
if (httpd_query_key_value(_query, "numbers", _numbersname, 50) != ESP_OK) { // If request is incomplete
|
||||
if (httpd_query_key_value(_query, "numbers", _numbersname, 50) != ESP_OK) {
|
||||
// If request is incomplete
|
||||
sReturnMessage = "E91: Query parameter incomplete or not valid!<br> "
|
||||
"Call /setPreValue to show REST API usage info and/or check documentation";
|
||||
httpd_resp_send(req, sReturnMessage.c_str(), sReturnMessage.length());
|
||||
@@ -894,12 +928,14 @@ esp_err_t handler_prevalue(httpd_req_t *req)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else { // if no parameter is provided, print handler usage
|
||||
else {
|
||||
// if no parameter is provided, print handler usage
|
||||
httpd_resp_send(req, RESTUsageInfo.c_str(), RESTUsageInfo.length());
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
if (strlen(_value) == 0) { // If no value is povided --> return actual PreValue
|
||||
if (strlen(_value) == 0) {
|
||||
// If no value is povided --> return actual PreValue
|
||||
sReturnMessage = flowctrl.GetPrevalue(std::string(_numbersname));
|
||||
|
||||
if (sReturnMessage.empty()) {
|
||||
@@ -938,14 +974,12 @@ esp_err_t handler_prevalue(httpd_req_t *req)
|
||||
}
|
||||
|
||||
|
||||
void task_autodoFlow(void *pvParameter)
|
||||
{
|
||||
void task_autodoFlow(void *pvParameter) {
|
||||
int64_t fr_start, fr_delta_ms;
|
||||
|
||||
bTaskAutoFlowCreated = true;
|
||||
|
||||
if (!isPlannedReboot && (esp_reset_reason() == ESP_RST_PANIC))
|
||||
{
|
||||
if (!isPlannedReboot && (esp_reset_reason() == ESP_RST_PANIC)) {
|
||||
flowctrl.setActStatus("Initialization (delayed)");
|
||||
//#ifdef ENABLE_MQTT
|
||||
//MQTTPublish(mqttServer_getMainTopic() + "/" + "status", "Initialization (delayed)", false); // Right now, not possible -> MQTT Service is going to be started later
|
||||
@@ -959,8 +993,7 @@ void task_autodoFlow(void *pvParameter)
|
||||
flowctrl.setAutoStartInterval(auto_interval);
|
||||
autostartIsEnabled = flowctrl.getIsAutoStart();
|
||||
|
||||
if (isSetupModusActive())
|
||||
{
|
||||
if (isSetupModusActive()) {
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "We are in Setup Mode -> Not starting Auto Flow!");
|
||||
autostartIsEnabled = false;
|
||||
std::string zw_time = getCurrentTimeString(LOGFILE_TIME_FORMAT);
|
||||
@@ -974,22 +1007,19 @@ void task_autodoFlow(void *pvParameter)
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Autostart is not enabled -> Not starting Flow");
|
||||
}
|
||||
|
||||
while (autostartIsEnabled)
|
||||
{
|
||||
while (autostartIsEnabled) {
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "----------------------------------------------------------------"); // Clear separation between runs
|
||||
std::string _zw = "Round #" + std::to_string(++countRounds) + " started";
|
||||
time_t roundStartTime = getUpTime();
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, _zw);
|
||||
fr_start = esp_timer_get_time();
|
||||
|
||||
if (flowisrunning)
|
||||
{
|
||||
if (flowisrunning) {
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Autoflow: doFlow is already running!");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Autoflow: doFlow is started");
|
||||
#endif
|
||||
@@ -1029,16 +1059,16 @@ void task_autodoFlow(void *pvParameter)
|
||||
#endif
|
||||
|
||||
fr_delta_ms = (esp_timer_get_time() - fr_start) / 1000;
|
||||
if (auto_interval > fr_delta_ms)
|
||||
{
|
||||
|
||||
if (auto_interval > fr_delta_ms) {
|
||||
const TickType_t xDelay = (auto_interval - fr_delta_ms) / portTICK_PERIOD_MS;
|
||||
ESP_LOGD(TAG, "Autoflow: sleep for: %ldms", (long) xDelay);
|
||||
vTaskDelay( xDelay );
|
||||
}
|
||||
}
|
||||
|
||||
while(1) // Keep flow task running to handle necessary sub tasks like reboot handler, etc..
|
||||
{
|
||||
while(1) {
|
||||
// Keep flow task running to handle necessary sub tasks like reboot handler, etc..
|
||||
vTaskDelay(2000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
|
||||
@@ -1048,25 +1078,24 @@ void task_autodoFlow(void *pvParameter)
|
||||
}
|
||||
|
||||
|
||||
void InitializeFlowTask()
|
||||
{
|
||||
void InitializeFlowTask() {
|
||||
BaseType_t xReturned;
|
||||
|
||||
ESP_LOGD(TAG, "getESPHeapInfo: %s", getESPHeapInfo().c_str());
|
||||
|
||||
uint32_t stackSize = 16 * 1024;
|
||||
xReturned = xTaskCreatePinnedToCore(&task_autodoFlow, "task_autodoFlow", stackSize, NULL, tskIDLE_PRIORITY+2, &xHandletask_autodoFlow, 0);
|
||||
if( xReturned != pdPASS )
|
||||
{
|
||||
|
||||
if( xReturned != pdPASS ) {
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Creation task_autodoFlow failed. Requested stack size:" + std::to_string(stackSize));
|
||||
LogFile.WriteHeapInfo("Creation task_autodoFlow failed");
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "getESPHeapInfo: %s", getESPHeapInfo().c_str());
|
||||
}
|
||||
|
||||
|
||||
void register_server_main_flow_task_uri(httpd_handle_t server)
|
||||
{
|
||||
void register_server_main_flow_task_uri(httpd_handle_t server) {
|
||||
ESP_LOGI(TAG, "server_main_flow_task - Registering URI handlers");
|
||||
|
||||
httpd_uri_t camuri = { };
|
||||
@@ -1166,5 +1195,4 @@ void register_server_main_flow_task_uri(httpd_handle_t server)
|
||||
camuri.handler = handler_stream;
|
||||
camuri.user_ctx = (void*) "stream";
|
||||
httpd_register_uri_handler(server, &camuri);
|
||||
|
||||
}
|
||||
|
||||
@@ -443,7 +443,7 @@ void CImageBasis::LoadFromMemory(stbi_uc *_buffer, int len)
|
||||
//free_psram_heap(std::string(TAG) + "->rgb_image (LoadFromMemory)", rgb_image);
|
||||
}
|
||||
|
||||
rgb_image = stbi_load_from_memory(_buffer, len, &width, &height, &channels, 3);
|
||||
rgb_image = stbi_load_from_memory(_buffer, len, &width, &height, &channels, STBI_rgb);
|
||||
bpp = channels;
|
||||
ESP_LOGD(TAG, "Image loaded from memory: %d, %d, %d", width, height, channels);
|
||||
|
||||
@@ -459,6 +459,44 @@ void CImageBasis::LoadFromMemory(stbi_uc *_buffer, int len)
|
||||
}
|
||||
|
||||
|
||||
void CImageBasis::crop_image(unsigned short cropLeft, unsigned short cropRight, unsigned short cropTop, unsigned short cropBottom)
|
||||
{
|
||||
unsigned int maxTopIndex = cropTop * width * channels;
|
||||
unsigned int minBottomIndex = ((width*height) - (cropBottom * width)) * channels;
|
||||
unsigned short maxX = width - cropRight; // In pixels
|
||||
unsigned short newWidth = width - cropLeft - cropRight;
|
||||
unsigned short newHeight = height - cropTop - cropBottom;
|
||||
|
||||
unsigned int writeIndex = 0;
|
||||
// Loop over all bytes
|
||||
for (int i = 0; i < width * height * channels; i += channels) {
|
||||
// Calculate current X, Y pixel position
|
||||
int x = (i/channels) % width;
|
||||
|
||||
// Crop from the top
|
||||
if (i < maxTopIndex) { continue; }
|
||||
|
||||
// Crop from the bottom
|
||||
if (i > minBottomIndex) { continue; }
|
||||
|
||||
// Crop from the left
|
||||
if (x <= cropLeft) { continue; }
|
||||
|
||||
// Crop from the right
|
||||
if (x > maxX) { continue; }
|
||||
|
||||
// If we get here, keep the pixels
|
||||
for (int c = 0; c < channels; c++) {
|
||||
rgb_image[writeIndex++] = rgb_image[i+c];
|
||||
}
|
||||
}
|
||||
|
||||
// Set the new dimensions of the framebuffer for further use.
|
||||
width = newWidth;
|
||||
height = newHeight;
|
||||
}
|
||||
|
||||
|
||||
CImageBasis::CImageBasis(string _name, CImageBasis *_copyfrom)
|
||||
{
|
||||
name = _name;
|
||||
@@ -598,6 +636,20 @@ CImageBasis::CImageBasis(string _name, uint8_t* _rgb_image, int _channels, int _
|
||||
}
|
||||
|
||||
|
||||
void CImageBasis::Negative(void)
|
||||
{
|
||||
RGBImageLock();
|
||||
|
||||
for (int i = 0; i < width * height * channels; i += channels) {
|
||||
for (int c = 0; c < channels; c++) {
|
||||
rgb_image[i+c] = 255 - rgb_image[i+c];
|
||||
}
|
||||
}
|
||||
|
||||
RGBImageRelease();
|
||||
}
|
||||
|
||||
|
||||
void CImageBasis::Contrast(float _contrast) //input range [-100..100]
|
||||
{
|
||||
stbi_uc* p_source;
|
||||
|
||||
@@ -56,6 +56,7 @@ class CImageBasis
|
||||
void drawEllipse(int x1, int y1, int radx, int rady, int r, int g, int b, int thickness = 1);
|
||||
|
||||
void setPixelColor(int x, int y, int r, int g, int b);
|
||||
void Negative(void);
|
||||
void Contrast(float _contrast);
|
||||
bool ImageOkay();
|
||||
bool CopyFromMemory(uint8_t* _source, int _size);
|
||||
@@ -74,6 +75,7 @@ class CImageBasis
|
||||
|
||||
void Resize(int _new_dx, int _new_dy);
|
||||
void Resize(int _new_dx, int _new_dy, CImageBasis *_target);
|
||||
void crop_image(unsigned short cropLeft, unsigned short cropRight, unsigned short cropTop, unsigned short cropBottom);
|
||||
|
||||
void LoadFromMemory(stbi_uc *_buffer, int len);
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ static const char *TAG = "MQTT SERVER";
|
||||
extern const char* libfive_git_version(void);
|
||||
extern const char* libfive_git_revision(void);
|
||||
extern const char* libfive_git_branch(void);
|
||||
extern std::string getFwVersion(void);
|
||||
|
||||
std::vector<NumberPost*>* NUMBERS;
|
||||
bool HomeassistantDiscovery = false;
|
||||
@@ -151,6 +152,7 @@ bool MQTThomeassistantDiscovery(int qos) {
|
||||
// Group | Field | User Friendly Name | Icon | Unit | Device Class | State Class | Entity Category
|
||||
allSendsSuccessed |= sendHomeAssistantDiscoveryTopic("", "uptime", "Uptime", "clock-time-eight-outline", "s", "", "", "diagnostic", qos);
|
||||
allSendsSuccessed |= sendHomeAssistantDiscoveryTopic("", "MAC", "MAC Address", "network-outline", "", "", "", "diagnostic", qos);
|
||||
allSendsSuccessed |= sendHomeAssistantDiscoveryTopic("", "fwVersion", "Firmware Version", "application-outline", "", "", "", "diagnostic", qos);
|
||||
allSendsSuccessed |= sendHomeAssistantDiscoveryTopic("", "hostname", "Hostname", "network-outline", "", "", "", "diagnostic", qos);
|
||||
allSendsSuccessed |= sendHomeAssistantDiscoveryTopic("", "freeMem", "Free Memory", "memory", "B", "", "measurement", "diagnostic", qos);
|
||||
allSendsSuccessed |= sendHomeAssistantDiscoveryTopic("", "wifiRSSI", "Wi-Fi RSSI", "wifi", "dBm", "signal_strength", "", "diagnostic", qos);
|
||||
@@ -244,6 +246,7 @@ bool publishStaticData(int qos) {
|
||||
|
||||
int aFreeInternalHeapSizeBefore = heap_caps_get_free_size(MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
|
||||
|
||||
allSendsSuccessed |= MQTTPublish(maintopic + "/" + "fwVersion", getFwVersion().c_str(), qos, retainFlag);
|
||||
allSendsSuccessed |= MQTTPublish(maintopic + "/" + "MAC", getMac(), qos, retainFlag);
|
||||
allSendsSuccessed |= MQTTPublish(maintopic + "/" + "IP", *getIPAddress(), qos, retainFlag);
|
||||
allSendsSuccessed |= MQTTPublish(maintopic + "/" + "hostname", wlan_config.hostname, qos, retainFlag);
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
#define FLASH_GPIO GPIO_NUM_4 // PIN for flashlight LED
|
||||
#define USE_PWM_LEDFLASH // if __LEDGLOBAL is defined, a global variable is used for LED control, otherwise locally and each time a new
|
||||
#define CAM_LIVESTREAM_REFRESHRATE 500 // Camera livestream feature: Waiting time in milliseconds to refresh image
|
||||
// #define GRAYSCALE_AS_DEFAULT
|
||||
|
||||
|
||||
//ClassControllCamera + ClassFlowTakeImage
|
||||
|
||||
@@ -109,11 +109,6 @@ CONFIG_ESP_INT_WDT_TIMEOUT_MS=300
|
||||
|
||||
CONFIG_HTTPD_MAX_REQ_HDR_LEN=1024
|
||||
CONFIG_HTTPD_PURGE_BUF_LEN=16
|
||||
<<<<<<< Updated upstream
|
||||
=======
|
||||
CONFIG_HTTPD_WS_SUPPORT=y
|
||||
CONFIG_LWIP_MAX_SOCKETS=12
|
||||
>>>>>>> Stashed changes
|
||||
|
||||
CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=16
|
||||
CONFIG_ESP32_WIFI_CACHE_TX_BUFFER_NUM=16
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "test_flow_postrocess_helper.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* ACHTUNG! Die Test laufen aktuell nur mit ausgeschaltetem Debug in ClassFlowCNNGeneral
|
||||
@@ -541,64 +542,4 @@ void test_doFlowPP4() {
|
||||
|
||||
}
|
||||
|
||||
std::string postProcess(std::vector<float> digits,
|
||||
std::vector<float> analogs,
|
||||
float analog2DigitalTransition=0.0)
|
||||
{
|
||||
std::unique_ptr<UnderTestPost> undertestPost(init_do_flow(std::move(analogs),
|
||||
std::move(digits),
|
||||
Digital100,
|
||||
false, false));
|
||||
|
||||
setAnalogdigitTransistionStart(undertestPost.get(), analog2DigitalTransition);
|
||||
return process_doFlow(undertestPost.get());
|
||||
}
|
||||
|
||||
void test_doFlowLateTransition()
|
||||
{
|
||||
// in these test cases, the last digit before comma turns 3.6 too late
|
||||
float a2dt = 3.6;
|
||||
|
||||
// meter shows 011.0210 but it already needs to be 012.0210, before transition
|
||||
TEST_ASSERT_EQUAL_STRING("12.0210", postProcess({0.0, 1.0, 1.0}, {0.2, 2.2, 1.0, 0.0}, a2dt).c_str());
|
||||
|
||||
// meter shows 011.3210 but it already needs to be 012.3210, just before transition
|
||||
TEST_ASSERT_EQUAL_STRING("12.3210", postProcess({0.0, 1.0, 1.2}, {3.3, 2.2, 1.0, 0.0}, a2dt).c_str());
|
||||
|
||||
// meter shows 012.4210 , this is after transition
|
||||
TEST_ASSERT_EQUAL_STRING("12.4210", postProcess({0.0, 1.0, 2.0}, {4.3, 2.2, 1.0, 0.0}, a2dt).c_str());
|
||||
|
||||
// meter shows 012.987
|
||||
TEST_ASSERT_EQUAL_STRING("12.9870", postProcess({0.0, 1.0, 2.0}, {9.8, 8.7, 7.0, 0.0}, a2dt).c_str());
|
||||
|
||||
// meter shows 0012.003
|
||||
TEST_ASSERT_EQUAL_STRING("13.003", postProcess({0.0, 0.0, 1.0, 2.0}, {0.1, 0.3, 3.1}, a2dt).c_str());
|
||||
|
||||
// meter shows 0012.351
|
||||
TEST_ASSERT_EQUAL_STRING("13.351", postProcess({0.0, 0.0, 1.0, 2.8}, {3.5, 5.2, 1.1}, a2dt).c_str());
|
||||
|
||||
// meter shows 0013.421
|
||||
TEST_ASSERT_EQUAL_STRING("13.421", postProcess({0.0, 0.0, 1.0, 3.0}, {4.1, 2.2, 1.1}, a2dt).c_str());
|
||||
}
|
||||
|
||||
void test_doFlowEarlyTransition()
|
||||
{
|
||||
// in these test cases, the last digit before comma turns at around 7.5
|
||||
// start transition 7.0 end transition 8.0
|
||||
float a2dt = 7.5;
|
||||
|
||||
// meter shows 011.0210 but it already needs to be 012.0210, before transition
|
||||
TEST_ASSERT_EQUAL_STRING("12.6789", postProcess({0.0, 1.0, 2.0}, {6.7, 7.8, 8.9, 9.0}, a2dt).c_str());
|
||||
|
||||
TEST_ASSERT_EQUAL_STRING("12.7234", postProcess({0.0, 1.0, 2.4}, {7.2, 2.3, 3.4, 4.0}, a2dt).c_str());
|
||||
|
||||
TEST_ASSERT_EQUAL_STRING("12.7789", postProcess({0.0, 1.0, 2.7}, {7.7, 7.8, 8.9, 9.0}, a2dt).c_str());
|
||||
|
||||
TEST_ASSERT_EQUAL_STRING("12.8123", postProcess({0.0, 1.0, 3.0}, {8.1, 1.2, 2.3, 3.0}, a2dt).c_str());
|
||||
|
||||
TEST_ASSERT_EQUAL_STRING("13.1234", postProcess({0.0, 1.0, 3.0}, {1.2, 2.3, 3.4, 4.0}, a2dt).c_str());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -164,8 +164,6 @@ extern "C" void app_main()
|
||||
RUN_TEST(test_doFlowPP2);
|
||||
RUN_TEST(test_doFlowPP3);
|
||||
RUN_TEST(test_doFlowPP4);
|
||||
RUN_TEST(test_doFlowLateTransition);
|
||||
RUN_TEST(test_doFlowEarlyTransition);
|
||||
|
||||
// getReadoutRawString test
|
||||
RUN_TEST(test_getReadoutRawString);
|
||||
|
||||
@@ -2,16 +2,10 @@ demo
|
||||
WaitBeforeTakingPicture
|
||||
ImageQuality
|
||||
ImageSize
|
||||
LEDIntensity
|
||||
Brightness
|
||||
Contrast
|
||||
Saturation
|
||||
FixedExposure
|
||||
SearchFieldX
|
||||
SearchFieldY
|
||||
AlignmentAlgo
|
||||
InitialMirror
|
||||
FlipImageSize
|
||||
CNNGoodThreshold
|
||||
PreValueAgeStartup
|
||||
ErrorMessage
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
# Parameter `FlipImageSize`
|
||||
Default Value: `false`
|
||||
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
!!! Note
|
||||
This parameter can also be set on the Reference Image configuration page!
|
||||
|
||||
!!! Note
|
||||
This parameter can also be set on the Reference Image configuration.
|
||||
After changing this parameter you need to update your reference image and alignment markers!
|
||||
|
||||
This parameter can be used to rotate the viewport together with the alignment rotation:
|
||||

|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# Parameter `InitialMirror`
|
||||
Default Value: `false`
|
||||
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
!!! Note
|
||||
This parameter can also be set on the Reference Image configuration page!
|
||||
|
||||
!!! Note
|
||||
This parameter can also be set on the Reference Image configuration.
|
||||
After changing this parameter you need to update your reference image and alignment markers!
|
||||
|
||||
Option for initially mirroring the image on the original x-axis.
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
# Parameter `InitialRotate`
|
||||
Default Value: `179`
|
||||
Default Value: `0`
|
||||
|
||||
Unit: Degrees
|
||||
|
||||
Initial rotation of image before alignment in degree (0 .. 359)
|
||||
!!! Note
|
||||
This parameter can also be set on the Reference Image configuration page!
|
||||
|
||||
!!! Note
|
||||
This parameter is accessible on the Reference Image Page but not on the Config page!
|
||||
After changing this parameter you need to update your reference image and alignment markers!
|
||||
|
||||
Initial rotation of image before alignment in degree (`-360` .. `+360`)
|
||||
|
||||
13
param-docs/parameter-pages/TakeImage/Aec2.md
Normal file
13
param-docs/parameter-pages/TakeImage/Aec2.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# Parameter `Aec2`
|
||||
Default Value: `false`
|
||||
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
|
||||
!!! Note
|
||||
This parameter can also be set on the Reference Image configuration page!
|
||||
|
||||
!!! Note
|
||||
After changing this parameter you need to update your reference image and alignment markers!
|
||||
|
||||
Switch to "Auto-exposure Control 2" algorithm. This may resolve some over-exposure and under-exposure issues.
|
||||
15
param-docs/parameter-pages/TakeImage/AutoExposureLevel.md
Normal file
15
param-docs/parameter-pages/TakeImage/AutoExposureLevel.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Parameter `AutoExposureLevel`
|
||||
Default Value: `0`
|
||||
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
|
||||
!!! Note
|
||||
This parameter can also be set on the Reference Image configuration page!
|
||||
|
||||
!!! Note
|
||||
After changing this parameter you need to update your reference image and alignment markers!
|
||||
|
||||
Exposure compensation. Lower values produce darker image.
|
||||
|
||||
Range (`-2` .. `2`)
|
||||
@@ -1,10 +1,10 @@
|
||||
# Parameter `Brightness`
|
||||
Default Value: `0`
|
||||
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
!!! Note
|
||||
This parameter can also be set on the Reference Image configuration page!
|
||||
|
||||
!!! Note
|
||||
This parameter can also be set on the Reference Image configuration.
|
||||
After changing this parameter you need to update your reference image and alignment markers!
|
||||
|
||||
Image Brightness (`-2` .. `2`)
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
# Parameter `Contrast`
|
||||
Default Value: `0`
|
||||
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
!!! Note
|
||||
This parameter can also be set on the Reference Image configuration page!
|
||||
|
||||
!!! Note
|
||||
This parameter can also be set on the Reference Image configuration.
|
||||
After changing this parameter you need to update your reference image and alignment markers!
|
||||
|
||||
Image Contrast (`-2` .. `2`)
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
# Parameter `Demo`
|
||||
Default Value: `false`
|
||||
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
|
||||
Enable to use demo images instead of the real camera images.
|
||||
Make sure to have a `/demo` folder on your SD-Card and make sure it contains the expected files!
|
||||
Check [here](../Demo-Mode) for details.
|
||||
|
||||
@@ -4,4 +4,10 @@ Default Value: `false`
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
|
||||
!!! Note
|
||||
This parameter can also be set on the Reference Image configuration page!
|
||||
|
||||
!!! Note
|
||||
After changing this parameter you need to update your reference image and alignment markers!
|
||||
|
||||
Fixes the illumination setting of camera at the startup and uses this later -> Individual round is faster.
|
||||
|
||||
13
param-docs/parameter-pages/TakeImage/Grayscale.md
Normal file
13
param-docs/parameter-pages/TakeImage/Grayscale.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# Parameter `Grayscale`
|
||||
Default Value: `false`
|
||||
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
|
||||
!!! Note
|
||||
This parameter can also be set on the Reference Image configuration page!
|
||||
|
||||
!!! Note
|
||||
After changing this parameter you need to update your reference image and alignment markers!
|
||||
|
||||
Produces black and white image.
|
||||
@@ -1,8 +1,10 @@
|
||||
# Parameter `LEDIntensity`
|
||||
Default Value: `50`
|
||||
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
This parameter can also be set on the Reference Image configuration.
|
||||
!!! Note
|
||||
This parameter can also be set on the Reference Image configuration page!
|
||||
|
||||
!!! Note
|
||||
After changing this parameter you need to update your reference image and alignment markers!
|
||||
|
||||
Set the Flash LED Intensity: (`0` .. `100`)
|
||||
|
||||
13
param-docs/parameter-pages/TakeImage/Negative.md
Normal file
13
param-docs/parameter-pages/TakeImage/Negative.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# Parameter `Negative`
|
||||
Default Value: `false`
|
||||
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
|
||||
!!! Note
|
||||
This parameter can also be set on the Reference Image configuration page!
|
||||
|
||||
!!! Note
|
||||
After changing this parameter you need to update your reference image and alignment markers!
|
||||
|
||||
Inverts the colors.
|
||||
@@ -1,11 +1,11 @@
|
||||
# Parameter `Saturation`
|
||||
Default Value: `0`
|
||||
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
!!! Note
|
||||
This parameter can also be set on the Reference Image configuration page!
|
||||
|
||||
!!! Note
|
||||
This parameter can also be set on the Reference Image configuration.
|
||||
After changing this parameter you need to update your reference image and alignment markers!
|
||||
|
||||
Image Saturation (`-2` .. `2`)
|
||||
|
||||
|
||||
15
param-docs/parameter-pages/TakeImage/Sharpness.md
Normal file
15
param-docs/parameter-pages/TakeImage/Sharpness.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Parameter `Sharpness`
|
||||
Default Value: `0`
|
||||
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
|
||||
!!! Note
|
||||
This parameter can also be set on the Reference Image configuration page!
|
||||
|
||||
!!! Note
|
||||
After changing this parameter you need to update your reference image and alignment markers!
|
||||
|
||||
Changes the sharpness of the image. Set to `-4` for auto-sharpness.
|
||||
|
||||
Range (`-4` .. `3`)
|
||||
13
param-docs/parameter-pages/TakeImage/Zoom.md
Normal file
13
param-docs/parameter-pages/TakeImage/Zoom.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# Parameter `Zoom`
|
||||
Default Value: `false`
|
||||
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
|
||||
!!! Note
|
||||
This parameter can also be set on the Reference Image configuration page!
|
||||
|
||||
!!! Note
|
||||
After changing this parameter you need to update your reference image and alignment markers!
|
||||
|
||||
Crop the camera sensor frame to `ImageSize` resolution instead of scaling it down.
|
||||
15
param-docs/parameter-pages/TakeImage/ZoomMode.md
Normal file
15
param-docs/parameter-pages/TakeImage/ZoomMode.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Parameter `ZoomMode`
|
||||
Default Value: `0`
|
||||
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
|
||||
!!! Note
|
||||
This parameter can also be set on the Reference Image configuration page!
|
||||
|
||||
!!! Note
|
||||
After changing this parameter you need to update your reference image and alignment markers!
|
||||
|
||||
`ZoomMode` only applies when `Zoom` is enabled.
|
||||
Value 0: Crop the camera sensor frame to `ImageSize` resolution.
|
||||
Value 1: Scale the camera sensor frame to 800 x 600 pixels then crop it to `ImageSize` resolution.
|
||||
14
param-docs/parameter-pages/TakeImage/ZoomOffsetX.md
Normal file
14
param-docs/parameter-pages/TakeImage/ZoomOffsetX.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# Parameter `ZoomOffsetX`
|
||||
Default Value: `0`
|
||||
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
|
||||
!!! Note
|
||||
This parameter can also be set on the Reference Image configuration page!
|
||||
|
||||
!!! Note
|
||||
After changing this parameter you need to update your reference image and alignment markers!
|
||||
|
||||
`ZoomOffsetX` only applies when `Zoom` is enabled.
|
||||
X coordinate of the crop location within the camera sensor frame.
|
||||
14
param-docs/parameter-pages/TakeImage/ZoomOffsetY.md
Normal file
14
param-docs/parameter-pages/TakeImage/ZoomOffsetY.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# Parameter `ZoomOffsetY`
|
||||
Default Value: `0`
|
||||
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
|
||||
!!! Note
|
||||
This parameter can also be set on the Reference Image configuration page!
|
||||
|
||||
!!! Note
|
||||
After changing this parameter you need to update your reference image and alignment markers!
|
||||
|
||||
`ZoomOffsetY` only applies when `Zoom` is enabled.
|
||||
Y coordinate of the crop location within the camera sensor frame.
|
||||
@@ -5,9 +5,18 @@ WaitBeforeTakingPicture = 5
|
||||
Brightness = 0
|
||||
Contrast = 0
|
||||
Saturation = 0
|
||||
Sharpness = 0
|
||||
LEDIntensity = 50
|
||||
ImageQuality = 12
|
||||
ImageSize = VGA
|
||||
Zoom = false
|
||||
ZoomMode = 0
|
||||
ZoomOffsetX = 0
|
||||
ZoomOffsetY = 0
|
||||
Grayscale = false
|
||||
Negative = false
|
||||
Aec2 = false
|
||||
AutoExposureLevel = 0
|
||||
FixedExposure = false
|
||||
Demo = false
|
||||
|
||||
|
||||
2
sd-card/html/.gitignore
vendored
2
sd-card/html/.gitignore
vendored
@@ -1 +1 @@
|
||||
edit_config_param.html
|
||||
edit_config.html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" xml:lang="en">
|
||||
<head>
|
||||
<title>Alignment marker</title>
|
||||
<title>Alignment markers</title>
|
||||
<meta charset="UTF-8" />
|
||||
|
||||
<style>
|
||||
@@ -86,16 +86,16 @@
|
||||
|
||||
<body style="font-family: arial; padding: 0px 10px;">
|
||||
<div id="overlay">
|
||||
<div id="overlaytext">Device is busy with digitalization round. Waiting until it completes...</div>
|
||||
<div id="overlaytext"></div>
|
||||
</div>
|
||||
|
||||
<h2>Alignment Marker</h2>
|
||||
<h2>Alignment Markers</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/Alignment/ target=_blank>Alignment</a>
|
||||
</summary>
|
||||
<p>
|
||||
Two alignment marker with clear contour and proper contrast are needed to identify unique "fix points" on the image.
|
||||
Two alignment markers with clear contour and proper contrast are needed to identify unique "fix points" on the image.
|
||||
The marker area should be not be part of the variable area of ROI evaluation. Please find more information in documenation:
|
||||
<a href=https://jomjol.github.io/AI-on-the-edge-device-docs/Alignment/ target=_blank>Alignment</a>
|
||||
</p>
|
||||
@@ -162,7 +162,7 @@
|
||||
<script type="text/javascript" src="readconfigparam.js?v=$COMMIT_HASH"></script>
|
||||
|
||||
<script language="JavaScript">
|
||||
var canvas = document.getElementById('canvas'),
|
||||
var canvas = document.getElementById('canvas'),
|
||||
ctx = canvas.getContext('2d'),
|
||||
imageObj = new Image(),
|
||||
rect = {},
|
||||
@@ -170,8 +170,9 @@
|
||||
aktindex = 0,
|
||||
refInfo,
|
||||
enhanceCon = false,
|
||||
param;
|
||||
domainname = getDomainname();
|
||||
domainname = getDomainname(),
|
||||
neueref1,
|
||||
neueref2,
|
||||
param;
|
||||
|
||||
function doReboot() {
|
||||
@@ -186,13 +187,38 @@ function doReboot() {
|
||||
|
||||
function ChangeSelection(){
|
||||
aktindex = parseInt(document.getElementById("index").value);
|
||||
|
||||
if (aktindex == 0 && neueref1 == 1) {
|
||||
UpdateReference();
|
||||
}
|
||||
else if (aktindex == 1 && neueref2 == 1) {
|
||||
UpdateReference();
|
||||
}
|
||||
else
|
||||
{
|
||||
LoadReference();
|
||||
}
|
||||
}
|
||||
|
||||
function SaveToConfig(){
|
||||
if (confirm("Are you sure you want to save the new alignment marker configuration?")) {
|
||||
WriteConfigININew();
|
||||
UpdateConfigReference(domainname)
|
||||
|
||||
if (neueref1 == 1 && neueref2 == 1) {
|
||||
UpdateConfigReferences(domainname);
|
||||
}
|
||||
|
||||
else if (neueref1 == 1) {
|
||||
var anzneueref = 1;
|
||||
UpdateConfigReference(anzneueref, domainname);
|
||||
}
|
||||
|
||||
else if (neueref2 == 1) {
|
||||
var anzneueref = 2;
|
||||
UpdateConfigReference(anzneueref, domainname);
|
||||
}
|
||||
|
||||
//UpdateConfigReference(domainname)
|
||||
SaveConfigToServer(domainname);
|
||||
document.getElementById("savemarker").disabled = true;
|
||||
document.getElementById("enhancecontrast").disabled = true;
|
||||
@@ -208,7 +234,7 @@ function EnhanceContrast(){
|
||||
refInfo[aktindex]["dx"] = document.getElementById("refdx").value;
|
||||
refInfo[aktindex]["dy"] = document.getElementById("refdy").value;
|
||||
|
||||
enhanceCon = true;
|
||||
var enhanceCon = true;
|
||||
|
||||
document.getElementById("overlay").style.display = "block";
|
||||
document.getElementById("overlaytext").innerHTML = "Enhancing Image Contrast...";
|
||||
@@ -219,11 +245,17 @@ function EnhanceContrast(){
|
||||
|
||||
async function task() {
|
||||
while (true) {
|
||||
var ret = MakeContrastImageZW(refInfo[aktindex], enhanceCon, domainname);
|
||||
var ret = MakeRefImageZW(refInfo[aktindex], enhanceCon, domainname);
|
||||
if (ret) {
|
||||
UpdateReference();
|
||||
//document.getElementById("enhancecontrast").disabled = true;
|
||||
document.getElementById("overlay").style.display = "none";
|
||||
if (aktindex == 0) {
|
||||
neueref1 = 1;
|
||||
}
|
||||
else if (aktindex == 1) {
|
||||
neueref2 = 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else {
|
||||
@@ -276,16 +308,20 @@ function UpdateReference(){
|
||||
}
|
||||
|
||||
function dataURLtoBlob(dataurl) {
|
||||
var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
|
||||
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
|
||||
var arr = dataurl.split(',');
|
||||
var mime = arr[0].match(/:(.*?);/)[1];
|
||||
var bstr = atob(arr[1]);
|
||||
var n = bstr.length;
|
||||
var u8arr = new Uint8Array(n);
|
||||
|
||||
while(n--){
|
||||
u8arr[n] = bstr.charCodeAt(n);
|
||||
}
|
||||
|
||||
return new Blob([u8arr], {type:mime});
|
||||
}
|
||||
|
||||
|
||||
function loadCanvas(dataURL) {
|
||||
function loadCanvas(dataURL) {
|
||||
var canvas = document.getElementById('canvas');
|
||||
var context = canvas.getContext('2d');
|
||||
|
||||
@@ -296,10 +332,9 @@ function dataURLtoBlob(dataurl) {
|
||||
};
|
||||
|
||||
imageObj.src = dataURL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function getCoords(elem) { // crossbrowser version
|
||||
function getCoords(elem) { // crossbrowser version
|
||||
var box = elem.getBoundingClientRect();
|
||||
var body = document.body;
|
||||
var docEl = document.documentElement;
|
||||
@@ -310,20 +345,46 @@ function dataURLtoBlob(dataurl) {
|
||||
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() {
|
||||
/* 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')
|
||||
if(hash == 'description') {
|
||||
document.getElementById("desc_details").open = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function LoadReference(){
|
||||
document.getElementById("img_ref").onload = function () {
|
||||
document.getElementById("refdx").value = this.width;
|
||||
document.getElementById("refdy").value = this.height;
|
||||
refInfo[aktindex]["dx"] = this.width;
|
||||
refInfo[aktindex]["dy"] = this.height;
|
||||
rect.w = document.getElementById("refdx").value;
|
||||
rect.h = document.getElementById("refdy").value;
|
||||
draw();
|
||||
}
|
||||
|
||||
function init() {
|
||||
_filenameurl = refInfo[aktindex]["name"];
|
||||
var url = domainname + "/fileserver" + _filenameurl + "?" + Date.now();
|
||||
document.getElementById("img_ref").src = url;
|
||||
|
||||
_filenameurl = _filenameurl.replace(".jpg", "_org.jpg");
|
||||
var url = domainname + "/fileserver" + _filenameurl + "?" + Date.now();
|
||||
document.getElementById("img_ref_org").src = url;
|
||||
|
||||
document.getElementById("name").value = refInfo[aktindex]["name"];
|
||||
document.getElementById("refx").value = refInfo[aktindex]["x"];
|
||||
document.getElementById("refy").value = refInfo[aktindex]["y"];
|
||||
rect.startX = document.getElementById("refx").value;
|
||||
rect.startY = document.getElementById("refy").value;
|
||||
draw();
|
||||
}
|
||||
|
||||
function init() {
|
||||
openDescription();
|
||||
domainname = getDomainname();
|
||||
loadConfig(domainname);
|
||||
@@ -338,32 +399,32 @@ function dataURLtoBlob(dataurl) {
|
||||
canvas.addEventListener('mousemove', mouseMove, false);
|
||||
loadCanvas(domainname + "/fileserver/config/reference.jpg");
|
||||
|
||||
CopyReferenceToImgTmp(domainname);
|
||||
//CopyReferenceToImgTmp(domainname);
|
||||
refInfo = GetReferencesInfo();
|
||||
|
||||
UpdateReference();
|
||||
|
||||
//UpdateReference();
|
||||
LoadReference();
|
||||
drawImage();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function drawImage(){
|
||||
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();
|
||||
}
|
||||
// context.restore();
|
||||
}
|
||||
|
||||
|
||||
function CutOutReference(){
|
||||
function CutOutReference(){
|
||||
refInfo[aktindex]["x"] = document.getElementById("refx").value;
|
||||
refInfo[aktindex]["y"] = document.getElementById("refy").value;
|
||||
refInfo[aktindex]["dx"] = document.getElementById("refdx").value;
|
||||
refInfo[aktindex]["dy"] = document.getElementById("refdy").value;
|
||||
|
||||
var enhanceCon = false;
|
||||
|
||||
document.getElementById("overlay").style.display = "block";
|
||||
document.getElementById("overlaytext").innerHTML = "Updating marker...";
|
||||
|
||||
@@ -373,12 +434,20 @@ function dataURLtoBlob(dataurl) {
|
||||
|
||||
async function task() {
|
||||
while (true) {
|
||||
var ret = MakeRefZW(refInfo[aktindex], domainname);
|
||||
var ret = MakeRefImageZW(refInfo[aktindex], enhanceCon, domainname);
|
||||
|
||||
if (ret) {
|
||||
UpdateReference();
|
||||
document.getElementById("enhancecontrast").disabled = false;
|
||||
document.getElementById("savemarker").disabled = false;
|
||||
document.getElementById("overlay").style.display = "none";
|
||||
|
||||
if (aktindex == 0) {
|
||||
neueref1 = 1;
|
||||
}
|
||||
else if (aktindex == 1) {
|
||||
neueref2 = 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else {
|
||||
@@ -400,18 +469,17 @@ function dataURLtoBlob(dataurl) {
|
||||
setTimeout(function() { // Delay so the overlay gets shown
|
||||
task();
|
||||
}, 1);
|
||||
}
|
||||
}
|
||||
|
||||
function drawGrid(){
|
||||
function drawGrid(){
|
||||
var canvas = document.getElementById('canvas');
|
||||
var ctx = canvas.getContext('2d');
|
||||
w = canvas.width;
|
||||
h = canvas.height;
|
||||
var w = canvas.width;
|
||||
var h = canvas.height;
|
||||
ctx.save();
|
||||
ctx.strokeStyle = '#00FF00';
|
||||
|
||||
for (i = h/2; i < h; i += 100)
|
||||
{
|
||||
for (i = h/2; i < h; i += 100) {
|
||||
ctx.moveTo(0, i);
|
||||
ctx.lineTo(w, i);
|
||||
ctx.stroke();
|
||||
@@ -419,23 +487,23 @@ function dataURLtoBlob(dataurl) {
|
||||
ctx.lineTo(w, h-i);
|
||||
ctx.stroke();
|
||||
}
|
||||
for (i = w/2; i < w; i += 100)
|
||||
{
|
||||
|
||||
for (i = w/2; i < w; i += 100) {
|
||||
ctx.moveTo(i, 0);
|
||||
ctx.lineTo(i, h);
|
||||
ctx.stroke();
|
||||
ctx.moveTo(w-i, 0);
|
||||
ctx.lineTo(w-i, h);
|
||||
ctx.stroke(); }
|
||||
// ctx.restore();
|
||||
ctx.stroke();
|
||||
}
|
||||
// ctx.restore();
|
||||
}
|
||||
|
||||
|
||||
function draw() {
|
||||
function draw() {
|
||||
var canvas = document.getElementById('canvas');
|
||||
var context = canvas.getContext('2d');
|
||||
context.drawImage(imageObj, 0, 0);
|
||||
lw = 4
|
||||
var lw = 4
|
||||
context.lineWidth = lw;
|
||||
context.strokeStyle = "#FF0000";
|
||||
var x0 = parseInt(rect.startX) - parseInt(lw/2);
|
||||
@@ -443,49 +511,39 @@ function dataURLtoBlob(dataurl) {
|
||||
var dx = parseInt(rect.w) + parseInt(lw);
|
||||
var dy = parseInt(rect.h) + parseInt(lw);
|
||||
context.strokeRect(x0, y0, dx, dy);
|
||||
}
|
||||
|
||||
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) };
|
||||
}
|
||||
|
||||
function mouseDown(e) {
|
||||
zw = getCoords(this)
|
||||
function mouseDown(e) {
|
||||
var 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() {
|
||||
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) {
|
||||
function mouseMove(e) {
|
||||
if (drag) {
|
||||
zw = getCoords(this)
|
||||
var zw = getCoords(this)
|
||||
rect.w = (e.pageX - zw.left) - rect.startX;
|
||||
rect.h = (e.pageY - zw.top) - rect.startY ;
|
||||
document.getElementById("refdx").value = rect.w;
|
||||
@@ -497,9 +555,9 @@ function dataURLtoBlob(dataurl) {
|
||||
var canvas = document.getElementById('canvas');
|
||||
var context = canvas.getContext('2d');
|
||||
|
||||
zw = getCoords(this);
|
||||
x = e.pageX - zw.left;
|
||||
y = e.pageY - zw.top;
|
||||
var zw = getCoords(this);
|
||||
var x = e.pageX - zw.left;
|
||||
var y = e.pageY - zw.top;
|
||||
|
||||
context.lineWidth = 2;
|
||||
context.strokeStyle = "#00FF00";
|
||||
@@ -510,15 +568,14 @@ function dataURLtoBlob(dataurl) {
|
||||
context.lineTo(x, canvas.height);
|
||||
context.stroke();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function namechanged()
|
||||
{
|
||||
function namechanged() {
|
||||
_name = document.getElementById("name").value;
|
||||
refInfo[aktindex]["name"] = _name;
|
||||
}
|
||||
}
|
||||
|
||||
function valuemanualchanged(){
|
||||
function valuemanualchanged(){
|
||||
if (!drag) {
|
||||
rect.w = document.getElementById("refdx").value;
|
||||
rect.h = document.getElementById("refdy").value;
|
||||
@@ -526,10 +583,9 @@ function dataURLtoBlob(dataurl) {
|
||||
rect.startY = document.getElementById("refy").value;
|
||||
draw();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
init();
|
||||
init();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -186,20 +186,25 @@
|
||||
<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>
|
||||
<td><input type="checkbox" id="lockAspectRatio" name="lockAspectRatio" value="1" onclick="changelockAspectRatio()" checked tabindex=6><label for="lockAspectRatio"> Lock aspect ratio </label></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>
|
||||
<td><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></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"></td>
|
||||
<td><input type="checkbox" id="CCW" name="CCW" value="0" onclick="changeCCW()" unchecked tabindex=8><label for="CCW">Counter clockwise rotation (CCW)</label></td>
|
||||
<td colspan="3"><input type="checkbox" id="CCW" name="CCW" value="0" onclick="changeCCW()" unchecked tabindex=8><label for="CCW">Counter clockwise rotation (CCW)</label></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=9><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>
|
||||
|
||||
<hr>
|
||||
|
||||
<table>
|
||||
<colgroup>
|
||||
<col span="1" style="width: 22%;">
|
||||
@@ -248,18 +253,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
function EnDisableAnalog() {
|
||||
function EnDisableAnalog() {
|
||||
isEnabled = document.getElementById("Category_Analog_enabled").checked;
|
||||
|
||||
$("#div2").attr("disabled", "disabled").off('click');
|
||||
var x1=$("#div2").hasClass("disabledDiv");
|
||||
|
||||
if (isEnabled)
|
||||
{
|
||||
if (isEnabled) {
|
||||
$("#div2").removeClass("disabledDiv");
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
$("#div2").addClass("disabledDiv");
|
||||
}
|
||||
|
||||
@@ -268,16 +271,16 @@ function EnDisableAnalog() {
|
||||
cofcat["Analog"]["enabled"] = isEnabled;
|
||||
document.getElementById("saveroi").disabled = false;
|
||||
|
||||
if (isEnabled)
|
||||
{
|
||||
if (isEnabled) {
|
||||
UpdateROIs();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function sah1(el, _target) {
|
||||
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);
|
||||
@@ -285,25 +288,27 @@ function sah1(el, _target) {
|
||||
}
|
||||
}
|
||||
|
||||
function onNameChange(){
|
||||
function onNameChange() {
|
||||
ROIInfo[aktindex]["name"] = document.getElementById("name").value;
|
||||
UpdateROIs();
|
||||
}
|
||||
}
|
||||
|
||||
function deleteROI(){
|
||||
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() {
|
||||
function newROI() {
|
||||
var sel = document.getElementById("Numbers_value1");
|
||||
var _number= sel.options[sel.selectedIndex].text;
|
||||
sel = document.getElementById("index");
|
||||
@@ -321,65 +326,70 @@ function newROI() {
|
||||
return; //break out of the function early because prompt was aborted
|
||||
}
|
||||
|
||||
if (ROIInfo.length > 0)
|
||||
if (ROIInfo.length > 0) {
|
||||
erg = CreateROI(_number, "analog", sel.selectedIndex, _roinew, 15, 30, ROIInfo[aktindex]["dx"], ROIInfo[aktindex]["dy"], ROIInfo[aktindex]["CCW"]=="true");
|
||||
else
|
||||
}
|
||||
else {
|
||||
erg = CreateROI(_number, "analog", sel.selectedIndex, _roinew, 15, 30, 30, 30, false);
|
||||
}
|
||||
|
||||
if (erg != "")
|
||||
if (erg != "") {
|
||||
firework.launch(erg, 'danger', 30000);
|
||||
else
|
||||
}
|
||||
else {
|
||||
UpdateROIs(_roinew);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function movePrevious(){
|
||||
function movePrevious() {
|
||||
var zw = ROIInfo[aktindex];
|
||||
ROIInfo[aktindex] = ROIInfo[aktindex-1];
|
||||
ROIInfo[aktindex-1] = zw;
|
||||
aktindex--;
|
||||
UpdateROIs();
|
||||
}
|
||||
}
|
||||
|
||||
function moveNext(){
|
||||
function moveNext() {
|
||||
var zw = ROIInfo[aktindex];
|
||||
ROIInfo[aktindex] = ROIInfo[aktindex+1];
|
||||
ROIInfo[aktindex+1] = zw;
|
||||
aktindex++;
|
||||
UpdateROIs();
|
||||
}
|
||||
}
|
||||
|
||||
function changelockAspectRatio(){
|
||||
function changelockAspectRatio() {
|
||||
lockAspectRatio = document.getElementById("lockAspectRatio").checked;
|
||||
}
|
||||
}
|
||||
|
||||
function changelockSizes(){
|
||||
function changelockSizes() {
|
||||
lockSizes = document.getElementById("lockSizes").checked;
|
||||
UpdateROIs();
|
||||
}
|
||||
}
|
||||
|
||||
function changeCCW(){
|
||||
function changeCCW() {
|
||||
var sel = document.getElementById("Numbers_value1");
|
||||
var _number = sel.options[sel.selectedIndex].text;
|
||||
|
||||
ROIInfo = getROIInfo("analog", _number);
|
||||
aktindex = parseInt(document.getElementById("index").value);
|
||||
|
||||
if (document.getElementById("CCW").checked)
|
||||
if (document.getElementById("CCW").checked) {
|
||||
ROIInfo[aktindex]["CCW"] = "true";
|
||||
else
|
||||
}
|
||||
else {
|
||||
ROIInfo[aktindex]["CCW"] = "false";
|
||||
}
|
||||
|
||||
UpdateROIs();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function ChangeSelection(){
|
||||
function ChangeSelection() {
|
||||
aktindex = parseInt(document.getElementById("index").value);
|
||||
// lockAspectRatio = true;
|
||||
// lockAspectRatio = true;
|
||||
UpdateROIs();
|
||||
}
|
||||
}
|
||||
|
||||
function SaveToConfig(){
|
||||
function SaveToConfig() {
|
||||
if (confirm("Are you sure you want to save the new analog ROI configuration?")) {
|
||||
//_zwcat = getConfigCategory();
|
||||
cofcat["Analog"]["enabled"] = document.getElementById("Category_Analog_enabled").checked;
|
||||
@@ -390,11 +400,9 @@ function SaveToConfig(){
|
||||
|
||||
firework.launch('Configuration saved. It will get applied after next reboot', 'success', 5000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function ShowMultiplier()
|
||||
{
|
||||
function ShowMultiplier() {
|
||||
var decimalShift = 0;
|
||||
var multiplier;
|
||||
var multiplier_decshift;
|
||||
@@ -406,6 +414,7 @@ function ShowMultiplier()
|
||||
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"]) {
|
||||
@@ -419,11 +428,13 @@ function ShowMultiplier()
|
||||
multiplier = fixedDecimals = aktindex + 1;
|
||||
multiplier_decshift = fixedDecimals_decshift = multiplier - Number(decimalShift);
|
||||
|
||||
if (multiplier < 0)
|
||||
if (multiplier < 0) {
|
||||
fixedDecimals = 0;
|
||||
}
|
||||
|
||||
if (multiplier_decshift < 0)
|
||||
if (multiplier_decshift < 0) {
|
||||
fixedDecimals_decshift = 0;
|
||||
}
|
||||
|
||||
document.getElementById("multiplier").value="x" + Number(10 ** (-1*multiplier)).toFixed(fixedDecimals);
|
||||
document.getElementById("multiplier_decshift").value="x" + Number(10 ** (-1*multiplier_decshift)).toFixed(fixedDecimals_decshift);
|
||||
@@ -432,8 +443,9 @@ function ShowMultiplier()
|
||||
multiplier = ROIInfo.length - 1 - aktindex;
|
||||
multiplier_decshift = fixedDecimals_decshift = multiplier + Number(decimalShift);
|
||||
|
||||
if (multiplier_decshift > 0)
|
||||
if (multiplier_decshift > 0) {
|
||||
fixedDecimals_decshift = 0;
|
||||
}
|
||||
|
||||
if (fixedDecimals_decshift < 0) {
|
||||
fixedDecimals_decshift = -1 * fixedDecimals_decshift;
|
||||
@@ -442,19 +454,18 @@ function ShowMultiplier()
|
||||
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){
|
||||
function UpdateROIs(_sel){
|
||||
document.getElementById("Category_Analog_enabled").checked = true;
|
||||
var sel = document.getElementById("Numbers_value1");
|
||||
var _number = sel.options[sel.selectedIndex].text;
|
||||
|
||||
ROIInfo = getROIInfo("analog", _number);
|
||||
// _catzw = getConfigCategory();
|
||||
// _catzw = getConfigCategory();
|
||||
|
||||
if (cofcat["Analog"]["enabled"] == false)
|
||||
{
|
||||
if (cofcat["Analog"]["enabled"] == false) {
|
||||
document.getElementById("Category_Analog_enabled").checked = false;
|
||||
EnDisableAnalog();
|
||||
firework.launch('Analog ROI processing is disabled. Activate with checkbox if needed', 'warning', 10000);
|
||||
@@ -474,6 +485,7 @@ function UpdateROIs(_sel){
|
||||
document.getElementById("refy").disabled = true;
|
||||
document.getElementById("refdy").disabled = true;
|
||||
document.getElementById("lockSizes").disabled = true;
|
||||
document.getElementById("showall").disabled = true;
|
||||
document.getElementById("lockAspectRatio").disabled = true;
|
||||
document.getElementById("CCW").disabled = true;
|
||||
document.getElementById("moveNext").disabled = true;
|
||||
@@ -481,8 +493,7 @@ function UpdateROIs(_sel){
|
||||
document.getElementById("saveroi").disabled = false;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
document.getElementById("newROI").disabled = false;
|
||||
document.getElementById("deleteROI").disabled = false;
|
||||
document.getElementById("renameROI").disabled = false;
|
||||
@@ -494,6 +505,7 @@ function UpdateROIs(_sel){
|
||||
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("CCW").disabled = false;
|
||||
document.getElementById("saveroi").disabled = false;
|
||||
@@ -504,8 +516,9 @@ function UpdateROIs(_sel){
|
||||
_index.remove(0);
|
||||
}
|
||||
|
||||
if (aktindex > ROIInfo.length)
|
||||
if (aktindex > ROIInfo.length) {
|
||||
aktindex = ROIInfo.length-1;
|
||||
}
|
||||
|
||||
for (var i = 0; i < ROIInfo.length; ++i){
|
||||
var option = document.createElement("option");
|
||||
@@ -513,12 +526,13 @@ function UpdateROIs(_sel){
|
||||
option.value = i;
|
||||
_index.add(option);
|
||||
if (typeof _sel !== 'undefined') {
|
||||
if (option.text == _sel)
|
||||
if (option.text == _sel) {
|
||||
aktindex = i;
|
||||
}
|
||||
}
|
||||
_index.selectedIndex = aktindex;
|
||||
}
|
||||
|
||||
_index.selectedIndex = aktindex;
|
||||
|
||||
document.getElementById("movePrevious").disabled = false;
|
||||
if (aktindex == 0){
|
||||
@@ -546,7 +560,7 @@ function UpdateROIs(_sel){
|
||||
rect.w = ROIInfo[aktindex]["dx"];
|
||||
rect.h = ROIInfo[aktindex]["dy"];
|
||||
draw();
|
||||
}
|
||||
}
|
||||
|
||||
function loadCanvas(dataURL) {
|
||||
var canvas = document.getElementById('canvas');
|
||||
@@ -562,8 +576,8 @@ function UpdateROIs(_sel){
|
||||
imageObj.src = dataURL;
|
||||
}
|
||||
|
||||
|
||||
function getCoords(elem) { // crossbrowser version
|
||||
function getCoords(elem) {
|
||||
// crossbrowser version
|
||||
var box = elem.getBoundingClientRect();
|
||||
var body = document.body;
|
||||
var docEl = document.documentElement;
|
||||
@@ -576,16 +590,15 @@ function UpdateROIs(_sel){
|
||||
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')
|
||||
if(hash == 'description') {
|
||||
document.getElementById("desc_details").open = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function init() {
|
||||
openDescription();
|
||||
@@ -604,8 +617,7 @@ function UpdateROIs(_sel){
|
||||
var all_dx_dy_Identical = true;
|
||||
if (ROIInfo.length > 1) {
|
||||
for (var i = 1; i < (ROIInfo.length); ++i) { // 2nd .. last ROI
|
||||
if (parseInt(ROIInfo[i].dx) != parseInt(ROIInfo[0].dx) ||
|
||||
parseInt(ROIInfo[i].dy) != parseInt(ROIInfo[0].dy)) {
|
||||
if (parseInt(ROIInfo[i].dx) != parseInt(ROIInfo[0].dx) || parseInt(ROIInfo[i].dy) != parseInt(ROIInfo[0].dy)) {
|
||||
all_dx_dy_Identical = false;
|
||||
break;
|
||||
}
|
||||
@@ -634,12 +646,11 @@ function UpdateROIs(_sel){
|
||||
context.clearRect(0,0,imageObj.width,imageObj.height);
|
||||
context.save();
|
||||
context.drawImage(imageObj, 0, 0);
|
||||
// context.restore();
|
||||
// context.restore();
|
||||
}
|
||||
|
||||
function UpdateNUMBERS(_sel){
|
||||
function UpdateNUMBERS(_sel) {
|
||||
zw = getNUMBERInfo();
|
||||
|
||||
index = 0;
|
||||
|
||||
var _index = document.getElementById("Numbers_value1");
|
||||
@@ -654,16 +665,17 @@ function UpdateNUMBERS(_sel){
|
||||
_index.add(option);
|
||||
|
||||
if (typeof _sel !== 'undefined') {
|
||||
if (zw[i]["name"] == _sel)
|
||||
index = i
|
||||
if (zw[i]["name"] == _sel) {
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
_index.selectedIndex = index;
|
||||
|
||||
UpdateROIs();
|
||||
}
|
||||
}
|
||||
|
||||
function renameNumber(){
|
||||
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);
|
||||
@@ -672,42 +684,46 @@ function renameNumber(){
|
||||
}
|
||||
|
||||
erg = RenameNUMBER(_delete, _numbernew);
|
||||
if (erg != "")
|
||||
firework.launch(erg, 'danger', 30000);
|
||||
else
|
||||
UpdateNUMBERS(_numbernew);
|
||||
}
|
||||
|
||||
function newNumber(){
|
||||
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 != "")
|
||||
|
||||
if (erg != "") {
|
||||
firework.launch(erg, 'danger', 30000);
|
||||
else
|
||||
}
|
||||
else {
|
||||
UpdateNUMBERS(_numbernew);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function removeNumber(){
|
||||
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?"))
|
||||
{
|
||||
"Do you really want to proceed?")) {
|
||||
var sel = document.getElementById("Numbers_value1");
|
||||
var _delete= sel.options[sel.selectedIndex].text;
|
||||
erg = DeleteNUMBER(_delete);
|
||||
if (erg != "")
|
||||
if (erg != "") {
|
||||
firework.launch(erg, 'danger', 30000);
|
||||
}
|
||||
UpdateNUMBERS();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function drawTextBG(context, txt, x, y, padding) {
|
||||
function drawTextBG(context, txt, x, y, padding) {
|
||||
context.font = "15px Arial";
|
||||
context.textAlign = "center";
|
||||
|
||||
@@ -717,10 +733,11 @@ function drawTextBG(context, txt, x, y, 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
|
||||
if (typeof ROIInfo === 'undefined') {
|
||||
// During init, ROIInfo is not defined yet
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -736,27 +753,23 @@ function drawTextBG(context, txt, x, y, padding) {
|
||||
context.fillStyle = "red";
|
||||
context.textAlign = "center";
|
||||
|
||||
if (document.getElementById("Category_Analog_enabled").checked)
|
||||
{
|
||||
if (document.getElementById("Category_Analog_enabled").checked) {
|
||||
var sel = document.getElementById("index");
|
||||
var _number = sel.selectedIndex;
|
||||
|
||||
if (lockSizes) {
|
||||
// Synchronize dx and dy
|
||||
for (var _nb = 0; _nb < ROIInfo.length; _nb++)
|
||||
{
|
||||
if (_nb != _number)
|
||||
{
|
||||
for (var _nb = 0; _nb < ROIInfo.length; _nb++) {
|
||||
if (_nb != _number) {
|
||||
ROIInfo[_nb].dy = rect.h;
|
||||
ROIInfo[_nb].dx = rect.w;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var _nb = 0; _nb < ROIInfo.length; _nb++)
|
||||
{
|
||||
if (_nb != _number)
|
||||
{
|
||||
if (document.getElementById("showall").checked) {
|
||||
for (var _nb = 0; _nb < ROIInfo.length; _nb++) {
|
||||
if (_nb != _number) {
|
||||
lw = 2;
|
||||
context.lineWidth = lw;
|
||||
context.strokeStyle = "#990000";
|
||||
@@ -766,10 +779,12 @@ function drawTextBG(context, txt, x, y, padding) {
|
||||
var dy = parseInt(ROIInfo[_nb].dy) + parseInt(lw);
|
||||
context.strokeRect(x0, y0, dx, dy);
|
||||
|
||||
if (ROIInfo[_nb]["CCW"] != "true")
|
||||
if (ROIInfo[_nb]["CCW"] != "true") {
|
||||
drawTextBG(context, ROIInfo[_nb]["name"], x0+dx/2-0.5, y0-13, 5);
|
||||
else
|
||||
}
|
||||
else {
|
||||
drawTextBG(context, ROIInfo[_nb]["name"]+" (CCW)", x0+dx/2-0.5, y0-13, 5);
|
||||
}
|
||||
|
||||
lw = 1;
|
||||
var x0 = parseInt(ROIInfo[_nb].x) - parseInt(lw/2);
|
||||
@@ -779,7 +794,7 @@ function drawTextBG(context, txt, x, y, padding) {
|
||||
context.strokeRect(x0, y0, dx, dy);
|
||||
context.lineWidth = lw;
|
||||
context.beginPath();
|
||||
// context.arc (x0+dx/2, y0+dy/2, dx/2, 0, 2 * Math.PI);
|
||||
// context.arc (x0+dx/2, y0+dy/2, dx/2, 0, 2 * Math.PI);
|
||||
context.ellipse(x0+dx/2, y0+dy/2, dx/2, dy/2, 0, 0, 2 * Math.PI);
|
||||
context.moveTo(x0+dx/2, y0);
|
||||
context.lineTo(x0+dx/2, y0+dy);
|
||||
@@ -788,6 +803,7 @@ function drawTextBG(context, txt, x, y, padding) {
|
||||
context.stroke();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lw = 4
|
||||
context.lineWidth = lw;
|
||||
@@ -798,14 +814,16 @@ function drawTextBG(context, txt, x, y, padding) {
|
||||
var dy = parseInt(rect.h) + parseInt(lw);
|
||||
context.strokeRect(x0, y0, dx, dy);
|
||||
|
||||
if (ROIInfo[aktindex]["CCW"] != "true")
|
||||
if (ROIInfo[aktindex]["CCW"] != "true") {
|
||||
drawTextBG(context, ROIInfo[aktindex]["name"], x0+dx/2, y0-11, 5);
|
||||
else
|
||||
}
|
||||
else {
|
||||
drawTextBG(context, ROIInfo[aktindex]["name"] + " (CCW)", x0+dx/2, y0-11, 5);
|
||||
}
|
||||
|
||||
context.lineWidth = 1;
|
||||
context.beginPath();
|
||||
// context.arc(x0+dx/2, y0+dy/2, dx/2, 0, 2 * Math.PI);
|
||||
// context.arc(x0+dx/2, y0+dy/2, dx/2, 0, 2 * Math.PI);
|
||||
context.ellipse(x0+dx/2, y0+dy/2, dx/2, dy/2, 0, 0, 2 * Math.PI);
|
||||
context.moveTo(x0+dx/2, y0);
|
||||
context.lineTo(x0+dx/2, y0+dy);
|
||||
@@ -819,7 +837,6 @@ function drawTextBG(context, txt, x, y, padding) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function mouseDown(e) {
|
||||
zw = getCoords(this)
|
||||
rect.startX = e.pageX - zw.left;
|
||||
@@ -849,10 +866,10 @@ function drawTextBG(context, txt, x, y, padding) {
|
||||
if (drag) {
|
||||
zw = getCoords(this)
|
||||
|
||||
|
||||
if (lockAspectRatio) {
|
||||
rect.h = (e.pageY - zw.top) - rect.startY;
|
||||
rect.w = Math.round(rect.h * ROIInfo[aktindex]["ar"]); }
|
||||
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;
|
||||
@@ -881,7 +898,7 @@ function drawTextBG(context, txt, x, y, padding) {
|
||||
}
|
||||
}
|
||||
|
||||
function valuemanualchanged(){
|
||||
function valuemanualchanged() {
|
||||
if (!drag) {
|
||||
rect.w = document.getElementById("refdx").value;
|
||||
rect.h = document.getElementById("refdy").value;
|
||||
@@ -897,7 +914,7 @@ function drawTextBG(context, txt, x, y, padding) {
|
||||
document.getElementById("saveroi").disabled = false;
|
||||
}
|
||||
|
||||
function valuemanualchangeddx(){
|
||||
function valuemanualchangeddx() {
|
||||
if (!drag) {
|
||||
rect.w = document.getElementById("refdx").value;
|
||||
rect.h = document.getElementById("refdy").value;
|
||||
@@ -913,8 +930,7 @@ function drawTextBG(context, txt, x, y, padding) {
|
||||
document.getElementById("saveroi").disabled = false;
|
||||
}
|
||||
|
||||
|
||||
function renameROI(){
|
||||
function renameROI() {
|
||||
var sel = document.getElementById("Numbers_value1");
|
||||
var _number= sel.options[sel.selectedIndex].text;
|
||||
sel = document.getElementById("index");
|
||||
@@ -926,23 +942,21 @@ function drawTextBG(context, txt, x, y, padding) {
|
||||
}
|
||||
|
||||
erg = RenameROI(_number, "analog", _roialt, _roinew);
|
||||
if (erg != "")
|
||||
if (erg != "") {
|
||||
firework.launch(erg, 'danger', 30000);
|
||||
else
|
||||
}
|
||||
else {
|
||||
UpdateROIs(_roinew);
|
||||
}
|
||||
}
|
||||
|
||||
function numberChanged()
|
||||
{
|
||||
function numberChanged() {
|
||||
aktindex = 0;
|
||||
UpdateROIs();
|
||||
}
|
||||
|
||||
|
||||
|
||||
init();
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -11,7 +11,7 @@
|
||||
p {font-size: 1em;}
|
||||
|
||||
input[type=number] {
|
||||
width: 60px;
|
||||
width: 40px;
|
||||
margin-right: 10px;
|
||||
padding: 3px 5px;
|
||||
display: inline-block;
|
||||
@@ -176,22 +176,24 @@
|
||||
<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>
|
||||
<td><input type="checkbox" id="lockAspectRatio" name="lockAspectRatio" value="1" onclick="changelockAspectRatio()" checked tabindex=6><label for="lockAspectRatio"> Lock aspect ratio </label></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>
|
||||
<td><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></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"></td>
|
||||
<td><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" step=1 onchange="valuemanualchangedspace()" tabindex=9> between all ROIs</label>
|
||||
</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%;">
|
||||
@@ -201,7 +203,7 @@
|
||||
</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=10></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>
|
||||
@@ -241,18 +243,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
function EnDisableDigits() {
|
||||
function EnDisableDigits() {
|
||||
isEnabled = document.getElementById("Category_Digits_enabled").checked;
|
||||
|
||||
$("#div2").attr("disabled", "disabled").off('click');
|
||||
var x1=$("#div2").hasClass("disabledDiv");
|
||||
|
||||
if (isEnabled)
|
||||
{
|
||||
if (isEnabled) {
|
||||
$("#div2").removeClass("disabledDiv");
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
$("#div2").addClass("disabledDiv");
|
||||
}
|
||||
|
||||
@@ -261,16 +261,16 @@ function EnDisableDigits() {
|
||||
cofcat["Digits"]["enabled"] = isEnabled;
|
||||
document.getElementById("saveroi").disabled = false;
|
||||
|
||||
if (isEnabled)
|
||||
{
|
||||
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);
|
||||
@@ -278,26 +278,26 @@ function EnDisableDigits() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function onNameChange(){
|
||||
function onNameChange() {
|
||||
ROIInfo[aktindex]["name"] = document.getElementById("name").value;
|
||||
UpdateROIs();
|
||||
}
|
||||
}
|
||||
|
||||
function deleteROI(){
|
||||
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() {
|
||||
function newROI() {
|
||||
var sel = document.getElementById("Numbers_value1");
|
||||
var _number= sel.options[sel.selectedIndex].text;
|
||||
sel = document.getElementById("index");
|
||||
@@ -322,11 +322,13 @@ function newROI() {
|
||||
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
|
||||
else {
|
||||
erg = CreateROI(_number, "digit", sel.selectedIndex, _roinew, 15, 30, 30, 51, 0);
|
||||
}
|
||||
|
||||
if (erg != "")
|
||||
if (erg != "") {
|
||||
firework.launch(erg, 'danger', 30000);
|
||||
}
|
||||
else {
|
||||
UpdateROIs(_roinew);
|
||||
// Shift all ROIs on right side to the right
|
||||
@@ -335,31 +337,31 @@ function newROI() {
|
||||
}
|
||||
draw();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function movePrevious(){
|
||||
function movePrevious() {
|
||||
var zw = ROIInfo[aktindex];
|
||||
ROIInfo[aktindex] = ROIInfo[aktindex-1];
|
||||
ROIInfo[aktindex-1] = zw;
|
||||
aktindex--;
|
||||
UpdateROIs();
|
||||
valuemanualchanged();
|
||||
}
|
||||
}
|
||||
|
||||
function moveNext(){
|
||||
function moveNext() {
|
||||
var zw = ROIInfo[aktindex];
|
||||
ROIInfo[aktindex] = ROIInfo[aktindex+1];
|
||||
ROIInfo[aktindex+1] = zw;
|
||||
aktindex++;
|
||||
UpdateROIs();
|
||||
valuemanualchanged();
|
||||
}
|
||||
}
|
||||
|
||||
function changelockAspectRatio(){
|
||||
function changelockAspectRatio() {
|
||||
lockAspectRatio = document.getElementById("lockAspectRatio").checked;
|
||||
}
|
||||
}
|
||||
|
||||
function changelockSizes(){
|
||||
function changelockSizes() {
|
||||
lockSizes = document.getElementById("lockSizes").checked;
|
||||
UpdateROIs();
|
||||
valuemanualchangedspace();
|
||||
@@ -367,9 +369,9 @@ function changelockSizes(){
|
||||
if (!lockSizes) {
|
||||
firework.launch("In most cases it's advised to keep the y, Δx and Δy identical!", 'warning', 10000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function changeLockSpaceEquidistant(){
|
||||
function changeLockSpaceEquidistant() {
|
||||
lockSpaceEquidistant = document.getElementById("lockSpaceEquidistant").checked;
|
||||
if (!lockSpaceEquidistant) {
|
||||
document.getElementById("space").disabled = true;
|
||||
@@ -378,15 +380,15 @@ function changeLockSpaceEquidistant(){
|
||||
document.getElementById("space").disabled = false;
|
||||
}
|
||||
UpdateROIs();
|
||||
}
|
||||
}
|
||||
|
||||
function ChangeSelection(){
|
||||
function ChangeSelection() {
|
||||
aktindex = parseInt(document.getElementById("index").value);
|
||||
// lockAspectRatio = true;
|
||||
//lockAspectRatio = true;
|
||||
UpdateROIs();
|
||||
}
|
||||
}
|
||||
|
||||
function SaveToConfig(){
|
||||
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;
|
||||
@@ -397,11 +399,9 @@ function SaveToConfig(){
|
||||
|
||||
firework.launch('Configuration saved. It will get applied after next reboot', 'success', 5000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function ShowMultiplier()
|
||||
{
|
||||
function ShowMultiplier() {
|
||||
var decimalShift = 0;
|
||||
var multiplier;
|
||||
var multiplier_decshift;
|
||||
@@ -411,6 +411,7 @@ function ShowMultiplier()
|
||||
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"]) {
|
||||
@@ -423,8 +424,9 @@ function ShowMultiplier()
|
||||
multiplier = ROIInfo.length - 1 - aktindex;
|
||||
multiplier_decshift = fixedDecimals_decshift = multiplier + Number(decimalShift);
|
||||
|
||||
if (multiplier_decshift > 0)
|
||||
if (multiplier_decshift > 0) {
|
||||
fixedDecimals_decshift = 0;
|
||||
}
|
||||
|
||||
if (fixedDecimals_decshift < 0) {
|
||||
fixedDecimals_decshift = -1*fixedDecimals_decshift;
|
||||
@@ -432,19 +434,17 @@ function ShowMultiplier()
|
||||
|
||||
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){
|
||||
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();
|
||||
// _catzw = getConfigCategory();
|
||||
|
||||
if (cofcat["Digits"]["enabled"] == false)
|
||||
{
|
||||
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);
|
||||
@@ -465,14 +465,14 @@ function UpdateROIs(_sel){
|
||||
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
|
||||
{
|
||||
else {
|
||||
document.getElementById("newROI").disabled = false;
|
||||
document.getElementById("deleteROI").disabled = false;
|
||||
document.getElementById("renameROI").disabled = false;
|
||||
@@ -484,6 +484,7 @@ function UpdateROIs(_sel){
|
||||
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;
|
||||
@@ -494,21 +495,24 @@ function UpdateROIs(_sel){
|
||||
_index.remove(0);
|
||||
}
|
||||
|
||||
if (aktindex > ROIInfo.length)
|
||||
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)
|
||||
if (option.text == _sel) {
|
||||
aktindex = i;
|
||||
}
|
||||
}
|
||||
_index.selectedIndex = aktindex;
|
||||
}
|
||||
|
||||
_index.selectedIndex = aktindex;
|
||||
|
||||
document.getElementById("movePrevious").disabled = false;
|
||||
if (aktindex == 0){
|
||||
@@ -526,6 +530,7 @@ function UpdateROIs(_sel){
|
||||
document.getElementById("lockSizes").checked = lockSizes;
|
||||
document.getElementById("lockSpaceEquidistant").checked = lockSpaceEquidistant;
|
||||
document.getElementById("space").value = space;
|
||||
|
||||
if (!lockSpaceEquidistant) {
|
||||
document.getElementById("space").disabled = true;
|
||||
}
|
||||
@@ -542,7 +547,7 @@ function UpdateROIs(_sel){
|
||||
rect.w = ROIInfo[aktindex]["dx"];
|
||||
rect.h = ROIInfo[aktindex]["dy"];
|
||||
draw();
|
||||
}
|
||||
}
|
||||
|
||||
function loadCanvas(dataURL) {
|
||||
var canvas = document.getElementById('canvas');
|
||||
@@ -558,8 +563,8 @@ function UpdateROIs(_sel){
|
||||
imageObj.src = dataURL;
|
||||
}
|
||||
|
||||
|
||||
function getCoords(elem) { // crossbrowser version
|
||||
function getCoords(elem) {
|
||||
// crossbrowser version
|
||||
var box = elem.getBoundingClientRect();
|
||||
var body = document.body;
|
||||
var docEl = document.documentElement;
|
||||
@@ -572,16 +577,15 @@ function UpdateROIs(_sel){
|
||||
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')
|
||||
if(hash == 'description') {
|
||||
document.getElementById("desc_details").open = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function init() {
|
||||
openDescription();
|
||||
@@ -596,7 +600,6 @@ function UpdateROIs(_sel){
|
||||
cofcat = getConfigCategory();
|
||||
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
|
||||
@@ -617,8 +620,10 @@ function UpdateROIs(_sel){
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 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) ||
|
||||
@@ -650,87 +655,91 @@ function UpdateROIs(_sel){
|
||||
draw();
|
||||
}
|
||||
|
||||
function drawImage(){
|
||||
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();
|
||||
// context.restore();
|
||||
}
|
||||
|
||||
function UpdateNUMBERS(_sel){
|
||||
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){
|
||||
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
|
||||
if (zw[i]["name"] == _sel) {
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_index.selectedIndex = index;
|
||||
|
||||
UpdateROIs();
|
||||
}
|
||||
}
|
||||
|
||||
function renameNumber(){
|
||||
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 != "")
|
||||
if (erg != "") {
|
||||
firework.launch(erg, 'danger', 30000);
|
||||
else
|
||||
}
|
||||
else {
|
||||
UpdateNUMBERS(_numbernew);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function newNumber(){
|
||||
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 != "")
|
||||
if (erg != "") {
|
||||
firework.launch(erg, 'danger', 30000);
|
||||
else
|
||||
}
|
||||
else {
|
||||
UpdateNUMBERS(_numbernew);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function removeNumber(){
|
||||
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?"))
|
||||
{
|
||||
"Do you really want to proceed?")) {
|
||||
var sel = document.getElementById("Numbers_value1");
|
||||
var _delete= sel.options[sel.selectedIndex].text;
|
||||
erg = DeleteNUMBER(_delete);
|
||||
if (erg != "")
|
||||
if (erg != "") {
|
||||
firework.launch(erg, 'danger', 30000);
|
||||
}
|
||||
UpdateNUMBERS();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function drawTextBG(context, txt, x, y, padding) {
|
||||
function drawTextBG(context, txt, x, y, padding) {
|
||||
context.font = "15px Arial";
|
||||
context.textAlign = "center";
|
||||
|
||||
@@ -740,10 +749,9 @@ function drawTextBG(context, txt, x, y, padding) {
|
||||
|
||||
context.fillStyle = "black";
|
||||
context.fillText(txt, x + padding / 2, y + padding / 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function draw() {
|
||||
function draw() {
|
||||
if (typeof ROIInfo === 'undefined') { // During init, ROIInfo is not defined yet
|
||||
return;
|
||||
}
|
||||
@@ -756,17 +764,14 @@ function draw() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (document.getElementById("Category_Digits_enabled").checked)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
@@ -774,10 +779,9 @@ function draw() {
|
||||
}
|
||||
}
|
||||
|
||||
for (var _nb = 0; _nb < ROIInfo.length; _nb++)
|
||||
{
|
||||
if (_nb != _number)
|
||||
{
|
||||
if (document.getElementById("showall").checked) {
|
||||
for (var _nb = 0; _nb < ROIInfo.length; _nb++) {
|
||||
if (_nb != _number) {
|
||||
lw = 2;
|
||||
context.lineWidth = lw;
|
||||
context.strokeStyle = "#990000";
|
||||
@@ -801,6 +805,7 @@ function draw() {
|
||||
context.strokeRect(x0+dx*0.2, y0+dy*0.2, dx*0.6, dy*0.6);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lw = 4
|
||||
context.lineWidth = lw;
|
||||
@@ -814,7 +819,6 @@ function draw() {
|
||||
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);
|
||||
@@ -864,7 +868,8 @@ function draw() {
|
||||
|
||||
if (lockAspectRatio) {
|
||||
rect.h = (e.pageY - zw.top) - rect.startY;
|
||||
rect.w = Math.round(rect.h * ROIInfo[aktindex]["ar"]); }
|
||||
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;
|
||||
@@ -893,7 +898,7 @@ function draw() {
|
||||
}
|
||||
}
|
||||
|
||||
function valuemanualchanged(){
|
||||
function valuemanualchanged() {
|
||||
if (ROIInfo.length == 0) {
|
||||
return;
|
||||
}
|
||||
@@ -919,7 +924,7 @@ function draw() {
|
||||
document.getElementById("saveroi").disabled = false;
|
||||
}
|
||||
|
||||
function valuemanualchangeddx(){
|
||||
function valuemanualchangeddx() {
|
||||
if (ROIInfo.length == 0) {
|
||||
return;
|
||||
}
|
||||
@@ -945,7 +950,7 @@ function draw() {
|
||||
document.getElementById("saveroi").disabled = false;
|
||||
}
|
||||
|
||||
function valuemanualchangedspace(){
|
||||
function valuemanualchangedspace() {
|
||||
if (!drag) {
|
||||
space = document.getElementById("space").value;
|
||||
valuemanualchanged();
|
||||
@@ -978,7 +983,7 @@ function draw() {
|
||||
}
|
||||
}
|
||||
|
||||
function renameROI(){
|
||||
function renameROI() {
|
||||
var sel = document.getElementById("Numbers_value1");
|
||||
var _number= sel.options[sel.selectedIndex].text;
|
||||
sel = document.getElementById("index");
|
||||
@@ -990,22 +995,21 @@ function draw() {
|
||||
}
|
||||
|
||||
erg = RenameROI(_number, "digit", _roialt, _roinew);
|
||||
if (erg != "")
|
||||
if (erg != "") {
|
||||
firework.launch(erg, 'danger', 30000);
|
||||
else
|
||||
}
|
||||
else {
|
||||
UpdateROIs(_roinew);
|
||||
}
|
||||
}
|
||||
|
||||
function numberChanged()
|
||||
{
|
||||
function numberChanged() {
|
||||
aktindex = 0;
|
||||
UpdateROIs();
|
||||
}
|
||||
|
||||
|
||||
init();
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
BIN
sd-card/html/img/flipImageSize.png
Normal file
BIN
sd-card/html/img/flipImageSize.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 167 KiB |
@@ -24,7 +24,7 @@
|
||||
'channelmode=no,directories=no,fullscreen=no,' +
|
||||
'location=no,dependent=yes,menubar=no,resizable=no,scrollbars=no,' +
|
||||
'status=no,toolbar=no,titlebar=no,' +
|
||||
'left=10,top=250,width=640px,height=480px';
|
||||
'left=10,top=260,width=640px,height=480px';
|
||||
|
||||
function loadPage(page) {
|
||||
console.log("loadPage( " + page + " )");
|
||||
@@ -88,21 +88,21 @@
|
||||
<ul>
|
||||
<li><a href="#" onclick="loadPage('overview.html?v=$COMMIT_HASH');">Overview</a></li>
|
||||
<li><a>Settings <i class="arrow down"></i></a>
|
||||
<ul class="submenu">
|
||||
<li><a href="#" onclick="loadPage('prevalue_set.html?v=$COMMIT_HASH');">Set "Previous Value"</a></li>
|
||||
<li><a href="#" onclick="loadPage('edit_config_param.html?v=$COMMIT_HASH');">Configuration</a></li>
|
||||
<li><a>Alignment <i class="arrow right"></i></a>
|
||||
<ul>
|
||||
<li><a href="#" onclick="loadPage('edit_reference.html?v=$COMMIT_HASH');">Reference Image</a></li>
|
||||
<li><a href="#" onclick="loadPage('edit_alignment.html?v=$COMMIT_HASH');">Alignment Marker</a></li>
|
||||
<ul class="submenu" style="width: 260px">
|
||||
<li style="width: 260px"><a href="#" onclick="loadPage('prevalue_set.html?v=$COMMIT_HASH');">Set "Previous Value"</a></li>
|
||||
<li style="width: 260px"><a>Alignment <i class="arrow right"></i></a>
|
||||
<ul style="width: 350px">
|
||||
<li style="width: 350px"><a href="#" onclick="loadPage('edit_reference.html?v=$COMMIT_HASH');">Reference Image and Camera Settings</a></li>
|
||||
<li style="width: 350px"><a href="#" onclick="loadPage('edit_alignment.html?v=$COMMIT_HASH');">Alignment Markers</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a><strong>R</strong>egions <strong>O</strong>f <strong>I</strong>nterest <i class="arrow right"></i></a>
|
||||
<li style="width: 260px"><a>Regions of Interest (ROIs)<i class="arrow right"></i></a>
|
||||
<ul>
|
||||
<li><a href="#" onclick="loadPage('edit_digits.html?v=$COMMIT_HASH');">Digit ROI</a></li>
|
||||
<li><a href="#" onclick="loadPage('edit_analog.html?v=$COMMIT_HASH');">Analog ROI</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li style="width: 260px"><a href="#" onclick="loadPage('edit_config.html?v=$COMMIT_HASH');">Configuration</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
@@ -242,7 +242,7 @@ table {
|
||||
|
||||
|
||||
<h3>Copyright</h3>
|
||||
Copyright © 2020 - 2023 by <a href="https://github.com/jomjol/AI-on-the-edge-device" target=_blank>Jomjol</a> and others.
|
||||
Copyright © 2020 - 2024 by <a href="https://github.com/jomjol/AI-on-the-edge-device" target=_blank>Jomjol</a> and others.
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -202,7 +202,7 @@
|
||||
if (action_runtime > 10) { // After 10 seconds, start to check if we are up again
|
||||
/* Check if the device is up again and forward to index page if so */
|
||||
fetch('reboot_page.html?v=$COMMIT_HASH&' + Math.random(), {mode: 'no-cors'}).then(
|
||||
r=>{parent.location.href=('index.html?v=$COMMIT_HASH');}
|
||||
r=>{parent.location.href=('index.html?v=' + Math.random());}
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -39,13 +39,11 @@ function createReader(file) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
function ZerlegeZeile(input, delimiter = " =\t\r")
|
||||
{
|
||||
var Output = Array(0);
|
||||
// delimiter = " =,\t";
|
||||
|
||||
|
||||
/* The input can have multiple formats:
|
||||
* - key = value
|
||||
* - key = value1 value2 value3 ...
|
||||
@@ -82,7 +80,6 @@ function ZerlegeZeile(input, delimiter = " =\t\r")
|
||||
}
|
||||
|
||||
return Output;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -111,7 +108,6 @@ function findDelimiterPos(input, delimiter)
|
||||
}
|
||||
|
||||
|
||||
|
||||
function trim(istring, adddelimiter)
|
||||
{
|
||||
while ((istring.length > 0) && (adddelimiter.indexOf(istring[0]) >= 0)){
|
||||
@@ -234,32 +230,21 @@ function FileSendContent(_content, _filename, _domainname = ""){
|
||||
}
|
||||
|
||||
|
||||
function SaveCanvasToImage(_canvas, _filename, _delete = true, _domainname = ""){
|
||||
var JPEG_QUALITY=0.8;
|
||||
var dataUrl = _canvas.toDataURL('image/jpeg', JPEG_QUALITY);
|
||||
var rtn = dataURLtoBlob(dataUrl);
|
||||
function MakeRefImageZW(zw, _enhance, _domainname){
|
||||
var _filename = zw["name"].replace("/config/", "/img_tmp/");
|
||||
|
||||
if (_delete) {
|
||||
FileDeleteOnServer(_filename, _domainname);
|
||||
}
|
||||
var url = _domainname + "/editflow?task=cutref&in=/config/reference.jpg&out=" + _filename + "&x=" + zw["x"] + "&y=" + zw["y"] + "&dx=" + zw["dx"] + "&dy=" + zw["dy"];
|
||||
|
||||
FileSendContent(rtn, _filename, _domainname);
|
||||
}
|
||||
|
||||
|
||||
function MakeContrastImageZW(zw, _enhance, _domainname){
|
||||
_filename = zw["name"].replace("/config/", "/img_tmp/");
|
||||
url = _domainname + "/editflow?task=cutref&in=/config/reference.jpg&out=" + _filename + "&x=" + zw["x"] + "&y=" + zw["y"] + "&dx=" + zw["dx"] + "&dy=" + zw["dy"];
|
||||
if (_enhance == true){
|
||||
url = url + "&enhance=true";
|
||||
}
|
||||
|
||||
var xhttp = new XMLHttpRequest();
|
||||
|
||||
try {
|
||||
xhttp.open("GET", url, false);
|
||||
xhttp.send();
|
||||
}
|
||||
catch (error){}
|
||||
} catch (error){}
|
||||
|
||||
if (xhttp.responseText == "CutImage Done") {
|
||||
firework.launch('Image Contrast got enhanced', 'success', 5000);
|
||||
@@ -269,28 +254,3 @@ function MakeContrastImageZW(zw, _enhance, _domainname){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function MakeRefZW(zw, _domainname){
|
||||
_filetarget = zw["name"].replace("/config/", "/img_tmp/");
|
||||
_filetarget = _filetarget.replace(".jpg", "_org.jpg");
|
||||
url = _domainname + "/editflow?task=cutref&in=/config/reference.jpg&out="+_filetarget+"&x=" + zw["x"] + "&y=" + zw["y"] + "&dx=" + zw["dx"] + "&dy=" + zw["dy"];
|
||||
var xhttp = new XMLHttpRequest();
|
||||
try {
|
||||
xhttp.open("GET", url, false);
|
||||
xhttp.send();
|
||||
}
|
||||
catch (error){}
|
||||
|
||||
if (xhttp.responseText == "CutImage Done") {
|
||||
_filetarget2 = zw["name"].replace("/config/", "/img_tmp/");
|
||||
// _filetarget2 = _filetarget2.replace(".jpg", "_org.jpg");
|
||||
FileCopyOnServer(_filetarget, _filetarget2, _domainname);
|
||||
firework.launch('Marker got updated', 'success', 5000);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -117,9 +117,18 @@ function ParseConfig() {
|
||||
ParamAddValue(param, catname, "Brightness");
|
||||
ParamAddValue(param, catname, "Contrast");
|
||||
ParamAddValue(param, catname, "Saturation");
|
||||
ParamAddValue(param, catname, "Sharpness");
|
||||
ParamAddValue(param, catname, "LEDIntensity");
|
||||
ParamAddValue(param, catname, "ImageQuality");
|
||||
ParamAddValue(param, catname, "ImageSize");
|
||||
ParamAddValue(param, catname, "Zoom");
|
||||
ParamAddValue(param, catname, "ZoomMode");
|
||||
ParamAddValue(param, catname, "ZoomOffsetX");
|
||||
ParamAddValue(param, catname, "ZoomOffsetY");
|
||||
ParamAddValue(param, catname, "Grayscale");
|
||||
ParamAddValue(param, catname, "Negative");
|
||||
ParamAddValue(param, catname, "Aec2");
|
||||
ParamAddValue(param, catname, "AutoExposureLevel");
|
||||
ParamAddValue(param, catname, "FixedExposure");
|
||||
|
||||
var catname = "Alignment";
|
||||
@@ -458,8 +467,6 @@ function WriteConfigININew()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
config_split = new Array(0);
|
||||
|
||||
for (var cat in param) {
|
||||
@@ -556,7 +563,6 @@ function WriteConfigININew()
|
||||
}
|
||||
|
||||
|
||||
|
||||
function isCommented(input)
|
||||
{
|
||||
let isComment = false;
|
||||
@@ -593,7 +599,6 @@ function getConfigCategory() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
function ExtractROIs(_aktline, _type){
|
||||
var linesplit = ZerlegeZeile(_aktline);
|
||||
abc = getNUMBERS(linesplit[0], _type);
|
||||
@@ -669,7 +674,6 @@ function getNUMBERS(_name, _type, _create = true)
|
||||
}
|
||||
|
||||
|
||||
|
||||
function CopyReferenceToImgTmp(_domainname)
|
||||
{
|
||||
for (index = 0; index < 2; ++index)
|
||||
@@ -691,7 +695,7 @@ function GetReferencesInfo(){
|
||||
}
|
||||
|
||||
|
||||
function UpdateConfigReference(_domainname){
|
||||
function UpdateConfigReferences(_domainname){
|
||||
for (var index = 0; index < 2; ++index)
|
||||
{
|
||||
_filenamenach = REFERENCES[index]["name"];
|
||||
@@ -703,11 +707,35 @@ function UpdateConfigReference(_domainname){
|
||||
_filenamevon = _filenamevon.replace(".jpg", "_org.jpg");
|
||||
FileDeleteOnServer(_filenamenach, _domainname);
|
||||
FileCopyOnServer(_filenamevon, _filenamenach, _domainname);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function UpdateConfigReference(_anzneueref, _domainname){
|
||||
var index = 0;
|
||||
|
||||
if (_anzneueref == 1) {
|
||||
index = 0;
|
||||
}
|
||||
|
||||
else if (_anzneueref == 2) {
|
||||
index = 1;
|
||||
}
|
||||
|
||||
_filenamenach = REFERENCES[index]["name"];
|
||||
_filenamevon = _filenamenach.replace("/config/", "/img_tmp/");
|
||||
|
||||
FileDeleteOnServer(_filenamenach, _domainname);
|
||||
FileCopyOnServer(_filenamevon, _filenamenach, _domainname);
|
||||
|
||||
_filenamenach = _filenamenach.replace(".jpg", "_org.jpg");
|
||||
_filenamevon = _filenamevon.replace(".jpg", "_org.jpg");
|
||||
|
||||
FileDeleteOnServer(_filenamenach, _domainname);
|
||||
FileCopyOnServer(_filenamevon, _filenamenach, _domainname);
|
||||
}
|
||||
|
||||
|
||||
function getNUMBERInfo(){
|
||||
return NUMBERS;
|
||||
}
|
||||
|
||||
@@ -268,7 +268,7 @@ body, html {
|
||||
break;
|
||||
|
||||
case 6: // Config page
|
||||
document.getElementById('maincontent').src = 'edit_config_param.html?v=$COMMIT_HASH#description';
|
||||
document.getElementById('maincontent').src = 'edit_config.html?v=$COMMIT_HASH#description';
|
||||
|
||||
document.getElementById('h_iframe_explain').style.display = "";
|
||||
document.getElementById('h_iframe_explain').style="height:100px;"
|
||||
|
||||
@@ -8,8 +8,9 @@ import markdown
|
||||
|
||||
parameterDocsFolder = "../../param-docs/parameter-pages"
|
||||
docsMainFolder = "../../sd-card/html"
|
||||
configPageTemplate = "edit_config_param_template.html"
|
||||
configPage = "edit_config_param.html"
|
||||
configPageTemplate = "edit_config_template.html"
|
||||
configPage = "edit_config.html"
|
||||
refImagePage = "edit_reference.html"
|
||||
|
||||
htmlTooltipPrefix = """
|
||||
<div class="rst-content"><div class="tooltip"><img src="help.png" width="32px"><span class="tooltiptext">
|
||||
@@ -54,13 +55,16 @@ def generateHtmlTooltip(section, parameter, markdownFile):
|
||||
# Add the tooltip to the config page
|
||||
with open(docsMainFolder + "/" + configPage, 'r') as configPageHandle:
|
||||
configPageContent = configPageHandle.read()
|
||||
|
||||
# print("replacing $TOOLTIP_" + section + "_" + parameter + " with the tooltip content...")
|
||||
configPageContent = configPageContent.replace("<td>$TOOLTIP_" + section + "_" + parameter + "</td>", "<td>" + htmlTooltip + "</td>")
|
||||
|
||||
with open(docsMainFolder + "/" + configPage, 'w') as configPageHandle:
|
||||
configPageHandle.write(configPageContent)
|
||||
|
||||
# Add the tooltip to the reference image page
|
||||
with open(docsMainFolder + "/" + refImagePage, 'r') as refImagePageHandle:
|
||||
refImagePageContent = refImagePageHandle.read()
|
||||
refImagePageContent = refImagePageContent.replace("<td>$TOOLTIP_" + section + "_" + parameter + "</td>", "<td>" + htmlTooltip + "</td>")
|
||||
with open(docsMainFolder + "/" + refImagePage, 'w') as refImagePageHandle:
|
||||
refImagePageHandle.write(refImagePageContent)
|
||||
|
||||
print("Generating Tooltips...")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user