mirror of
https://github.com/jomjol/AI-on-the-edge-device.git
synced 2025-12-07 03:56:57 +03:00
Compare commits
101 Commits
mqtt-logfi
...
analog-dig
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
919ede0e7c | ||
|
|
b0a7c7716f | ||
|
|
aff08fafee | ||
|
|
ed746f96b9 | ||
|
|
fa08a02e12 | ||
|
|
57715b5bdd | ||
|
|
53f3b99f05 | ||
|
|
ba63d0a589 | ||
|
|
0309620fd6 | ||
|
|
295038a881 | ||
|
|
488ae174a4 | ||
|
|
4049d752ba | ||
|
|
4b4b42d4c5 | ||
|
|
135b03d505 | ||
|
|
74c09ac023 | ||
|
|
dc90972659 | ||
|
|
32282ecfe2 | ||
|
|
ae6a94544b | ||
|
|
70b031eacc | ||
|
|
c3fadf5c2a | ||
|
|
7e5f6bf4a5 | ||
|
|
88b531ae8b | ||
|
|
8481cc4b26 | ||
|
|
ecaed38c1d | ||
|
|
d6a1838d47 | ||
|
|
5194c466be | ||
|
|
043de9265a | ||
|
|
08a350172d | ||
|
|
7e806df64d | ||
|
|
dccfb5e91e | ||
|
|
fbe4609bb9 | ||
|
|
3e85cfb456 | ||
|
|
5dff4ca8cf | ||
|
|
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 | ||
|
|
1f4b8807fb | ||
|
|
827ca1cf61 | ||
|
|
dc640d7bce | ||
|
|
b551eadf8a | ||
|
|
8e8ac621dd | ||
|
|
54d4990d16 | ||
|
|
f8dd986e4f | ||
|
|
444dc0fa39 |
@@ -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
|
||||
30
Changelog.md
30
Changelog.md
@@ -1,3 +1,31 @@
|
||||
## [update] - 2024-03-30
|
||||
|
||||
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
|
||||
|
||||
- New tflite-Model for Analog (v13.0.0)
|
||||
- New tflite-Model for Digital Hybrid (v7.0.0)
|
||||
|
||||
#### Bug Fixes
|
||||
|
||||
- tbd
|
||||
|
||||
## [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)
|
||||
@@ -42,6 +70,8 @@ For a full list of changes see [Full list of changes](https://github.com/jomjol/
|
||||
- dig-class100-0167_s2_q.tflite
|
||||
- dig-class11_1700_s2.tflite
|
||||
- ana-cont_1208_s2_q.tflite
|
||||
|
||||
- Added config entries for MQTT TLS
|
||||
|
||||
|
||||
#### Fixed
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -15,49 +15,100 @@
|
||||
#include "CImageBasis.h"
|
||||
#include "../../include/defines.h"
|
||||
|
||||
class CCamera {
|
||||
protected:
|
||||
int ActualQuality;
|
||||
framesize_t ActualResolution;
|
||||
int brightness, contrast, saturation;
|
||||
bool isFixedExposure;
|
||||
int waitbeforepicture_org;
|
||||
int led_intensity = 4095;
|
||||
typedef enum
|
||||
{
|
||||
OV2640_MODE_UXGA,
|
||||
OV2640_MODE_SVGA,
|
||||
OV2640_MODE_CIF
|
||||
} ov2640_sensor_mode_t;
|
||||
|
||||
void ledc_init(void);
|
||||
bool CameraInitSuccessful = false;
|
||||
bool demoMode = false;
|
||||
typedef struct
|
||||
{
|
||||
framesize_t ImageFrameSize = FRAMESIZE_VGA; // 0 - 10
|
||||
gainceiling_t ImageGainceiling; // Image gain (GAINCEILING_x2, x4, x8, x16, x32, x64 or x128)
|
||||
|
||||
bool loadNextDemoImage(camera_fb_t *fb);
|
||||
long GetFileSize(std::string filename);
|
||||
int ImageQuality; // 0 - 63
|
||||
int ImageBrightness; // (-2 to 2) - set brightness
|
||||
int ImageContrast; //-2 - 2
|
||||
int ImageSaturation; //-2 - 2
|
||||
int ImageSharpness; //-2 - 2
|
||||
bool ImageAutoSharpness;
|
||||
int ImageSpecialEffect; // 0 - 6
|
||||
int ImageWbMode; // 0 to 4 - if awb_gain enabled (0 - Auto, 1 - Sunny, 2 - Cloudy, 3 - Office, 4 - Home)
|
||||
int ImageAwb; // white balance enable (0 or 1)
|
||||
int ImageAwbGain; // Auto White Balance enable (0 or 1)
|
||||
int ImageAec; // auto exposure off (1 or 0)
|
||||
int ImageAec2; // automatic exposure sensor (0 or 1)
|
||||
int ImageAeLevel; // auto exposure levels (-2 to 2)
|
||||
int ImageAecValue; // set exposure manually (0-1200)
|
||||
int ImageAgc; // auto gain off (1 or 0)
|
||||
int ImageAgcGain; // set gain manually (0 - 30)
|
||||
int ImageBpc; // black pixel correction
|
||||
int ImageWpc; // white pixel correction
|
||||
int ImageRawGma; // (1 or 0)
|
||||
int ImageLenc; // lens correction (1 or 0)
|
||||
int ImageHmirror; // (0 or 1) flip horizontally
|
||||
int ImageVflip; // Invert image (0 or 1)
|
||||
int ImageDcw; // downsize enable (1 or 0)
|
||||
|
||||
public:
|
||||
int image_height, image_width;
|
||||
|
||||
CCamera();
|
||||
esp_err_t InitCam();
|
||||
int ImageWidth;
|
||||
int ImageHeight;
|
||||
|
||||
void LightOnOff(bool status);
|
||||
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 SetLEDIntensity(float _intrel);
|
||||
bool testCamera(void);
|
||||
void EnableAutoExposure(int flash_duration);
|
||||
bool getCameraInitSuccessful();
|
||||
void useDemoMode(void);
|
||||
|
||||
int ImageLedIntensity;
|
||||
|
||||
framesize_t TextToFramesize(const char * text);
|
||||
bool ImageZoomEnabled;
|
||||
int ImageZoomMode;
|
||||
int ImageZoomOffsetX;
|
||||
int ImageZoomOffsetY;
|
||||
int ImageZoomSize;
|
||||
|
||||
esp_err_t CaptureToFile(std::string nm, int delay = 0);
|
||||
esp_err_t CaptureToBasisImage(CImageBasis *_Image, int delay = 0);
|
||||
int WaitBeforePicture;
|
||||
bool isImageSize;
|
||||
|
||||
bool CameraInitSuccessful;
|
||||
bool changedCameraSettings;
|
||||
bool DemoMode;
|
||||
bool SaveAllFiles;
|
||||
} camera_controll_config_temp_t;
|
||||
|
||||
extern camera_controll_config_temp_t CCstatus;
|
||||
|
||||
class CCamera
|
||||
{
|
||||
protected:
|
||||
void ledc_init(void);
|
||||
bool loadNextDemoImage(camera_fb_t *fb);
|
||||
long GetFileSize(std::string filename);
|
||||
void SetCamWindow(sensor_t *s, int resolution, int xOffset, int yOffset, int xTotal, int yTotal, int xOutput, int yOutput);
|
||||
void SetImageWidthHeightFromResolution(framesize_t resol);
|
||||
|
||||
public:
|
||||
CCamera(void);
|
||||
esp_err_t InitCam(void);
|
||||
|
||||
void LightOnOff(bool status);
|
||||
void LEDOnOff(bool status);
|
||||
|
||||
esp_err_t setSensorDatenFromCCstatus(void);
|
||||
esp_err_t getSensorDatenToCCstatus(void);
|
||||
|
||||
esp_err_t CaptureToHTTP(httpd_req_t *req, int delay = 0);
|
||||
esp_err_t CaptureToStream(httpd_req_t *req, bool FlashlightOn);
|
||||
|
||||
void SetQualityZoomSize(int qual, framesize_t resol, bool zoomEnabled, int zoomOffsetX, int zoomOffsetY, int imageSize);
|
||||
void SetZoomSize(bool zoomEnabled, int zoomOffsetX, int zoomOffsetY, int imageSize);
|
||||
void SetCamSharpness(bool _autoSharpnessEnabled, int _sharpnessLevel);
|
||||
|
||||
void SetLEDIntensity(float _intrel);
|
||||
bool testCamera(void);
|
||||
bool getCameraInitSuccessful(void);
|
||||
void useDemoMode(void);
|
||||
|
||||
framesize_t TextToFramesize(const char *text);
|
||||
|
||||
esp_err_t CaptureToFile(std::string nm, int delay = 0);
|
||||
esp_err_t CaptureToBasisImage(CImageBasis *_Image, int delay = 0);
|
||||
};
|
||||
|
||||
|
||||
extern CCamera Camera;
|
||||
|
||||
#endif
|
||||
152
code/components/jomjol_controlcamera/ov2640_sharpness.cpp
Normal file
152
code/components/jomjol_controlcamera/ov2640_sharpness.cpp
Normal file
@@ -0,0 +1,152 @@
|
||||
#include <stdint.h>
|
||||
#include "esp_camera.h"
|
||||
#include "ov2640_sharpness.h"
|
||||
|
||||
|
||||
const static uint8_t OV2640_SHARPNESS_AUTO[]=
|
||||
{
|
||||
//reg, val, mask
|
||||
0xFF, 0x00, 0xFF,
|
||||
0x92, 0x01, 0xFF,
|
||||
0x93, 0x20, 0x20,
|
||||
0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
const static uint8_t OV2640_SHARPNESS_MANUAL[]=
|
||||
{
|
||||
//reg, val, mask
|
||||
0xFF, 0x00, 0xFF,
|
||||
0x92, 0x01, 0xFF,
|
||||
0x93, 0x00, 0x20,
|
||||
0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
const static uint8_t OV2640_SHARPNESS_LEVEL0[]=
|
||||
{
|
||||
//reg, val, mask
|
||||
0xFF, 0x00, 0xFF,
|
||||
0x92, 0x01, 0xFF,
|
||||
0x93, 0xC0, 0x1F,
|
||||
0x00, 0x00, 0x00
|
||||
};
|
||||
const static uint8_t OV2640_SHARPNESS_LEVEL1[]=
|
||||
{
|
||||
//reg, val, mask
|
||||
0xFF, 0x00, 0xFF,
|
||||
0x92, 0x01, 0xFF,
|
||||
0x93, 0xC1, 0x1F,
|
||||
0x00, 0x00, 0x00
|
||||
};
|
||||
const static uint8_t OV2640_SHARPNESS_LEVEL2[]=
|
||||
{
|
||||
//reg, val, mask
|
||||
0xFF, 0x00, 0xFF,
|
||||
0x92, 0x01, 0xFF,
|
||||
0x93, 0xC2, 0x1F,
|
||||
0x00, 0x00, 0x00
|
||||
};
|
||||
const static uint8_t OV2640_SHARPNESS_LEVEL3[]=
|
||||
{
|
||||
//reg, val, mask
|
||||
0xFF, 0x00, 0xFF,
|
||||
0x92, 0x01, 0xFF,
|
||||
0x93, 0xC4, 0x1F,
|
||||
0x00, 0x00, 0x00
|
||||
};
|
||||
const static uint8_t OV2640_SHARPNESS_LEVEL4[]=
|
||||
{
|
||||
//reg, val, mask
|
||||
0xFF, 0x00, 0xFF,
|
||||
0x92, 0x01, 0xFF,
|
||||
0x93, 0xC8, 0x1F,
|
||||
0x00, 0x00, 0x00
|
||||
};
|
||||
const static uint8_t OV2640_SHARPNESS_LEVEL5[]=
|
||||
{
|
||||
//reg, val, mask
|
||||
0xFF, 0x00, 0xFF,
|
||||
0x92, 0x01, 0xFF,
|
||||
0x93, 0xD0, 0x1F,
|
||||
0x00, 0x00, 0x00
|
||||
};
|
||||
const static uint8_t OV2640_SHARPNESS_LEVEL6[]=
|
||||
{
|
||||
//reg, val, mask
|
||||
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
|
||||
};
|
||||
|
||||
#define OV2640_MAXLEVEL_SHARPNESS 6
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
int sharpness_temp = 0;
|
||||
|
||||
if (sharpness < -3)
|
||||
{
|
||||
sharpness_temp = -3;
|
||||
}
|
||||
|
||||
if (sharpness > OV2640_MAXLEVEL_SHARPNESS - 3)
|
||||
{
|
||||
sharpness_temp = OV2640_MAXLEVEL_SHARPNESS - 3;
|
||||
}
|
||||
|
||||
table_mask_write(sensor, OV2640_SHARPNESS_MANUAL);
|
||||
table_mask_write(sensor, OV2640_SETTING_SHARPNESS[sharpness_temp + 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
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include "esp_camera.h"
|
||||
#include "ClassControllCamera.h"
|
||||
#include "MainFlowControl.h"
|
||||
|
||||
#include "ClassLogFile.h"
|
||||
#include "esp_log.h"
|
||||
@@ -13,183 +14,183 @@
|
||||
|
||||
static const char *TAG = "server_cam";
|
||||
|
||||
void PowerResetCamera()
|
||||
{
|
||||
ESP_LOGD(TAG, "Resetting camera by power down line");
|
||||
gpio_config_t conf;
|
||||
conf.intr_type = GPIO_INTR_DISABLE;
|
||||
conf.pin_bit_mask = 1LL << GPIO_NUM_32;
|
||||
conf.mode = GPIO_MODE_OUTPUT;
|
||||
conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
|
||||
conf.pull_up_en = GPIO_PULLUP_DISABLE;
|
||||
gpio_config(&conf);
|
||||
|
||||
void PowerResetCamera(){
|
||||
|
||||
ESP_LOGD(TAG, "Resetting camera by power down line");
|
||||
gpio_config_t conf;
|
||||
conf.intr_type = GPIO_INTR_DISABLE;
|
||||
conf.pin_bit_mask = 1LL << GPIO_NUM_32;
|
||||
conf.mode = GPIO_MODE_OUTPUT;
|
||||
conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
|
||||
conf.pull_up_en = GPIO_PULLUP_DISABLE;
|
||||
gpio_config(&conf);
|
||||
|
||||
// carefull, logic is inverted compared to reset pin
|
||||
gpio_set_level(GPIO_NUM_32, 1);
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
gpio_set_level(GPIO_NUM_32, 0);
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
// carefull, logic is inverted compared to reset pin
|
||||
gpio_set_level(GPIO_NUM_32, 1);
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
gpio_set_level(GPIO_NUM_32, 0);
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
|
||||
|
||||
esp_err_t handler_lightOn(httpd_req_t *req)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_lightOn - Start");
|
||||
ESP_LOGD(TAG, "handler_lightOn uri: %s", req->uri);
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_lightOn - Start");
|
||||
ESP_LOGD(TAG, "handler_lightOn uri: %s", req->uri);
|
||||
#endif
|
||||
|
||||
if (Camera.getCameraInitSuccessful())
|
||||
if (Camera.getCameraInitSuccessful())
|
||||
{
|
||||
Camera.LightOnOff(true);
|
||||
const char* resp_str = (const char*) req->user_ctx;
|
||||
const char *resp_str = (const char *)req->user_ctx;
|
||||
httpd_resp_send(req, resp_str, strlen(resp_str));
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
httpd_resp_send_err(req, HTTPD_403_FORBIDDEN, "Camera not initialized: REST API /lighton not available!");
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_lightOn - Done");
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_lightOn - Done");
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
esp_err_t handler_lightOff(httpd_req_t *req)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_lightOff - Start");
|
||||
ESP_LOGD(TAG, "handler_lightOff uri: %s", req->uri);
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_lightOff - Start");
|
||||
ESP_LOGD(TAG, "handler_lightOff uri: %s", req->uri);
|
||||
#endif
|
||||
|
||||
if (Camera.getCameraInitSuccessful())
|
||||
if (Camera.getCameraInitSuccessful())
|
||||
{
|
||||
Camera.LightOnOff(false);
|
||||
const char* resp_str = (const char*) req->user_ctx;
|
||||
httpd_resp_send(req, resp_str, strlen(resp_str));
|
||||
const char *resp_str = (const char *)req->user_ctx;
|
||||
httpd_resp_send(req, resp_str, strlen(resp_str));
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
httpd_resp_send_err(req, HTTPD_403_FORBIDDEN, "Camera not initialized: REST API /lightoff not available!");
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_lightOff - Done");
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_lightOff - Done");
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
esp_err_t handler_capture(httpd_req_t *req)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_capture - Start");
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_capture - Start");
|
||||
#endif
|
||||
|
||||
if (Camera.getCameraInitSuccessful())
|
||||
if (Camera.getCameraInitSuccessful())
|
||||
{
|
||||
int quality;
|
||||
framesize_t res;
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Size: %d, Quality: %d", res, quality);
|
||||
#endif
|
||||
|
||||
Camera.GetCameraParameter(req, quality, res);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Size: %d, Quality: %d", res, quality);
|
||||
#endif
|
||||
|
||||
Camera.SetQualitySize(quality, res);
|
||||
// wenn die Kameraeinstellungen durch Erstellen eines neuen Referenzbildes verändert wurden, müssen sie neu gesetzt werden
|
||||
if (CFstatus.changedCameraSettings)
|
||||
{
|
||||
Camera.setSensorDatenFromCCstatus(); // CCstatus >>> Kamera
|
||||
Camera.SetQualityZoomSize(CCstatus.ImageQuality, CCstatus.ImageFrameSize, CCstatus.ImageZoomEnabled, CCstatus.ImageZoomOffsetX, CCstatus.ImageZoomOffsetY, CCstatus.ImageZoomSize);
|
||||
CFstatus.changedCameraSettings = false;
|
||||
}
|
||||
|
||||
esp_err_t result;
|
||||
result = Camera.CaptureToHTTP(req);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_capture - Done");
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_capture - Done");
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
httpd_resp_send_err(req, HTTPD_403_FORBIDDEN, "Camera not initialized: REST API /capture not available!");
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
esp_err_t handler_capture_with_light(httpd_req_t *req)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_capture_with_light - Start");
|
||||
#endif
|
||||
|
||||
if (Camera.getCameraInitSuccessful())
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_capture_with_light - Start");
|
||||
#endif
|
||||
|
||||
if (Camera.getCameraInitSuccessful())
|
||||
{
|
||||
char _query[100];
|
||||
char _delay[10];
|
||||
|
||||
int quality;
|
||||
framesize_t res;
|
||||
int delay = 2500;
|
||||
|
||||
if (httpd_req_get_url_query_str(req, _query, 100) == ESP_OK)
|
||||
{
|
||||
ESP_LOGD(TAG, "Query: %s", _query);
|
||||
|
||||
if (httpd_query_key_value(_query, "delay", _delay, 10) == ESP_OK)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Delay: %s", _delay);
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Delay: %s", _delay);
|
||||
#endif
|
||||
delay = atoi(_delay);
|
||||
|
||||
if (delay < 0)
|
||||
{
|
||||
delay = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Camera.GetCameraParameter(req, quality, res);
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Size: %d, Quality: %d", res, quality);
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Size: %d, Quality: %d", res, quality);
|
||||
#endif
|
||||
// wenn die Kameraeinstellungen durch Erstellen eines neuen Referenzbildes verändert wurden, müssen sie neu gesetzt werden
|
||||
if (CFstatus.changedCameraSettings)
|
||||
{
|
||||
Camera.setSensorDatenFromCCstatus(); // CCstatus >>> Kamera
|
||||
Camera.SetQualityZoomSize(CCstatus.ImageQuality, CCstatus.ImageFrameSize, CCstatus.ImageZoomEnabled, CCstatus.ImageZoomOffsetX, CCstatus.ImageZoomOffsetY, CCstatus.ImageZoomSize);
|
||||
CFstatus.changedCameraSettings = false;
|
||||
}
|
||||
|
||||
Camera.SetQualitySize(quality, res);
|
||||
Camera.LightOnOff(true);
|
||||
const TickType_t xDelay = delay / portTICK_PERIOD_MS;
|
||||
vTaskDelay( xDelay );
|
||||
vTaskDelay(xDelay);
|
||||
|
||||
esp_err_t result;
|
||||
result = Camera.CaptureToHTTP(req);
|
||||
result = Camera.CaptureToHTTP(req);
|
||||
|
||||
Camera.LightOnOff(false);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_capture_with_light - Done");
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_capture_with_light - Done");
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
httpd_resp_send_err(req, HTTPD_403_FORBIDDEN, "Camera not initialized: REST API /capture_with_flashlight not available!");
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
esp_err_t handler_capture_save_to_file(httpd_req_t *req)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_capture_save_to_file - Start");
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_capture_save_to_file - Start");
|
||||
#endif
|
||||
|
||||
if (Camera.getCameraInitSuccessful())
|
||||
if (Camera.getCameraInitSuccessful())
|
||||
{
|
||||
char _query[100];
|
||||
char _delay[10];
|
||||
@@ -197,94 +198,102 @@ esp_err_t handler_capture_save_to_file(httpd_req_t *req)
|
||||
char filename[100];
|
||||
std::string fn = "/sdcard/";
|
||||
|
||||
|
||||
int quality;
|
||||
framesize_t res;
|
||||
|
||||
if (httpd_req_get_url_query_str(req, _query, 100) == ESP_OK)
|
||||
{
|
||||
ESP_LOGD(TAG, "Query: %s", _query);
|
||||
|
||||
if (httpd_query_key_value(_query, "filename", filename, 100) == ESP_OK)
|
||||
{
|
||||
fn.append(filename);
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Filename: %s", fn.c_str());
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Filename: %s", fn.c_str());
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
fn.append("noname.jpg");
|
||||
}
|
||||
|
||||
if (httpd_query_key_value(_query, "delay", _delay, 10) == ESP_OK)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Delay: %s", _delay);
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Delay: %s", _delay);
|
||||
#endif
|
||||
delay = atoi(_delay);
|
||||
|
||||
if (delay < 0)
|
||||
{
|
||||
delay = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fn.append("noname.jpg");
|
||||
}
|
||||
|
||||
Camera.GetCameraParameter(req, quality, res);
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Size: %d, Quality: %d", res, quality);
|
||||
#endif
|
||||
Camera.SetQualitySize(quality, res);
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Size: %d, Quality: %d", res, quality);
|
||||
#endif
|
||||
|
||||
// wenn die Kameraeinstellungen durch Erstellen eines neuen Referenzbildes verändert wurden, müssen sie neu gesetzt werden
|
||||
if (CFstatus.changedCameraSettings)
|
||||
{
|
||||
Camera.setSensorDatenFromCCstatus(); // CCstatus >>> Kamera
|
||||
Camera.SetQualityZoomSize(CCstatus.ImageQuality, CCstatus.ImageFrameSize, CCstatus.ImageZoomEnabled, CCstatus.ImageZoomOffsetX, CCstatus.ImageZoomOffsetY, CCstatus.ImageZoomSize);
|
||||
CFstatus.changedCameraSettings = false;
|
||||
}
|
||||
|
||||
esp_err_t result;
|
||||
result = Camera.CaptureToFile(fn, delay);
|
||||
result = Camera.CaptureToFile(fn, delay);
|
||||
|
||||
const char* resp_str = (const char*) fn.c_str();
|
||||
const char *resp_str = (const char *)fn.c_str();
|
||||
httpd_resp_send(req, resp_str, strlen(resp_str));
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_capture_save_to_file - Done");
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_capture_save_to_file - Done");
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
httpd_resp_send_err(req, HTTPD_403_FORBIDDEN, "Camera not initialized: REST API /save not available!");
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void register_server_camera_uri(httpd_handle_t server)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGI(TAG, "server_part_camera - Registering URI handlers");
|
||||
#endif
|
||||
|
||||
httpd_uri_t camuri = { };
|
||||
camuri.method = HTTP_GET;
|
||||
httpd_uri_t camuri = {};
|
||||
camuri.method = HTTP_GET;
|
||||
|
||||
camuri.uri = "/lighton";
|
||||
camuri.handler = handler_lightOn;
|
||||
camuri.user_ctx = (void*) "Light On";
|
||||
camuri.uri = "/lighton";
|
||||
camuri.handler = handler_lightOn;
|
||||
camuri.user_ctx = (void *)"Light On";
|
||||
httpd_register_uri_handler(server, &camuri);
|
||||
|
||||
camuri.uri = "/lightoff";
|
||||
camuri.handler = handler_lightOff;
|
||||
camuri.user_ctx = (void*) "Light Off";
|
||||
httpd_register_uri_handler(server, &camuri);
|
||||
camuri.uri = "/lightoff";
|
||||
camuri.handler = handler_lightOff;
|
||||
camuri.user_ctx = (void *)"Light Off";
|
||||
httpd_register_uri_handler(server, &camuri);
|
||||
|
||||
camuri.uri = "/capture";
|
||||
camuri.handler = handler_capture;
|
||||
camuri.user_ctx = NULL;
|
||||
httpd_register_uri_handler(server, &camuri);
|
||||
camuri.uri = "/capture";
|
||||
camuri.handler = handler_capture;
|
||||
camuri.user_ctx = NULL;
|
||||
httpd_register_uri_handler(server, &camuri);
|
||||
|
||||
camuri.uri = "/capture_with_flashlight";
|
||||
camuri.handler = handler_capture_with_light;
|
||||
camuri.user_ctx = NULL;
|
||||
httpd_register_uri_handler(server, &camuri);
|
||||
camuri.uri = "/capture_with_flashlight";
|
||||
camuri.handler = handler_capture_with_light;
|
||||
camuri.user_ctx = NULL;
|
||||
httpd_register_uri_handler(server, &camuri);
|
||||
|
||||
camuri.uri = "/save";
|
||||
camuri.handler = handler_capture_save_to_file;
|
||||
camuri.user_ctx = NULL;
|
||||
httpd_register_uri_handler(server, &camuri);
|
||||
camuri.uri = "/save";
|
||||
camuri.handler = handler_capture_save_to_file;
|
||||
camuri.user_ctx = NULL;
|
||||
httpd_register_uri_handler(server, &camuri);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
//#include "ClassControllCamera.h"
|
||||
|
||||
void register_server_camera_uri(httpd_handle_t server);
|
||||
|
||||
void PowerResetCamera();
|
||||
|
||||
#endif
|
||||
@@ -1,393 +1,402 @@
|
||||
#include "ClassFlowAlignment.h"
|
||||
#include "ClassFlowTakeImage.h"
|
||||
#include "ClassFlow.h"
|
||||
#include "MainFlowControl.h"
|
||||
|
||||
#include "CRotateImage.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
|
||||
#include "ClassLogFile.h"
|
||||
#include "psram.h"
|
||||
#include "../../include/defines.h"
|
||||
|
||||
|
||||
static const char *TAG = "ALIGN";
|
||||
|
||||
// #define DEBUG_DETAIL_ON
|
||||
|
||||
|
||||
void ClassFlowAlignment::SetInitialParameter(void)
|
||||
{
|
||||
initalrotate = 0;
|
||||
anz_ref = 0;
|
||||
initialmirror = false;
|
||||
use_antialiasing = false;
|
||||
initialflip = false;
|
||||
SaveAllFiles = false;
|
||||
namerawimage = "/sdcard/img_tmp/raw.jpg";
|
||||
FileStoreRefAlignment = "/sdcard/config/align.txt";
|
||||
ListFlowControll = NULL;
|
||||
AlignAndCutImage = NULL;
|
||||
ImageBasis = NULL;
|
||||
ImageTMP = NULL;
|
||||
#ifdef ALGROI_LOAD_FROM_MEM_AS_JPG
|
||||
AlgROI = (ImageData*)malloc_psram_heap(std::string(TAG) + "->AlgROI", sizeof(ImageData), MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM);
|
||||
#endif
|
||||
previousElement = NULL;
|
||||
disabled = false;
|
||||
SAD_criteria = 0.05;
|
||||
}
|
||||
|
||||
|
||||
ClassFlowAlignment::ClassFlowAlignment(std::vector<ClassFlow*>* lfc)
|
||||
{
|
||||
SetInitialParameter();
|
||||
ListFlowControll = lfc;
|
||||
|
||||
for (int i = 0; i < ListFlowControll->size(); ++i)
|
||||
{
|
||||
if (((*ListFlowControll)[i])->name().compare("ClassFlowTakeImage") == 0)
|
||||
{
|
||||
ImageBasis = ((ClassFlowTakeImage*) (*ListFlowControll)[i])->rawImage;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ImageBasis) // the function take pictures does not exist --> must be created first ONLY FOR TEST PURPOSES
|
||||
{
|
||||
ESP_LOGD(TAG, "CImageBasis had to be created");
|
||||
ImageBasis = new CImageBasis("ImageBasis", namerawimage);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool ClassFlowAlignment::ReadParameter(FILE* pfile, string& aktparamgraph)
|
||||
{
|
||||
std::vector<string> splitted;
|
||||
int suchex = 40;
|
||||
int suchey = 40;
|
||||
int alg_algo = 0; //default=0; 1 =HIGHACCURACY; 2= FAST; 3= OFF //add disable aligment algo |01.2023
|
||||
|
||||
|
||||
aktparamgraph = trim(aktparamgraph);
|
||||
|
||||
if (aktparamgraph.size() == 0)
|
||||
if (!this->GetNextParagraph(pfile, aktparamgraph))
|
||||
return false;
|
||||
|
||||
if (aktparamgraph.compare("[Alignment]") != 0) //Paragraph does not fit Alignment
|
||||
return false;
|
||||
|
||||
while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph))
|
||||
{
|
||||
splitted = ZerlegeZeile(aktparamgraph);
|
||||
if ((toUpper(splitted[0]) == "FLIPIMAGESIZE") && (splitted.size() > 1))
|
||||
{
|
||||
if (toUpper(splitted[1]) == "TRUE")
|
||||
initialflip = true;
|
||||
}
|
||||
if ((toUpper(splitted[0]) == "INITIALMIRROR") && (splitted.size() > 1))
|
||||
{
|
||||
if (toUpper(splitted[1]) == "TRUE")
|
||||
initialmirror = true;
|
||||
}
|
||||
if (((toUpper(splitted[0]) == "INITALROTATE") || (toUpper(splitted[0]) == "INITIALROTATE")) && (splitted.size() > 1))
|
||||
{
|
||||
this->initalrotate = std::stod(splitted[1]);
|
||||
}
|
||||
if ((toUpper(splitted[0]) == "SEARCHFIELDX") && (splitted.size() > 1))
|
||||
{
|
||||
suchex = std::stod(splitted[1]);
|
||||
}
|
||||
if ((toUpper(splitted[0]) == "SEARCHFIELDY") && (splitted.size() > 1))
|
||||
{
|
||||
suchey = std::stod(splitted[1]);
|
||||
}
|
||||
if ((toUpper(splitted[0]) == "ANTIALIASING") && (splitted.size() > 1))
|
||||
{
|
||||
if (toUpper(splitted[1]) == "TRUE")
|
||||
use_antialiasing = true;
|
||||
}
|
||||
if ((splitted.size() == 3) && (anz_ref < 2))
|
||||
{
|
||||
References[anz_ref].image_file = FormatFileName("/sdcard" + splitted[0]);
|
||||
References[anz_ref].target_x = std::stod(splitted[1]);
|
||||
References[anz_ref].target_y = std::stod(splitted[2]);
|
||||
anz_ref++;
|
||||
}
|
||||
|
||||
if ((toUpper(splitted[0]) == "SAVEALLFILES") && (splitted.size() > 1))
|
||||
{
|
||||
if (toUpper(splitted[1]) == "TRUE")
|
||||
SaveAllFiles = true;
|
||||
}
|
||||
if ((toUpper(splitted[0]) == "ALIGNMENTALGO") && (splitted.size() > 1))
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
std::string zw2 = "Alignment mode selected: " + splitted[1];
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, zw2);
|
||||
#endif
|
||||
if (toUpper(splitted[1]) == "HIGHACCURACY")
|
||||
alg_algo = 1;
|
||||
if (toUpper(splitted[1]) == "FAST")
|
||||
alg_algo = 2;
|
||||
if (toUpper(splitted[1]) == "OFF") //no align algo if set to 3 = off => no draw ref //add disable aligment algo |01.2023
|
||||
alg_algo = 3;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < anz_ref; ++i)
|
||||
{
|
||||
References[i].search_x = suchex;
|
||||
References[i].search_y = suchey;
|
||||
References[i].fastalg_SAD_criteria = SAD_criteria;
|
||||
References[i].alignment_algo = alg_algo;
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
std::string zw2 = "Alignment mode written: " + std::to_string(alg_algo);
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, zw2);
|
||||
#endif
|
||||
}
|
||||
|
||||
//no align algo if set to 3 = off => no draw ref //add disable aligment algo |01.2023
|
||||
if(References[0].alignment_algo != 3){
|
||||
LoadReferenceAlignmentValues();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
string ClassFlowAlignment::getHTMLSingleStep(string host)
|
||||
{
|
||||
string result;
|
||||
|
||||
result = "<p>Rotated Image: </p> <p><img src=\"" + host + "/img_tmp/rot.jpg\"></p>\n";
|
||||
result = result + "<p>Found Alignment: </p> <p><img src=\"" + host + "/img_tmp/rot_roi.jpg\"></p>\n";
|
||||
result = result + "<p>Aligned Image: </p> <p><img src=\"" + host + "/img_tmp/alg.jpg\"></p>\n";
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
bool ClassFlowAlignment::doFlow(string time)
|
||||
{
|
||||
#ifdef ALGROI_LOAD_FROM_MEM_AS_JPG
|
||||
if (!AlgROI) // AlgROI needs to be allocated before ImageTMP to avoid heap fragmentation
|
||||
{
|
||||
AlgROI = (ImageData*)heap_caps_realloc(AlgROI, sizeof(ImageData), MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM);
|
||||
if (!AlgROI)
|
||||
{
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Can't allocate AlgROI");
|
||||
LogFile.WriteHeapInfo("ClassFlowAlignment-doFlow");
|
||||
}
|
||||
}
|
||||
|
||||
if (AlgROI)
|
||||
{
|
||||
ImageBasis->writeToMemoryAsJPG((ImageData*)AlgROI, 90);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!ImageTMP)
|
||||
{
|
||||
ImageTMP = new CImageBasis("tmpImage", ImageBasis); // Make sure the name does not get change, it is relevant for the PSRAM allocation!
|
||||
if (!ImageTMP)
|
||||
{
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Can't allocate tmpImage -> Exec this round aborted!");
|
||||
LogFile.WriteHeapInfo("ClassFlowAlignment-doFlow");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
delete AlignAndCutImage;
|
||||
AlignAndCutImage = new CAlignAndCutImage("AlignAndCutImage", ImageBasis, ImageTMP);
|
||||
if (!AlignAndCutImage)
|
||||
{
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Can't allocate AlignAndCutImage -> Exec this round aborted!");
|
||||
LogFile.WriteHeapInfo("ClassFlowAlignment-doFlow");
|
||||
return false;
|
||||
}
|
||||
|
||||
CRotateImage rt("rawImage", AlignAndCutImage, ImageTMP, initialflip);
|
||||
if (initialflip)
|
||||
{
|
||||
int _zw = ImageBasis->height;
|
||||
ImageBasis->height = ImageBasis->width;
|
||||
ImageBasis->width = _zw;
|
||||
|
||||
_zw = ImageTMP->width;
|
||||
ImageTMP->width = ImageTMP->height;
|
||||
ImageTMP->height = _zw;
|
||||
}
|
||||
|
||||
if (initialmirror)
|
||||
{
|
||||
ESP_LOGD(TAG, "do mirror");
|
||||
rt.Mirror();
|
||||
|
||||
if (SaveAllFiles)
|
||||
AlignAndCutImage->SaveToFile(FormatFileName("/sdcard/img_tmp/mirror.jpg"));
|
||||
}
|
||||
|
||||
if ((initalrotate != 0) || initialflip)
|
||||
{
|
||||
if (use_antialiasing)
|
||||
rt.RotateAntiAliasing(initalrotate);
|
||||
else
|
||||
rt.Rotate(initalrotate);
|
||||
|
||||
if (SaveAllFiles)
|
||||
AlignAndCutImage->SaveToFile(FormatFileName("/sdcard/img_tmp/rot.jpg"));
|
||||
}
|
||||
|
||||
|
||||
//no align algo if set to 3 = off //add disable aligment algo |01.2023
|
||||
if(References[0].alignment_algo != 3){
|
||||
if (!AlignAndCutImage->Align(&References[0], &References[1]))
|
||||
{
|
||||
SaveReferenceAlignmentValues();
|
||||
}
|
||||
}// no align
|
||||
|
||||
|
||||
#ifdef ALGROI_LOAD_FROM_MEM_AS_JPG
|
||||
if (AlgROI) {
|
||||
//no align algo if set to 3 = off => no draw ref //add disable aligment algo |01.2023
|
||||
if(References[0].alignment_algo != 3){
|
||||
DrawRef(ImageTMP);
|
||||
}
|
||||
flowctrl.DigitalDrawROI(ImageTMP);
|
||||
flowctrl.AnalogDrawROI(ImageTMP);
|
||||
ImageTMP->writeToMemoryAsJPG((ImageData*)AlgROI, 90);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (SaveAllFiles)
|
||||
{
|
||||
AlignAndCutImage->SaveToFile(FormatFileName("/sdcard/img_tmp/alg.jpg"));
|
||||
ImageTMP->SaveToFile(FormatFileName("/sdcard/img_tmp/alg_roi.jpg"));
|
||||
}
|
||||
|
||||
// must be deleted to have memory space for loading tflite
|
||||
delete ImageTMP;
|
||||
ImageTMP = NULL;
|
||||
|
||||
//no align algo if set to 3 = off => no draw ref //add disable aligment algo |01.2023
|
||||
if(References[0].alignment_algo != 3){
|
||||
LoadReferenceAlignmentValues();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void ClassFlowAlignment::SaveReferenceAlignmentValues()
|
||||
{
|
||||
FILE* pFile;
|
||||
std::string zwtime, zwvalue;
|
||||
|
||||
pFile = fopen(FileStoreRefAlignment.c_str(), "w");
|
||||
|
||||
if (strlen(zwtime.c_str()) == 0)
|
||||
{
|
||||
time_t rawtime;
|
||||
struct tm* timeinfo;
|
||||
char buffer[80];
|
||||
|
||||
time(&rawtime);
|
||||
timeinfo = localtime(&rawtime);
|
||||
|
||||
strftime(buffer, 80, "%Y-%m-%dT%H:%M:%S", timeinfo);
|
||||
zwtime = std::string(buffer);
|
||||
}
|
||||
|
||||
fputs(zwtime.c_str(), pFile);
|
||||
fputs("\n", pFile);
|
||||
|
||||
zwvalue = std::to_string(References[0].fastalg_x) + "\t" + std::to_string(References[0].fastalg_y);
|
||||
zwvalue = zwvalue + "\t" +std::to_string(References[0].fastalg_SAD)+ "\t" +std::to_string(References[0].fastalg_min);
|
||||
zwvalue = zwvalue + "\t" +std::to_string(References[0].fastalg_max)+ "\t" +std::to_string(References[0].fastalg_avg);
|
||||
fputs(zwvalue.c_str(), pFile);
|
||||
fputs("\n", pFile);
|
||||
|
||||
zwvalue = std::to_string(References[1].fastalg_x) + "\t" + std::to_string(References[1].fastalg_y);
|
||||
zwvalue = zwvalue + "\t" +std::to_string(References[1].fastalg_SAD)+ "\t" +std::to_string(References[1].fastalg_min);
|
||||
zwvalue = zwvalue + "\t" +std::to_string(References[1].fastalg_max)+ "\t" +std::to_string(References[1].fastalg_avg);
|
||||
fputs(zwvalue.c_str(), pFile);
|
||||
fputs("\n", pFile);
|
||||
|
||||
fclose(pFile);
|
||||
}
|
||||
|
||||
|
||||
bool ClassFlowAlignment::LoadReferenceAlignmentValues(void)
|
||||
{
|
||||
FILE* pFile;
|
||||
char zw[1024];
|
||||
string zwvalue;
|
||||
std::vector<string> splitted;
|
||||
|
||||
|
||||
pFile = fopen(FileStoreRefAlignment.c_str(), "r");
|
||||
if (pFile == NULL)
|
||||
return false;
|
||||
|
||||
fgets(zw, 1024, pFile);
|
||||
ESP_LOGD(TAG, "%s", zw);
|
||||
|
||||
fgets(zw, 1024, pFile);
|
||||
splitted = ZerlegeZeile(std::string(zw), " \t");
|
||||
if (splitted.size() < 6)
|
||||
{
|
||||
fclose(pFile);
|
||||
return false;
|
||||
}
|
||||
|
||||
References[0].fastalg_x = stoi(splitted[0]);
|
||||
References[0].fastalg_y = stoi(splitted[1]);
|
||||
References[0].fastalg_SAD = stof(splitted[2]);
|
||||
References[0].fastalg_min = stoi(splitted[3]);
|
||||
References[0].fastalg_max = stoi(splitted[4]);
|
||||
References[0].fastalg_avg = stof(splitted[5]);
|
||||
|
||||
fgets(zw, 1024, pFile);
|
||||
splitted = ZerlegeZeile(std::string(zw));
|
||||
if (splitted.size() < 6)
|
||||
{
|
||||
fclose(pFile);
|
||||
return false;
|
||||
}
|
||||
|
||||
References[1].fastalg_x = stoi(splitted[0]);
|
||||
References[1].fastalg_y = stoi(splitted[1]);
|
||||
References[1].fastalg_SAD = stof(splitted[2]);
|
||||
References[1].fastalg_min = stoi(splitted[3]);
|
||||
References[1].fastalg_max = stoi(splitted[4]);
|
||||
References[1].fastalg_avg = stof(splitted[5]);
|
||||
|
||||
fclose(pFile);
|
||||
|
||||
|
||||
/*#ifdef DEBUG_DETAIL_ON
|
||||
std::string _zw = "\tLoadReferences[0]\tx,y:\t" + std::to_string(References[0].fastalg_x) + "\t" + std::to_string(References[0].fastalg_x);
|
||||
_zw = _zw + "\tSAD, min, max, avg:\t" + std::to_string(References[0].fastalg_SAD) + "\t" + std::to_string(References[0].fastalg_min);
|
||||
_zw = _zw + "\t" + std::to_string(References[0].fastalg_max) + "\t" + std::to_string(References[0].fastalg_avg);
|
||||
LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", _zw);
|
||||
_zw = "\tLoadReferences[1]\tx,y:\t" + std::to_string(References[1].fastalg_x) + "\t" + std::to_string(References[1].fastalg_x);
|
||||
_zw = _zw + "\tSAD, min, max, avg:\t" + std::to_string(References[1].fastalg_SAD) + "\t" + std::to_string(References[1].fastalg_min);
|
||||
_zw = _zw + "\t" + std::to_string(References[1].fastalg_max) + "\t" + std::to_string(References[1].fastalg_avg);
|
||||
LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", _zw);
|
||||
#endif*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void ClassFlowAlignment::DrawRef(CImageBasis *_zw)
|
||||
{
|
||||
if (_zw->ImageOkay())
|
||||
{
|
||||
_zw->drawRect(References[0].target_x, References[0].target_y, References[0].width, References[0].height, 255, 0, 0, 2);
|
||||
_zw->drawRect(References[1].target_x, References[1].target_y, References[1].width, References[1].height, 255, 0, 0, 2);
|
||||
}
|
||||
}
|
||||
#include "ClassFlowAlignment.h"
|
||||
#include "ClassFlowTakeImage.h"
|
||||
#include "ClassFlow.h"
|
||||
#include "MainFlowControl.h"
|
||||
|
||||
#include "CRotateImage.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "ClassLogFile.h"
|
||||
#include "psram.h"
|
||||
#include "../../include/defines.h"
|
||||
|
||||
static const char *TAG = "ALIGN";
|
||||
|
||||
// #define DEBUG_DETAIL_ON
|
||||
|
||||
void ClassFlowAlignment::SetInitialParameter(void)
|
||||
{
|
||||
initialrotate = 0;
|
||||
anz_ref = 0;
|
||||
use_antialiasing = false;
|
||||
initialflip = false;
|
||||
SaveAllFiles = false;
|
||||
namerawimage = "/sdcard/img_tmp/raw.jpg";
|
||||
FileStoreRefAlignment = "/sdcard/config/align.txt";
|
||||
ListFlowControll = NULL;
|
||||
AlignAndCutImage = NULL;
|
||||
ImageBasis = NULL;
|
||||
ImageTMP = NULL;
|
||||
#ifdef ALGROI_LOAD_FROM_MEM_AS_JPG
|
||||
AlgROI = (ImageData *)malloc_psram_heap(std::string(TAG) + "->AlgROI", sizeof(ImageData), MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM);
|
||||
#endif
|
||||
previousElement = NULL;
|
||||
disabled = false;
|
||||
SAD_criteria = 0.05;
|
||||
}
|
||||
|
||||
ClassFlowAlignment::ClassFlowAlignment(std::vector<ClassFlow *> *lfc)
|
||||
{
|
||||
SetInitialParameter();
|
||||
ListFlowControll = lfc;
|
||||
|
||||
for (int i = 0; i < ListFlowControll->size(); ++i)
|
||||
{
|
||||
if (((*ListFlowControll)[i])->name().compare("ClassFlowTakeImage") == 0)
|
||||
{
|
||||
ImageBasis = ((ClassFlowTakeImage *)(*ListFlowControll)[i])->rawImage;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ImageBasis) // the function take pictures does not exist --> must be created first ONLY FOR TEST PURPOSES
|
||||
{
|
||||
ESP_LOGD(TAG, "CImageBasis had to be created");
|
||||
ImageBasis = new CImageBasis("ImageBasis", namerawimage);
|
||||
}
|
||||
}
|
||||
|
||||
bool ClassFlowAlignment::ReadParameter(FILE *pfile, string &aktparamgraph)
|
||||
{
|
||||
std::vector<string> splitted;
|
||||
int suchex = 40;
|
||||
int suchey = 40;
|
||||
int alg_algo = 0; // default=0; 1 =HIGHACCURACY; 2= FAST; 3= OFF //add disable aligment algo |01.2023
|
||||
|
||||
aktparamgraph = trim(aktparamgraph);
|
||||
|
||||
if (aktparamgraph.size() == 0)
|
||||
{
|
||||
if (!this->GetNextParagraph(pfile, aktparamgraph))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (aktparamgraph.compare("[Alignment]") != 0)
|
||||
{
|
||||
// Paragraph does not fit Alignment
|
||||
return false;
|
||||
}
|
||||
|
||||
while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph))
|
||||
{
|
||||
splitted = ZerlegeZeile(aktparamgraph);
|
||||
|
||||
if ((toUpper(splitted[0]) == "FLIPIMAGESIZE") && (splitted.size() > 1))
|
||||
{
|
||||
if (toUpper(splitted[1]) == "TRUE")
|
||||
{
|
||||
initialflip = true;
|
||||
}
|
||||
}
|
||||
else if (((toUpper(splitted[0]) == "initialrotate") || (toUpper(splitted[0]) == "INITIALROTATE")) && (splitted.size() > 1))
|
||||
{
|
||||
this->initialrotate = std::stod(splitted[1]);
|
||||
}
|
||||
else if ((toUpper(splitted[0]) == "SEARCHFIELDX") && (splitted.size() > 1))
|
||||
{
|
||||
suchex = std::stod(splitted[1]);
|
||||
}
|
||||
else if ((toUpper(splitted[0]) == "SEARCHFIELDY") && (splitted.size() > 1))
|
||||
{
|
||||
suchey = std::stod(splitted[1]);
|
||||
}
|
||||
else if ((toUpper(splitted[0]) == "ANTIALIASING") && (splitted.size() > 1))
|
||||
{
|
||||
if (toUpper(splitted[1]) == "TRUE")
|
||||
{
|
||||
use_antialiasing = true;
|
||||
}
|
||||
}
|
||||
else if ((splitted.size() == 3) && (anz_ref < 2))
|
||||
{
|
||||
References[anz_ref].image_file = FormatFileName("/sdcard" + splitted[0]);
|
||||
References[anz_ref].target_x = std::stod(splitted[1]);
|
||||
References[anz_ref].target_y = std::stod(splitted[2]);
|
||||
anz_ref++;
|
||||
}
|
||||
|
||||
else if ((toUpper(splitted[0]) == "SAVEALLFILES") && (splitted.size() > 1))
|
||||
{
|
||||
if (toUpper(splitted[1]) == "TRUE")
|
||||
{
|
||||
SaveAllFiles = true;
|
||||
}
|
||||
}
|
||||
else if ((toUpper(splitted[0]) == "ALIGNMENTALGO") && (splitted.size() > 1))
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
std::string zw2 = "Alignment mode selected: " + splitted[1];
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, zw2);
|
||||
#endif
|
||||
if (toUpper(splitted[1]) == "HIGHACCURACY")
|
||||
{
|
||||
alg_algo = 1;
|
||||
}
|
||||
if (toUpper(splitted[1]) == "FAST")
|
||||
{
|
||||
alg_algo = 2;
|
||||
}
|
||||
if (toUpper(splitted[1]) == "OFF")
|
||||
{
|
||||
// no align algo if set to 3 = off => no draw ref //add disable aligment algo |01.2023
|
||||
alg_algo = 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < anz_ref; ++i)
|
||||
{
|
||||
References[i].search_x = suchex;
|
||||
References[i].search_y = suchey;
|
||||
References[i].fastalg_SAD_criteria = SAD_criteria;
|
||||
References[i].alignment_algo = alg_algo;
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
std::string zw2 = "Alignment mode written: " + std::to_string(alg_algo);
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, zw2);
|
||||
#endif
|
||||
}
|
||||
|
||||
// no align algo if set to 3 = off => no draw ref //add disable aligment algo |01.2023
|
||||
if (References[0].alignment_algo != 3)
|
||||
{
|
||||
LoadReferenceAlignmentValues();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
string ClassFlowAlignment::getHTMLSingleStep(string host)
|
||||
{
|
||||
string result;
|
||||
|
||||
result = "<p>Rotated Image: </p> <p><img src=\"" + host + "/img_tmp/rot.jpg\"></p>\n";
|
||||
result = result + "<p>Found Alignment: </p> <p><img src=\"" + host + "/img_tmp/rot_roi.jpg\"></p>\n";
|
||||
result = result + "<p>Aligned Image: </p> <p><img src=\"" + host + "/img_tmp/alg.jpg\"></p>\n";
|
||||
return result;
|
||||
}
|
||||
|
||||
bool ClassFlowAlignment::doFlow(string time)
|
||||
{
|
||||
#ifdef ALGROI_LOAD_FROM_MEM_AS_JPG
|
||||
if (!AlgROI) // AlgROI needs to be allocated before ImageTMP to avoid heap fragmentation
|
||||
{
|
||||
AlgROI = (ImageData *)heap_caps_realloc(AlgROI, sizeof(ImageData), MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM);
|
||||
|
||||
if (!AlgROI)
|
||||
{
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Can't allocate AlgROI");
|
||||
LogFile.WriteHeapInfo("ClassFlowAlignment-doFlow");
|
||||
}
|
||||
}
|
||||
|
||||
if (AlgROI)
|
||||
{
|
||||
ImageBasis->writeToMemoryAsJPG((ImageData *)AlgROI, 90);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!ImageTMP)
|
||||
{
|
||||
ImageTMP = new CImageBasis("tmpImage", ImageBasis); // Make sure the name does not get change, it is relevant for the PSRAM allocation!
|
||||
|
||||
if (!ImageTMP)
|
||||
{
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Can't allocate tmpImage -> Exec this round aborted!");
|
||||
LogFile.WriteHeapInfo("ClassFlowAlignment-doFlow");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
delete AlignAndCutImage;
|
||||
AlignAndCutImage = new CAlignAndCutImage("AlignAndCutImage", ImageBasis, ImageTMP);
|
||||
|
||||
if (!AlignAndCutImage)
|
||||
{
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Can't allocate AlignAndCutImage -> Exec this round aborted!");
|
||||
LogFile.WriteHeapInfo("ClassFlowAlignment-doFlow");
|
||||
return false;
|
||||
}
|
||||
|
||||
CRotateImage rt("rawImage", AlignAndCutImage, ImageTMP, initialflip);
|
||||
|
||||
if (initialflip)
|
||||
{
|
||||
int _zw = ImageBasis->height;
|
||||
ImageBasis->height = ImageBasis->width;
|
||||
ImageBasis->width = _zw;
|
||||
|
||||
_zw = ImageTMP->width;
|
||||
ImageTMP->width = ImageTMP->height;
|
||||
ImageTMP->height = _zw;
|
||||
}
|
||||
|
||||
if ((initialrotate != 0) || initialflip)
|
||||
{
|
||||
if (use_antialiasing)
|
||||
{
|
||||
rt.RotateAntiAliasing(initialrotate);
|
||||
}
|
||||
else
|
||||
{
|
||||
rt.Rotate(initialrotate);
|
||||
}
|
||||
|
||||
if (SaveAllFiles)
|
||||
{
|
||||
AlignAndCutImage->SaveToFile(FormatFileName("/sdcard/img_tmp/rot.jpg"));
|
||||
}
|
||||
}
|
||||
|
||||
// no align algo if set to 3 = off //add disable aligment algo |01.2023
|
||||
if (References[0].alignment_algo != 3)
|
||||
{
|
||||
if (!AlignAndCutImage->Align(&References[0], &References[1]))
|
||||
{
|
||||
SaveReferenceAlignmentValues();
|
||||
}
|
||||
} // no align
|
||||
|
||||
#ifdef ALGROI_LOAD_FROM_MEM_AS_JPG
|
||||
if (AlgROI)
|
||||
{
|
||||
// no align algo if set to 3 = off => no draw ref //add disable aligment algo |01.2023
|
||||
if (References[0].alignment_algo != 3)
|
||||
{
|
||||
DrawRef(ImageTMP);
|
||||
}
|
||||
|
||||
flowctrl.DigitalDrawROI(ImageTMP);
|
||||
flowctrl.AnalogDrawROI(ImageTMP);
|
||||
ImageTMP->writeToMemoryAsJPG((ImageData *)AlgROI, 90);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (SaveAllFiles)
|
||||
{
|
||||
AlignAndCutImage->SaveToFile(FormatFileName("/sdcard/img_tmp/alg.jpg"));
|
||||
ImageTMP->SaveToFile(FormatFileName("/sdcard/img_tmp/alg_roi.jpg"));
|
||||
}
|
||||
|
||||
// must be deleted to have memory space for loading tflite
|
||||
delete ImageTMP;
|
||||
ImageTMP = NULL;
|
||||
|
||||
// no align algo if set to 3 = off => no draw ref //add disable aligment algo |01.2023
|
||||
if (References[0].alignment_algo != 3)
|
||||
{
|
||||
LoadReferenceAlignmentValues();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ClassFlowAlignment::SaveReferenceAlignmentValues()
|
||||
{
|
||||
FILE *pFile;
|
||||
std::string zwtime, zwvalue;
|
||||
|
||||
pFile = fopen(FileStoreRefAlignment.c_str(), "w");
|
||||
|
||||
if (strlen(zwtime.c_str()) == 0)
|
||||
{
|
||||
time_t rawtime;
|
||||
struct tm *timeinfo;
|
||||
char buffer[80];
|
||||
|
||||
time(&rawtime);
|
||||
timeinfo = localtime(&rawtime);
|
||||
|
||||
strftime(buffer, 80, "%Y-%m-%dT%H:%M:%S", timeinfo);
|
||||
zwtime = std::string(buffer);
|
||||
}
|
||||
|
||||
fputs(zwtime.c_str(), pFile);
|
||||
fputs("\n", pFile);
|
||||
|
||||
zwvalue = std::to_string(References[0].fastalg_x) + "\t" + std::to_string(References[0].fastalg_y);
|
||||
zwvalue = zwvalue + "\t" + std::to_string(References[0].fastalg_SAD) + "\t" + std::to_string(References[0].fastalg_min);
|
||||
zwvalue = zwvalue + "\t" + std::to_string(References[0].fastalg_max) + "\t" + std::to_string(References[0].fastalg_avg);
|
||||
fputs(zwvalue.c_str(), pFile);
|
||||
fputs("\n", pFile);
|
||||
|
||||
zwvalue = std::to_string(References[1].fastalg_x) + "\t" + std::to_string(References[1].fastalg_y);
|
||||
zwvalue = zwvalue + "\t" + std::to_string(References[1].fastalg_SAD) + "\t" + std::to_string(References[1].fastalg_min);
|
||||
zwvalue = zwvalue + "\t" + std::to_string(References[1].fastalg_max) + "\t" + std::to_string(References[1].fastalg_avg);
|
||||
fputs(zwvalue.c_str(), pFile);
|
||||
fputs("\n", pFile);
|
||||
|
||||
fclose(pFile);
|
||||
}
|
||||
|
||||
bool ClassFlowAlignment::LoadReferenceAlignmentValues(void)
|
||||
{
|
||||
FILE *pFile;
|
||||
char zw[1024];
|
||||
string zwvalue;
|
||||
std::vector<string> splitted;
|
||||
|
||||
pFile = fopen(FileStoreRefAlignment.c_str(), "r");
|
||||
|
||||
if (pFile == NULL)
|
||||
return false;
|
||||
|
||||
fgets(zw, 1024, pFile);
|
||||
ESP_LOGD(TAG, "%s", zw);
|
||||
|
||||
fgets(zw, 1024, pFile);
|
||||
splitted = ZerlegeZeile(std::string(zw), " \t");
|
||||
|
||||
if (splitted.size() < 6)
|
||||
{
|
||||
fclose(pFile);
|
||||
return false;
|
||||
}
|
||||
|
||||
References[0].fastalg_x = stoi(splitted[0]);
|
||||
References[0].fastalg_y = stoi(splitted[1]);
|
||||
References[0].fastalg_SAD = stof(splitted[2]);
|
||||
References[0].fastalg_min = stoi(splitted[3]);
|
||||
References[0].fastalg_max = stoi(splitted[4]);
|
||||
References[0].fastalg_avg = stof(splitted[5]);
|
||||
|
||||
fgets(zw, 1024, pFile);
|
||||
splitted = ZerlegeZeile(std::string(zw));
|
||||
|
||||
if (splitted.size() < 6)
|
||||
{
|
||||
fclose(pFile);
|
||||
return false;
|
||||
}
|
||||
|
||||
References[1].fastalg_x = stoi(splitted[0]);
|
||||
References[1].fastalg_y = stoi(splitted[1]);
|
||||
References[1].fastalg_SAD = stof(splitted[2]);
|
||||
References[1].fastalg_min = stoi(splitted[3]);
|
||||
References[1].fastalg_max = stoi(splitted[4]);
|
||||
References[1].fastalg_avg = stof(splitted[5]);
|
||||
|
||||
fclose(pFile);
|
||||
|
||||
/*#ifdef DEBUG_DETAIL_ON
|
||||
std::string _zw = "\tLoadReferences[0]\tx,y:\t" + std::to_string(References[0].fastalg_x) + "\t" + std::to_string(References[0].fastalg_x);
|
||||
_zw = _zw + "\tSAD, min, max, avg:\t" + std::to_string(References[0].fastalg_SAD) + "\t" + std::to_string(References[0].fastalg_min);
|
||||
_zw = _zw + "\t" + std::to_string(References[0].fastalg_max) + "\t" + std::to_string(References[0].fastalg_avg);
|
||||
LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", _zw);
|
||||
_zw = "\tLoadReferences[1]\tx,y:\t" + std::to_string(References[1].fastalg_x) + "\t" + std::to_string(References[1].fastalg_x);
|
||||
_zw = _zw + "\tSAD, min, max, avg:\t" + std::to_string(References[1].fastalg_SAD) + "\t" + std::to_string(References[1].fastalg_min);
|
||||
_zw = _zw + "\t" + std::to_string(References[1].fastalg_max) + "\t" + std::to_string(References[1].fastalg_avg);
|
||||
LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", _zw);
|
||||
#endif*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ClassFlowAlignment::DrawRef(CImageBasis *_zw)
|
||||
{
|
||||
if (_zw->ImageOkay())
|
||||
{
|
||||
_zw->drawRect(References[0].target_x, References[0].target_y, References[0].width, References[0].height, 255, 0, 0, 2);
|
||||
_zw->drawRect(References[1].target_x, References[1].target_y, References[1].width, References[1].height, 255, 0, 0, 2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,54 +1,51 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef CLASSFLOWALIGNMENT_H
|
||||
#define CLASSFLOWALIGNMENT_H
|
||||
|
||||
#include "ClassFlow.h"
|
||||
#include "Helper.h"
|
||||
#include "CAlignAndCutImage.h"
|
||||
#include "CFindTemplate.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class ClassFlowAlignment :
|
||||
public ClassFlow
|
||||
{
|
||||
protected:
|
||||
float initalrotate;
|
||||
bool initialmirror;
|
||||
bool initialflip;
|
||||
bool use_antialiasing;
|
||||
RefInfo References[2];
|
||||
int anz_ref;
|
||||
string namerawimage;
|
||||
bool SaveAllFiles;
|
||||
CAlignAndCutImage *AlignAndCutImage;
|
||||
std::string FileStoreRefAlignment;
|
||||
float SAD_criteria;
|
||||
|
||||
void SetInitialParameter(void);
|
||||
bool LoadReferenceAlignmentValues(void);
|
||||
void SaveReferenceAlignmentValues();
|
||||
|
||||
public:
|
||||
CImageBasis *ImageBasis, *ImageTMP;
|
||||
#ifdef ALGROI_LOAD_FROM_MEM_AS_JPG
|
||||
ImageData *AlgROI;
|
||||
#endif
|
||||
|
||||
ClassFlowAlignment(std::vector<ClassFlow*>* lfc);
|
||||
|
||||
CAlignAndCutImage* GetAlignAndCutImage(){return AlignAndCutImage;};
|
||||
|
||||
void DrawRef(CImageBasis *_zw);
|
||||
|
||||
bool ReadParameter(FILE* pfile, string& aktparamgraph);
|
||||
bool doFlow(string time);
|
||||
string getHTMLSingleStep(string host);
|
||||
string name(){return "ClassFlowAlignment";};
|
||||
};
|
||||
|
||||
|
||||
#endif //CLASSFLOWALIGNMENT_H
|
||||
#pragma once
|
||||
|
||||
#ifndef CLASSFLOWALIGNMENT_H
|
||||
#define CLASSFLOWALIGNMENT_H
|
||||
|
||||
#include "ClassFlow.h"
|
||||
#include "Helper.h"
|
||||
#include "CAlignAndCutImage.h"
|
||||
#include "CFindTemplate.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class ClassFlowAlignment : public ClassFlow
|
||||
{
|
||||
protected:
|
||||
float initialrotate;
|
||||
bool initialflip;
|
||||
bool use_antialiasing;
|
||||
RefInfo References[2];
|
||||
int anz_ref;
|
||||
string namerawimage;
|
||||
bool SaveAllFiles;
|
||||
CAlignAndCutImage *AlignAndCutImage;
|
||||
std::string FileStoreRefAlignment;
|
||||
float SAD_criteria;
|
||||
|
||||
void SetInitialParameter(void);
|
||||
bool LoadReferenceAlignmentValues(void);
|
||||
void SaveReferenceAlignmentValues();
|
||||
|
||||
public:
|
||||
CImageBasis *ImageBasis, *ImageTMP;
|
||||
#ifdef ALGROI_LOAD_FROM_MEM_AS_JPG
|
||||
ImageData *AlgROI;
|
||||
#endif
|
||||
|
||||
ClassFlowAlignment(std::vector<ClassFlow *> *lfc);
|
||||
|
||||
CAlignAndCutImage *GetAlignAndCutImage() { return AlignAndCutImage; };
|
||||
|
||||
void DrawRef(CImageBasis *_zw);
|
||||
|
||||
bool ReadParameter(FILE *pfile, string &aktparamgraph);
|
||||
bool doFlow(string time);
|
||||
string getHTMLSingleStep(string host);
|
||||
string name() { return "ClassFlowAlignment"; };
|
||||
};
|
||||
|
||||
#endif // CLASSFLOWALIGNMENT_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,15 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <regex>
|
||||
|
||||
#include "ClassFlowTakeImage.h"
|
||||
#include "Helper.h"
|
||||
#include "ClassLogFile.h"
|
||||
|
||||
#include "CImageBasis.h"
|
||||
#include "ClassControllCamera.h"
|
||||
#include "MainFlowControl.h"
|
||||
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_log.h"
|
||||
@@ -12,14 +18,14 @@
|
||||
|
||||
#include <time.h>
|
||||
|
||||
// #define DEBUG_DETAIL_ON
|
||||
|
||||
// #define DEBUG_DETAIL_ON
|
||||
// #define WIFITURNOFF
|
||||
|
||||
static const char* TAG = "TAKEIMAGE";
|
||||
static const char *TAG = "TAKEIMAGE";
|
||||
|
||||
esp_err_t ClassFlowTakeImage::camera_capture(){
|
||||
string nm = namerawimage;
|
||||
esp_err_t ClassFlowTakeImage::camera_capture(void)
|
||||
{
|
||||
string nm = namerawimage;
|
||||
Camera.CaptureToFile(nm);
|
||||
time(&TimeImageTaken);
|
||||
localtime(&TimeImageTaken);
|
||||
@@ -30,150 +36,480 @@ esp_err_t ClassFlowTakeImage::camera_capture(){
|
||||
void ClassFlowTakeImage::takePictureWithFlash(int flash_duration)
|
||||
{
|
||||
// in case the image is flipped, it must be reset here //
|
||||
rawImage->width = image_width;
|
||||
rawImage->height = image_height;
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
rawImage->width = CCstatus.ImageWidth;
|
||||
rawImage->height = CCstatus.ImageHeight;
|
||||
|
||||
ESP_LOGD(TAG, "flash_duration: %d", flash_duration);
|
||||
|
||||
Camera.CaptureToBasisImage(rawImage, flash_duration);
|
||||
|
||||
time(&TimeImageTaken);
|
||||
localtime(&TimeImageTaken);
|
||||
|
||||
if (SaveAllFiles) rawImage->SaveToFile(namerawimage);
|
||||
if (CCstatus.SaveAllFiles)
|
||||
{
|
||||
rawImage->SaveToFile(namerawimage);
|
||||
}
|
||||
}
|
||||
|
||||
void ClassFlowTakeImage::SetInitialParameter(void)
|
||||
{
|
||||
waitbeforepicture = 5;
|
||||
isImageSize = false;
|
||||
ImageQuality = -1;
|
||||
TimeImageTaken = 0;
|
||||
ImageQuality = 5;
|
||||
rawImage = NULL;
|
||||
ImageSize = FRAMESIZE_VGA;
|
||||
SaveAllFiles = false;
|
||||
disabled = false;
|
||||
FixedExposure = false;
|
||||
namerawimage = "/sdcard/img_tmp/raw.jpg";
|
||||
}
|
||||
}
|
||||
|
||||
// auslesen der Kameraeinstellungen aus der config.ini
|
||||
// wird beim Start aufgerufen
|
||||
bool ClassFlowTakeImage::ReadParameter(FILE *pfile, string &aktparamgraph)
|
||||
{
|
||||
Camera.getSensorDatenToCCstatus(); // Kamera >>> CCstatus
|
||||
|
||||
ClassFlowTakeImage::ClassFlowTakeImage(std::vector<ClassFlow*>* lfc) : ClassFlowImage(lfc, TAG)
|
||||
std::vector<string> splitted;
|
||||
|
||||
aktparamgraph = trim(aktparamgraph);
|
||||
|
||||
if (aktparamgraph.size() == 0)
|
||||
{
|
||||
if (!this->GetNextParagraph(pfile, aktparamgraph))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (aktparamgraph.compare("[TakeImage]") != 0)
|
||||
{
|
||||
// Paragraph does not fit TakeImage
|
||||
return false;
|
||||
}
|
||||
|
||||
while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph))
|
||||
{
|
||||
splitted = ZerlegeZeile(aktparamgraph);
|
||||
|
||||
if ((toUpper(splitted[0]) == "RAWIMAGESLOCATION") && (splitted.size() > 1))
|
||||
{
|
||||
imagesLocation = "/sdcard" + splitted[1];
|
||||
isLogImage = true;
|
||||
}
|
||||
|
||||
else if ((toUpper(splitted[0]) == "RAWIMAGESRETENTION") && (splitted.size() > 1))
|
||||
{
|
||||
this->imagesRetention = std::stod(splitted[1]);
|
||||
}
|
||||
|
||||
else if ((toUpper(splitted[0]) == "SAVEALLFILES") && (splitted.size() > 1))
|
||||
{
|
||||
if (toUpper(splitted[1]) == "TRUE")
|
||||
{
|
||||
CCstatus.SaveAllFiles = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
CCstatus.SaveAllFiles = 0;
|
||||
}
|
||||
}
|
||||
|
||||
else if ((toUpper(splitted[0]) == "WAITBEFORETAKINGPICTURE") && (splitted.size() > 1))
|
||||
{
|
||||
int _WaitBeforePicture = std::stoi(splitted[1]);
|
||||
if (_WaitBeforePicture != 0)
|
||||
{
|
||||
CCstatus.WaitBeforePicture = _WaitBeforePicture;
|
||||
}
|
||||
else
|
||||
{
|
||||
CCstatus.WaitBeforePicture = 2;
|
||||
}
|
||||
}
|
||||
|
||||
else if ((toUpper(splitted[0]) == "CAMGAINCEILING") && (splitted.size() > 1))
|
||||
{
|
||||
std::string _ImageGainceiling = toUpper(splitted[1]);
|
||||
if (_ImageGainceiling == "X4")
|
||||
{
|
||||
CCstatus.ImageGainceiling = GAINCEILING_4X;
|
||||
}
|
||||
else if (_ImageGainceiling == "X8")
|
||||
{
|
||||
CCstatus.ImageGainceiling = GAINCEILING_8X;
|
||||
}
|
||||
else if (_ImageGainceiling == "X16")
|
||||
{
|
||||
CCstatus.ImageGainceiling = GAINCEILING_16X;
|
||||
}
|
||||
else if (_ImageGainceiling == "X32")
|
||||
{
|
||||
CCstatus.ImageGainceiling = GAINCEILING_32X;
|
||||
}
|
||||
else if (_ImageGainceiling == "X64")
|
||||
{
|
||||
CCstatus.ImageGainceiling = GAINCEILING_64X;
|
||||
}
|
||||
else if (_ImageGainceiling == "X128")
|
||||
{
|
||||
CCstatus.ImageGainceiling = GAINCEILING_128X;
|
||||
}
|
||||
else
|
||||
{
|
||||
CCstatus.ImageGainceiling = GAINCEILING_2X;
|
||||
}
|
||||
}
|
||||
|
||||
else if ((toUpper(splitted[0]) == "CAMQUALITY") && (splitted.size() > 1))
|
||||
{
|
||||
int _ImageQuality = std::stoi(splitted[1]);
|
||||
if ((_ImageQuality >= 0) && (_ImageQuality <= 63))
|
||||
{
|
||||
CCstatus.ImageQuality = _ImageQuality;
|
||||
}
|
||||
}
|
||||
|
||||
else if ((toUpper(splitted[0]) == "CAMBRIGHTNESS") && (splitted.size() > 1))
|
||||
{
|
||||
int _ImageBrightness = std::stoi(splitted[1]);
|
||||
if ((_ImageBrightness >= -2) && (_ImageBrightness <= 2))
|
||||
{
|
||||
CCstatus.ImageBrightness = _ImageBrightness;
|
||||
}
|
||||
}
|
||||
|
||||
else if ((toUpper(splitted[0]) == "CAMCONTRAST") && (splitted.size() > 1))
|
||||
{
|
||||
int _ImageContrast = std::stoi(splitted[1]);
|
||||
if ((_ImageContrast >= -2) && (_ImageContrast <= 2))
|
||||
{
|
||||
CCstatus.ImageContrast = _ImageContrast;
|
||||
}
|
||||
}
|
||||
|
||||
else if ((toUpper(splitted[0]) == "CAMSATURATION") && (splitted.size() > 1))
|
||||
{
|
||||
int _ImageSaturation = std::stoi(splitted[1]);
|
||||
if ((_ImageSaturation >= -2) && (_ImageSaturation <= 2))
|
||||
{
|
||||
CCstatus.ImageSaturation = _ImageSaturation;
|
||||
}
|
||||
}
|
||||
|
||||
else if ((toUpper(splitted[0]) == "CAMSHARPNESS") && (splitted.size() > 1))
|
||||
{
|
||||
int _ImageSharpness = std::stoi(splitted[1]);
|
||||
if ((_ImageSharpness >= -2) && (_ImageSharpness <= 2))
|
||||
{
|
||||
CCstatus.ImageSharpness = _ImageSharpness;
|
||||
}
|
||||
}
|
||||
|
||||
else if ((toUpper(splitted[0]) == "CAMAUTOSHARPNESS") && (splitted.size() > 1))
|
||||
{
|
||||
if (toUpper(splitted[1]) == "TRUE")
|
||||
{
|
||||
CCstatus.ImageAutoSharpness = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
CCstatus.ImageAutoSharpness = 0;
|
||||
}
|
||||
}
|
||||
|
||||
else if ((toUpper(splitted[0]) == "CAMSPECIALEFFECT") && (splitted.size() > 1))
|
||||
{
|
||||
std::string _ImageSpecialEffect = toUpper(splitted[1]);
|
||||
if (_ImageSpecialEffect == "NEGATIVE")
|
||||
{
|
||||
CCstatus.ImageSpecialEffect = 1;
|
||||
}
|
||||
else if (_ImageSpecialEffect == "GRAYSCALE")
|
||||
{
|
||||
CCstatus.ImageSpecialEffect = 2;
|
||||
}
|
||||
else if (_ImageSpecialEffect == "RED")
|
||||
{
|
||||
CCstatus.ImageSpecialEffect = 3;
|
||||
}
|
||||
else if (_ImageSpecialEffect == "GREEN")
|
||||
{
|
||||
CCstatus.ImageSpecialEffect = 4;
|
||||
}
|
||||
else if (_ImageSpecialEffect == "BLUE")
|
||||
{
|
||||
CCstatus.ImageSpecialEffect = 5;
|
||||
}
|
||||
else if (_ImageSpecialEffect == "RETRO")
|
||||
{
|
||||
CCstatus.ImageSpecialEffect = 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
CCstatus.ImageSpecialEffect = 0;
|
||||
}
|
||||
}
|
||||
|
||||
else if ((toUpper(splitted[0]) == "CAMWBMODE") && (splitted.size() > 1))
|
||||
{
|
||||
std::string _ImageWbMode = toUpper(splitted[1]);
|
||||
if (_ImageWbMode == "SUNNY")
|
||||
{
|
||||
CCstatus.ImageWbMode = 1;
|
||||
}
|
||||
else if (_ImageWbMode == "CLOUDY")
|
||||
{
|
||||
CCstatus.ImageWbMode = 2;
|
||||
}
|
||||
else if (_ImageWbMode == "OFFICE")
|
||||
{
|
||||
CCstatus.ImageWbMode = 3;
|
||||
}
|
||||
else if (_ImageWbMode == "HOME")
|
||||
{
|
||||
CCstatus.ImageWbMode = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
CCstatus.ImageWbMode = 0;
|
||||
}
|
||||
}
|
||||
|
||||
else if ((toUpper(splitted[0]) == "CAMAWB") && (splitted.size() > 1))
|
||||
{
|
||||
if (toUpper(splitted[1]) == "TRUE")
|
||||
{
|
||||
CCstatus.ImageAwb = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
CCstatus.ImageAwb = 0;
|
||||
}
|
||||
}
|
||||
|
||||
else if ((toUpper(splitted[0]) == "CAMAWBGAIN") && (splitted.size() > 1))
|
||||
{
|
||||
if (toUpper(splitted[1]) == "TRUE")
|
||||
{
|
||||
CCstatus.ImageAwbGain = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
CCstatus.ImageAwbGain = 0;
|
||||
}
|
||||
}
|
||||
|
||||
else if ((toUpper(splitted[0]) == "CAMAEC") && (splitted.size() > 1))
|
||||
{
|
||||
if (toUpper(splitted[1]) == "TRUE")
|
||||
{
|
||||
CCstatus.ImageAec = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
CCstatus.ImageAec = 0;
|
||||
}
|
||||
}
|
||||
|
||||
else if ((toUpper(splitted[0]) == "CAMAEC2") && (splitted.size() > 1))
|
||||
{
|
||||
if (toUpper(splitted[1]) == "TRUE")
|
||||
{
|
||||
CCstatus.ImageAec2 = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
CCstatus.ImageAec2 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
else if ((toUpper(splitted[0]) == "CAMAELEVEL") && (splitted.size() > 1))
|
||||
{
|
||||
int _ImageAeLevel = std::stoi(splitted[1]);
|
||||
if ((_ImageAeLevel >= -2) && (_ImageAeLevel <= 2))
|
||||
{
|
||||
CCstatus.ImageAeLevel = _ImageAeLevel;
|
||||
}
|
||||
}
|
||||
|
||||
else if ((toUpper(splitted[0]) == "CAMAECVALUE") && (splitted.size() > 1))
|
||||
{
|
||||
int _ImageAecValue = std::stoi(splitted[1]);
|
||||
if ((_ImageAecValue >= 0) && (_ImageAecValue <= 1200))
|
||||
{
|
||||
CCstatus.ImageAecValue = _ImageAecValue;
|
||||
}
|
||||
}
|
||||
|
||||
else if ((toUpper(splitted[0]) == "CAMAGC") && (splitted.size() > 1))
|
||||
{
|
||||
if (toUpper(splitted[1]) == "TRUE")
|
||||
{
|
||||
CCstatus.ImageAgc = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
CCstatus.ImageAgc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
else if ((toUpper(splitted[0]) == "CAMAGCGAIN") && (splitted.size() > 1))
|
||||
{
|
||||
int _ImageAgcGain = std::stoi(splitted[1]);
|
||||
if ((_ImageAgcGain >= 0) && (_ImageAgcGain <= 30))
|
||||
{
|
||||
CCstatus.ImageAgcGain = _ImageAgcGain;
|
||||
}
|
||||
}
|
||||
|
||||
else if ((toUpper(splitted[0]) == "CAMBPC") && (splitted.size() > 1))
|
||||
{
|
||||
if (toUpper(splitted[1]) == "TRUE")
|
||||
{
|
||||
CCstatus.ImageBpc = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
CCstatus.ImageBpc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
else if ((toUpper(splitted[0]) == "CAMWPC") && (splitted.size() > 1))
|
||||
{
|
||||
if (toUpper(splitted[1]) == "TRUE")
|
||||
{
|
||||
CCstatus.ImageWpc = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
CCstatus.ImageWpc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
else if ((toUpper(splitted[0]) == "CAMRAWGMA") && (splitted.size() > 1))
|
||||
{
|
||||
if (toUpper(splitted[1]) == "TRUE")
|
||||
{
|
||||
CCstatus.ImageRawGma = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
CCstatus.ImageRawGma = 0;
|
||||
}
|
||||
}
|
||||
|
||||
else if ((toUpper(splitted[0]) == "CAMLENC") && (splitted.size() > 1))
|
||||
{
|
||||
if (toUpper(splitted[1]) == "TRUE")
|
||||
{
|
||||
CCstatus.ImageLenc = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
CCstatus.ImageLenc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
else if ((toUpper(splitted[0]) == "CAMHMIRROR") && (splitted.size() > 1))
|
||||
{
|
||||
if (toUpper(splitted[1]) == "TRUE")
|
||||
{
|
||||
CCstatus.ImageHmirror = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
CCstatus.ImageHmirror = 0;
|
||||
}
|
||||
}
|
||||
|
||||
else if ((toUpper(splitted[0]) == "CAMVFLIP") && (splitted.size() > 1))
|
||||
{
|
||||
if (toUpper(splitted[1]) == "TRUE")
|
||||
{
|
||||
CCstatus.ImageVflip = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
CCstatus.ImageVflip = 0;
|
||||
}
|
||||
}
|
||||
|
||||
else if ((toUpper(splitted[0]) == "CAMDCW") && (splitted.size() > 1))
|
||||
{
|
||||
if (toUpper(splitted[1]) == "TRUE")
|
||||
{
|
||||
CCstatus.ImageDcw = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
CCstatus.ImageDcw = 0;
|
||||
}
|
||||
}
|
||||
|
||||
else if ((toUpper(splitted[0]) == "CAMZOOM") && (splitted.size() > 1))
|
||||
{
|
||||
if (toUpper(splitted[1]) == "TRUE")
|
||||
{
|
||||
CCstatus.ImageZoomEnabled = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
CCstatus.ImageZoomEnabled = 0;
|
||||
}
|
||||
}
|
||||
|
||||
else if ((toUpper(splitted[0]) == "CAMZOOMOFFSETX") && (splitted.size() > 1))
|
||||
{
|
||||
CCstatus.ImageZoomOffsetX = std::stoi(splitted[1]);
|
||||
}
|
||||
|
||||
else if ((toUpper(splitted[0]) == "CAMZOOMOFFSETY") && (splitted.size() > 1))
|
||||
{
|
||||
CCstatus.ImageZoomOffsetY = std::stoi(splitted[1]);
|
||||
}
|
||||
|
||||
else if ((toUpper(splitted[0]) == "CAMZOOMSIZE") && (splitted.size() > 1))
|
||||
{
|
||||
int _ImageZoomSize = std::stoi(splitted[1]);
|
||||
if (_ImageZoomSize >= 0)
|
||||
{
|
||||
CCstatus.ImageZoomSize = _ImageZoomSize;
|
||||
}
|
||||
}
|
||||
|
||||
else if ((toUpper(splitted[0]) == "LEDINTENSITY") && (splitted.size() > 1))
|
||||
{
|
||||
float ledintensity = std::stof(splitted[1]);
|
||||
Camera.SetLEDIntensity(ledintensity);
|
||||
}
|
||||
|
||||
else if ((toUpper(splitted[0]) == "DEMO") && (splitted.size() > 1))
|
||||
{
|
||||
if (toUpper(splitted[1]) == "TRUE")
|
||||
{
|
||||
CCstatus.DemoMode = true;
|
||||
Camera.useDemoMode();
|
||||
}
|
||||
else
|
||||
{
|
||||
CCstatus.DemoMode = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Camera.setSensorDatenFromCCstatus(); // CCstatus >>> Kamera
|
||||
Camera.SetQualityZoomSize(CCstatus.ImageQuality, CCstatus.ImageFrameSize, CCstatus.ImageZoomEnabled, CCstatus.ImageZoomOffsetX, CCstatus.ImageZoomOffsetY, CCstatus.ImageZoomSize);
|
||||
|
||||
rawImage = new CImageBasis("rawImage");
|
||||
rawImage->CreateEmptyImage(CCstatus.ImageWidth, CCstatus.ImageHeight, 3);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ClassFlowTakeImage::ClassFlowTakeImage(std::vector<ClassFlow *> *lfc) : ClassFlowImage(lfc, TAG)
|
||||
{
|
||||
imagesLocation = "/log/source";
|
||||
imagesRetention = 5;
|
||||
SetInitialParameter();
|
||||
}
|
||||
|
||||
|
||||
bool ClassFlowTakeImage::ReadParameter(FILE* pfile, string& aktparamgraph)
|
||||
{
|
||||
std::vector<string> splitted;
|
||||
|
||||
aktparamgraph = trim(aktparamgraph);
|
||||
int _brightness = -100;
|
||||
int _contrast = -100;
|
||||
int _saturation = -100;
|
||||
|
||||
if (aktparamgraph.size() == 0)
|
||||
if (!this->GetNextParagraph(pfile, aktparamgraph))
|
||||
return false;
|
||||
|
||||
if (aktparamgraph.compare("[TakeImage]") != 0) // Paragraph does not fit TakeImage
|
||||
return false;
|
||||
|
||||
while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph))
|
||||
{
|
||||
splitted = ZerlegeZeile(aktparamgraph);
|
||||
if ((toUpper(splitted[0]) == "RAWIMAGESLOCATION") && (splitted.size() > 1))
|
||||
{
|
||||
imagesLocation = "/sdcard" + splitted[1];
|
||||
isLogImage = true;
|
||||
}
|
||||
if ((toUpper(splitted[0]) == "IMAGEQUALITY") && (splitted.size() > 1))
|
||||
ImageQuality = std::stod(splitted[1]);
|
||||
|
||||
if ((toUpper(splitted[0]) == "IMAGESIZE") && (splitted.size() > 1))
|
||||
{
|
||||
ImageSize = Camera.TextToFramesize(splitted[1].c_str());
|
||||
isImageSize = true;
|
||||
}
|
||||
|
||||
if ((toUpper(splitted[0]) == "SAVEALLFILES") && (splitted.size() > 1))
|
||||
{
|
||||
if (toUpper(splitted[1]) == "TRUE")
|
||||
SaveAllFiles = true;
|
||||
}
|
||||
|
||||
if ((toUpper(splitted[0]) == "WAITBEFORETAKINGPICTURE") && (splitted.size() > 1))
|
||||
{
|
||||
waitbeforepicture = stoi(splitted[1]);
|
||||
}
|
||||
|
||||
if ((toUpper(splitted[0]) == "RAWIMAGESRETENTION") && (splitted.size() > 1))
|
||||
{
|
||||
this->imagesRetention = std::stoi(splitted[1]);
|
||||
}
|
||||
|
||||
if ((toUpper(splitted[0]) == "BRIGHTNESS") && (splitted.size() > 1))
|
||||
{
|
||||
_brightness = stoi(splitted[1]);
|
||||
}
|
||||
|
||||
if ((toUpper(splitted[0]) == "CONTRAST") && (splitted.size() > 1))
|
||||
{
|
||||
_contrast = stoi(splitted[1]);
|
||||
}
|
||||
|
||||
if ((toUpper(splitted[0]) == "SATURATION") && (splitted.size() > 1))
|
||||
{
|
||||
_saturation = stoi(splitted[1]);
|
||||
}
|
||||
|
||||
if ((toUpper(splitted[0]) == "FIXEDEXPOSURE") && (splitted.size() > 1))
|
||||
{
|
||||
if (toUpper(splitted[1]) == "TRUE")
|
||||
FixedExposure = true;
|
||||
}
|
||||
|
||||
if ((toUpper(splitted[0]) == "LEDINTENSITY") && (splitted.size() > 1))
|
||||
{
|
||||
float ledintensity = stof(splitted[1]);
|
||||
ledintensity = min((float) 100, ledintensity);
|
||||
ledintensity = max((float) 0, ledintensity);
|
||||
Camera.SetLEDIntensity(ledintensity);
|
||||
}
|
||||
|
||||
if ((toUpper(splitted[0]) == "DEMO") && (splitted.size() > 1))
|
||||
{
|
||||
if (toUpper(splitted[1]) == "TRUE")
|
||||
Camera.useDemoMode();
|
||||
}
|
||||
}
|
||||
|
||||
Camera.SetBrightnessContrastSaturation(_brightness, _contrast, _saturation);
|
||||
Camera.SetQualitySize(ImageQuality, ImageSize);
|
||||
|
||||
image_width = Camera.image_width;
|
||||
image_height = Camera.image_height;
|
||||
rawImage = new CImageBasis("rawImage");
|
||||
rawImage->CreateEmptyImage(image_width, image_height, 3);
|
||||
|
||||
waitbeforepicture_store = waitbeforepicture;
|
||||
if (FixedExposure && (waitbeforepicture > 0))
|
||||
{
|
||||
// ESP_LOGD(TAG, "Fixed Exposure enabled!");
|
||||
int flash_duration = (int) (waitbeforepicture * 1000);
|
||||
Camera.EnableAutoExposure(flash_duration);
|
||||
waitbeforepicture = 0.2;
|
||||
// flash_duration = (int) (waitbeforepicture * 1000);
|
||||
// takePictureWithFlash(flash_duration);
|
||||
// rawImage->SaveToFile("/sdcard/init2.jpg");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
string ClassFlowTakeImage::getHTMLSingleStep(string host)
|
||||
{
|
||||
string result;
|
||||
@@ -181,74 +517,78 @@ string ClassFlowTakeImage::getHTMLSingleStep(string host)
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
// wird bei jeder Auswertrunde aufgerufen
|
||||
bool ClassFlowTakeImage::doFlow(string zwtime)
|
||||
{
|
||||
psram_init_shared_memory_for_take_image_step();
|
||||
|
||||
string logPath = CreateLogFolder(zwtime);
|
||||
|
||||
int flash_duration = (int) (waitbeforepicture * 1000);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("ClassFlowTakeImage::doFlow - Before takePictureWithFlash");
|
||||
#endif
|
||||
int flash_duration = (int)(CCstatus.WaitBeforePicture * 1000);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("ClassFlowTakeImage::doFlow - Before takePictureWithFlash");
|
||||
#endif
|
||||
|
||||
#ifdef WIFITURNOFF
|
||||
esp_wifi_stop(); // to save power usage and
|
||||
#endif
|
||||
#ifdef WIFITURNOFF
|
||||
esp_wifi_stop(); // to save power usage and
|
||||
#endif
|
||||
|
||||
// wenn die Kameraeinstellungen durch Erstellen eines neuen Referenzbildes verändert wurden, müssen sie neu gesetzt werden
|
||||
if (CFstatus.changedCameraSettings)
|
||||
{
|
||||
Camera.setSensorDatenFromCCstatus(); // CCstatus >>> Kamera
|
||||
Camera.SetQualityZoomSize(CCstatus.ImageQuality, CCstatus.ImageFrameSize, CCstatus.ImageZoomEnabled, CCstatus.ImageZoomOffsetX, CCstatus.ImageZoomOffsetY, CCstatus.ImageZoomSize);
|
||||
CFstatus.changedCameraSettings = false;
|
||||
}
|
||||
|
||||
takePictureWithFlash(flash_duration);
|
||||
|
||||
#ifdef WIFITURNOFF
|
||||
esp_wifi_start();
|
||||
#endif
|
||||
#ifdef WIFITURNOFF
|
||||
esp_wifi_start();
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("ClassFlowTakeImage::doFlow - After takePictureWithFlash");
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("ClassFlowTakeImage::doFlow - After takePictureWithFlash");
|
||||
#endif
|
||||
|
||||
LogImage(logPath, "raw", NULL, NULL, zwtime, rawImage);
|
||||
|
||||
RemoveOldLogs();
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("ClassFlowTakeImage::doFlow - After RemoveOldLogs");
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("ClassFlowTakeImage::doFlow - After RemoveOldLogs");
|
||||
#endif
|
||||
|
||||
psram_deinit_shared_memory_for_take_image_step();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
esp_err_t ClassFlowTakeImage::SendRawJPG(httpd_req_t *req)
|
||||
{
|
||||
int flash_duration = (int) (waitbeforepicture * 1000);
|
||||
int flash_duration = (int)(CCstatus.WaitBeforePicture * 1000);
|
||||
time(&TimeImageTaken);
|
||||
localtime(&TimeImageTaken);
|
||||
|
||||
return Camera.CaptureToHTTP(req, flash_duration);
|
||||
}
|
||||
|
||||
|
||||
ImageData* ClassFlowTakeImage::SendRawImage()
|
||||
ImageData *ClassFlowTakeImage::SendRawImage(void)
|
||||
{
|
||||
CImageBasis *zw = new CImageBasis("SendRawImage", rawImage);
|
||||
ImageData *id;
|
||||
int flash_duration = (int) (waitbeforepicture * 1000);
|
||||
int flash_duration = (int)(CCstatus.WaitBeforePicture * 1000);
|
||||
Camera.CaptureToBasisImage(zw, flash_duration);
|
||||
time(&TimeImageTaken);
|
||||
localtime(&TimeImageTaken);
|
||||
|
||||
id = zw->writeToMemoryAsJPG();
|
||||
id = zw->writeToMemoryAsJPG();
|
||||
delete zw;
|
||||
return id;
|
||||
return id;
|
||||
}
|
||||
|
||||
time_t ClassFlowTakeImage::getTimeImageTaken()
|
||||
time_t ClassFlowTakeImage::getTimeImageTaken(void)
|
||||
{
|
||||
return TimeImageTaken;
|
||||
}
|
||||
@@ -257,4 +597,3 @@ ClassFlowTakeImage::~ClassFlowTakeImage(void)
|
||||
{
|
||||
delete rawImage;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,47 +9,32 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
class ClassFlowTakeImage :
|
||||
public ClassFlowImage
|
||||
class ClassFlowTakeImage : public ClassFlowImage
|
||||
{
|
||||
protected:
|
||||
float waitbeforepicture;
|
||||
float waitbeforepicture_store;
|
||||
framesize_t ImageSize;
|
||||
bool isImageSize;
|
||||
int ImageQuality;
|
||||
time_t TimeImageTaken;
|
||||
string namerawimage;
|
||||
int image_height, image_width;
|
||||
bool SaveAllFiles;
|
||||
bool FixedExposure;
|
||||
|
||||
|
||||
|
||||
void CopyFile(string input, string output);
|
||||
|
||||
esp_err_t camera_capture();
|
||||
esp_err_t camera_capture(void);
|
||||
void takePictureWithFlash(int flash_duration);
|
||||
|
||||
|
||||
void SetInitialParameter(void);
|
||||
void SetInitialParameter(void);
|
||||
|
||||
public:
|
||||
CImageBasis *rawImage;
|
||||
|
||||
ClassFlowTakeImage(std::vector<ClassFlow*>* lfc);
|
||||
ClassFlowTakeImage(std::vector<ClassFlow *> *lfc);
|
||||
|
||||
bool ReadParameter(FILE* pfile, string& aktparamgraph);
|
||||
bool ReadParameter(FILE *pfile, string &aktparamgraph);
|
||||
bool doFlow(string time);
|
||||
string getHTMLSingleStep(string host);
|
||||
time_t getTimeImageTaken();
|
||||
string name(){return "ClassFlowTakeImage";};
|
||||
time_t getTimeImageTaken(void);
|
||||
string name() { return "ClassFlowTakeImage"; };
|
||||
|
||||
ImageData* SendRawImage();
|
||||
ImageData *SendRawImage(void);
|
||||
esp_err_t SendRawJPG(httpd_req_t *req);
|
||||
|
||||
~ClassFlowTakeImage(void);
|
||||
};
|
||||
|
||||
|
||||
#endif //CLASSFFLOWTAKEIMAGE_H
|
||||
#endif // CLASSFFLOWTAKEIMAGE_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -10,25 +10,78 @@
|
||||
#include "CImageBasis.h"
|
||||
#include "ClassFlowControll.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
framesize_t ImageFrameSize = FRAMESIZE_VGA; // 0 - 10
|
||||
gainceiling_t ImageGainceiling; // Image gain (GAINCEILING_x2, x4, x8, x16, x32, x64 or x128)
|
||||
|
||||
int ImageQuality; // 0 - 63
|
||||
int ImageBrightness; // (-2 to 2) - set brightness
|
||||
int ImageContrast; //-2 - 2
|
||||
int ImageSaturation; //-2 - 2
|
||||
int ImageSharpness; //-2 - 2
|
||||
bool ImageAutoSharpness;
|
||||
int ImageSpecialEffect; // 0 - 6
|
||||
int ImageWbMode; // 0 to 4 - if awb_gain enabled (0 - Auto, 1 - Sunny, 2 - Cloudy, 3 - Office, 4 - Home)
|
||||
int ImageAwb; // white balance enable (0 or 1)
|
||||
int ImageAwbGain; // Auto White Balance enable (0 or 1)
|
||||
int ImageAec; // auto exposure off (1 or 0)
|
||||
int ImageAec2; // automatic exposure sensor (0 or 1)
|
||||
int ImageAeLevel; // auto exposure levels (-2 to 2)
|
||||
int ImageAecValue; // set exposure manually (0-1200)
|
||||
int ImageAgc; // auto gain off (1 or 0)
|
||||
int ImageAgcGain; // set gain manually (0 - 30)
|
||||
int ImageBpc; // black pixel correction
|
||||
int ImageWpc; // white pixel correction
|
||||
int ImageRawGma; // (1 or 0)
|
||||
int ImageLenc; // lens correction (1 or 0)
|
||||
int ImageHmirror; // (0 or 1) flip horizontally
|
||||
int ImageVflip; // Invert image (0 or 1)
|
||||
int ImageDcw; // downsize enable (1 or 0)
|
||||
|
||||
int ImageWidth;
|
||||
int ImageHeight;
|
||||
|
||||
int ImageLedIntensity;
|
||||
|
||||
bool ImageZoomEnabled;
|
||||
int ImageZoomMode;
|
||||
int ImageZoomOffsetX;
|
||||
int ImageZoomOffsetY;
|
||||
int ImageZoomSize;
|
||||
|
||||
int WaitBeforePicture;
|
||||
bool isImageSize;
|
||||
|
||||
bool CameraInitSuccessful;
|
||||
bool changedCameraSettings;
|
||||
bool DemoMode;
|
||||
bool SaveAllFiles;
|
||||
} camera_flow_config_temp_t;
|
||||
|
||||
extern camera_flow_config_temp_t CFstatus;
|
||||
extern ClassFlowControll flowctrl;
|
||||
|
||||
esp_err_t setCCstatusToCFstatus(void); // CCstatus >>> CFstatus
|
||||
esp_err_t setCFstatusToCCstatus(void); // CFstatus >>> CCstatus
|
||||
esp_err_t setCFstatusToCam(void); // CFstatus >>> Kamera
|
||||
|
||||
void register_server_main_flow_task_uri(httpd_handle_t server);
|
||||
|
||||
void CheckIsPlannedReboot();
|
||||
bool getIsPlannedReboot();
|
||||
void CheckIsPlannedReboot(void);
|
||||
bool getIsPlannedReboot(void);
|
||||
|
||||
void InitializeFlowTask();
|
||||
void DeleteMainFlowTask();
|
||||
bool isSetupModusActive();
|
||||
void InitializeFlowTask(void);
|
||||
void DeleteMainFlowTask(void);
|
||||
bool isSetupModusActive(void);
|
||||
|
||||
int getCountFlowRounds();
|
||||
int getCountFlowRounds(void);
|
||||
|
||||
#ifdef ENABLE_MQTT
|
||||
esp_err_t MQTTCtrlFlowStart(std::string _topic);
|
||||
#endif //ENABLE_MQTT
|
||||
#endif // ENABLE_MQTT
|
||||
|
||||
esp_err_t GetRawJPG(httpd_req_t *req);
|
||||
esp_err_t GetJPG(std::string _filename, httpd_req_t *req);
|
||||
|
||||
#endif //MAINFLOWCONTROL_H
|
||||
#endif // MAINFLOWCONTROL_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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);
|
||||
|
||||
|
||||
@@ -1,353 +1,309 @@
|
||||
#include <string>
|
||||
#include "CRotateImage.h"
|
||||
#include "psram.h"
|
||||
|
||||
static const char *TAG = "C ROTATE IMG";
|
||||
|
||||
CRotateImage::CRotateImage(std::string _name, CImageBasis *_org, CImageBasis *_temp, bool _flip) : CImageBasis(_name)
|
||||
{
|
||||
rgb_image = _org->rgb_image;
|
||||
channels = _org->channels;
|
||||
width = _org->width;
|
||||
height = _org->height;
|
||||
bpp = _org->bpp;
|
||||
externalImage = true;
|
||||
ImageTMP = _temp;
|
||||
ImageOrg = _org;
|
||||
islocked = false;
|
||||
doflip = _flip;
|
||||
}
|
||||
|
||||
|
||||
void CRotateImage::Mirror(){
|
||||
int memsize = width * height * channels;
|
||||
uint8_t* odata;
|
||||
if (ImageTMP)
|
||||
{
|
||||
odata = ImageTMP->RGBImageLock();
|
||||
}
|
||||
else
|
||||
{
|
||||
odata = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->odata", memsize, MALLOC_CAP_SPIRAM);
|
||||
}
|
||||
|
||||
|
||||
int x_source, y_source;
|
||||
stbi_uc* p_target;
|
||||
stbi_uc* p_source;
|
||||
|
||||
RGBImageLock();
|
||||
|
||||
for (int x = 0; x < width; ++x)
|
||||
for (int y = 0; y < height; ++y)
|
||||
{
|
||||
p_target = odata + (channels * (y * width + x));
|
||||
|
||||
x_source = width - x;
|
||||
y_source = y;
|
||||
|
||||
p_source = rgb_image + (channels * (y_source * width + x_source));
|
||||
for (int _channels = 0; _channels < channels; ++_channels)
|
||||
p_target[_channels] = p_source[_channels];
|
||||
}
|
||||
|
||||
// memcpy(rgb_image, odata, memsize);
|
||||
memCopy(odata, rgb_image, memsize);
|
||||
if (!ImageTMP)
|
||||
free_psram_heap(std::string(TAG) + "->odata", odata);
|
||||
|
||||
if (ImageTMP)
|
||||
ImageTMP->RGBImageRelease();
|
||||
|
||||
RGBImageRelease();
|
||||
}
|
||||
|
||||
void CRotateImage::Rotate(float _angle, int _centerx, int _centery)
|
||||
{
|
||||
int org_width, org_height;
|
||||
float m[2][3];
|
||||
|
||||
float x_center = _centerx;
|
||||
float y_center = _centery;
|
||||
_angle = _angle / 180 * M_PI;
|
||||
|
||||
if (doflip)
|
||||
{
|
||||
org_width = width;
|
||||
org_height = height;
|
||||
height = org_width;
|
||||
width = org_height;
|
||||
x_center = x_center - (org_width/2) + (org_height/2);
|
||||
y_center = y_center + (org_width/2) - (org_height/2);
|
||||
if (ImageOrg)
|
||||
{
|
||||
ImageOrg->height = height;
|
||||
ImageOrg->width = width;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
org_width = width;
|
||||
org_height = height;
|
||||
}
|
||||
|
||||
m[0][0] = cos(_angle);
|
||||
m[0][1] = sin(_angle);
|
||||
m[0][2] = (1 - m[0][0]) * x_center - m[0][1] * y_center;
|
||||
|
||||
m[1][0] = -m[0][1];
|
||||
m[1][1] = m[0][0];
|
||||
m[1][2] = m[0][1] * x_center + (1 - m[0][0]) * y_center;
|
||||
|
||||
if (doflip)
|
||||
{
|
||||
m[0][2] = m[0][2] + (org_width/2) - (org_height/2);
|
||||
m[1][2] = m[1][2] - (org_width/2) + (org_height/2);
|
||||
}
|
||||
|
||||
int memsize = width * height * channels;
|
||||
uint8_t* odata;
|
||||
if (ImageTMP)
|
||||
{
|
||||
odata = ImageTMP->RGBImageLock();
|
||||
}
|
||||
else
|
||||
{
|
||||
odata = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->odata", memsize, MALLOC_CAP_SPIRAM);
|
||||
}
|
||||
|
||||
|
||||
int x_source, y_source;
|
||||
stbi_uc* p_target;
|
||||
stbi_uc* p_source;
|
||||
|
||||
RGBImageLock();
|
||||
|
||||
for (int x = 0; x < width; ++x)
|
||||
for (int y = 0; y < height; ++y)
|
||||
{
|
||||
p_target = odata + (channels * (y * width + x));
|
||||
|
||||
x_source = int(m[0][0] * x + m[0][1] * y);
|
||||
y_source = int(m[1][0] * x + m[1][1] * y);
|
||||
|
||||
x_source += int(m[0][2]);
|
||||
y_source += int(m[1][2]);
|
||||
|
||||
if ((x_source >= 0) && (x_source < org_width) && (y_source >= 0) && (y_source < org_height))
|
||||
{
|
||||
p_source = rgb_image + (channels * (y_source * org_width + x_source));
|
||||
for (int _channels = 0; _channels < channels; ++_channels)
|
||||
p_target[_channels] = p_source[_channels];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int _channels = 0; _channels < channels; ++_channels)
|
||||
p_target[_channels] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
// memcpy(rgb_image, odata, memsize);
|
||||
memCopy(odata, rgb_image, memsize);
|
||||
|
||||
if (!ImageTMP)
|
||||
{
|
||||
free_psram_heap(std::string(TAG) + "->odata", odata);
|
||||
}
|
||||
if (ImageTMP)
|
||||
ImageTMP->RGBImageRelease();
|
||||
|
||||
RGBImageRelease();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CRotateImage::RotateAntiAliasing(float _angle, int _centerx, int _centery)
|
||||
{
|
||||
int org_width, org_height;
|
||||
float m[2][3];
|
||||
|
||||
float x_center = _centerx;
|
||||
float y_center = _centery;
|
||||
_angle = _angle / 180 * M_PI;
|
||||
|
||||
if (doflip)
|
||||
{
|
||||
org_width = width;
|
||||
org_height = height;
|
||||
height = org_width;
|
||||
width = org_height;
|
||||
x_center = x_center - (org_width/2) + (org_height/2);
|
||||
y_center = y_center + (org_width/2) - (org_height/2);
|
||||
if (ImageOrg)
|
||||
{
|
||||
ImageOrg->height = height;
|
||||
ImageOrg->width = width;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
org_width = width;
|
||||
org_height = height;
|
||||
}
|
||||
|
||||
m[0][0] = cos(_angle);
|
||||
m[0][1] = sin(_angle);
|
||||
m[0][2] = (1 - m[0][0]) * x_center - m[0][1] * y_center;
|
||||
|
||||
m[1][0] = -m[0][1];
|
||||
m[1][1] = m[0][0];
|
||||
m[1][2] = m[0][1] * x_center + (1 - m[0][0]) * y_center;
|
||||
|
||||
if (doflip)
|
||||
{
|
||||
m[0][2] = m[0][2] + (org_width/2) - (org_height/2);
|
||||
m[1][2] = m[1][2] - (org_width/2) + (org_height/2);
|
||||
}
|
||||
|
||||
int memsize = width * height * channels;
|
||||
uint8_t* odata;
|
||||
if (ImageTMP)
|
||||
{
|
||||
odata = ImageTMP->RGBImageLock();
|
||||
}
|
||||
else
|
||||
{
|
||||
odata = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->odata", memsize, MALLOC_CAP_SPIRAM);
|
||||
}
|
||||
|
||||
|
||||
int x_source_1, y_source_1, x_source_2, y_source_2;
|
||||
float x_source, y_source;
|
||||
float quad_ul, quad_ur, quad_ol, quad_or;
|
||||
stbi_uc* p_target;
|
||||
stbi_uc *p_source_ul, *p_source_ur, *p_source_ol, *p_source_or;
|
||||
|
||||
RGBImageLock();
|
||||
|
||||
for (int x = 0; x < width; ++x)
|
||||
for (int y = 0; y < height; ++y)
|
||||
{
|
||||
p_target = odata + (channels * (y * width + x));
|
||||
|
||||
x_source = (m[0][0] * x + m[0][1] * y);
|
||||
y_source = (m[1][0] * x + m[1][1] * y);
|
||||
|
||||
x_source += (m[0][2]);
|
||||
y_source += (m[1][2]);
|
||||
|
||||
x_source_1 = (int)x_source;
|
||||
x_source_2 = x_source_1 + 1;
|
||||
y_source_1 = (int)y_source;
|
||||
y_source_2 = y_source_1 + 1;
|
||||
|
||||
quad_ul = (x_source_2 - x_source) * (y_source_2 - y_source);
|
||||
quad_ur = (1- (x_source_2 - x_source)) * (y_source_2 - y_source);
|
||||
quad_or = (x_source_2 - x_source) * (1-(y_source_2 - y_source));
|
||||
quad_ol = (1- (x_source_2 - x_source)) * (1-(y_source_2 - y_source));
|
||||
|
||||
|
||||
if ((x_source_1 >= 0) && (x_source_2 < org_width) && (y_source_1 >= 0) && (y_source_2 < org_height))
|
||||
{
|
||||
p_source_ul = rgb_image + (channels * (y_source_1 * org_width + x_source_1));
|
||||
p_source_ur = rgb_image + (channels * (y_source_1 * org_width + x_source_2));
|
||||
p_source_or = rgb_image + (channels * (y_source_2 * org_width + x_source_1));
|
||||
p_source_ol = rgb_image + (channels * (y_source_2 * org_width + x_source_2));
|
||||
for (int _channels = 0; _channels < channels; ++_channels)
|
||||
{
|
||||
p_target[_channels] = (int)((float)p_source_ul[_channels] * quad_ul
|
||||
+ (float)p_source_ur[_channels] * quad_ur
|
||||
+ (float)p_source_or[_channels] * quad_or
|
||||
+ (float)p_source_ol[_channels] * quad_ol);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int _channels = 0; _channels < channels; ++_channels)
|
||||
p_target[_channels] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
// memcpy(rgb_image, odata, memsize);
|
||||
memCopy(odata, rgb_image, memsize);
|
||||
|
||||
if (!ImageTMP)
|
||||
{
|
||||
free_psram_heap(std::string(TAG) + "->odata", odata);
|
||||
}
|
||||
if (ImageTMP)
|
||||
ImageTMP->RGBImageRelease();
|
||||
|
||||
RGBImageRelease();
|
||||
}
|
||||
|
||||
|
||||
void CRotateImage::Rotate(float _angle)
|
||||
{
|
||||
// ESP_LOGD(TAG, "width %d, height %d", width, height);
|
||||
Rotate(_angle, width / 2, height / 2);
|
||||
}
|
||||
|
||||
void CRotateImage::RotateAntiAliasing(float _angle)
|
||||
{
|
||||
// ESP_LOGD(TAG, "width %d, height %d", width, height);
|
||||
RotateAntiAliasing(_angle, width / 2, height / 2);
|
||||
}
|
||||
|
||||
void CRotateImage::Translate(int _dx, int _dy)
|
||||
{
|
||||
int memsize = width * height * channels;
|
||||
uint8_t* odata;
|
||||
if (ImageTMP)
|
||||
{
|
||||
odata = ImageTMP->RGBImageLock();
|
||||
}
|
||||
else
|
||||
{
|
||||
odata = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->odata", memsize, MALLOC_CAP_SPIRAM);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int x_source, y_source;
|
||||
stbi_uc* p_target;
|
||||
stbi_uc* p_source;
|
||||
|
||||
RGBImageLock();
|
||||
|
||||
for (int x = 0; x < width; ++x)
|
||||
for (int y = 0; y < height; ++y)
|
||||
{
|
||||
p_target = odata + (channels * (y * width + x));
|
||||
|
||||
x_source = x - _dx;
|
||||
y_source = y - _dy;
|
||||
|
||||
if ((x_source >= 0) && (x_source < width) && (y_source >= 0) && (y_source < height))
|
||||
{
|
||||
p_source = rgb_image + (channels * (y_source * width + x_source));
|
||||
for (int _channels = 0; _channels < channels; ++_channels)
|
||||
p_target[_channels] = p_source[_channels];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int _channels = 0; _channels < channels; ++_channels)
|
||||
p_target[_channels] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
// memcpy(rgb_image, odata, memsize);
|
||||
memCopy(odata, rgb_image, memsize);
|
||||
if (!ImageTMP)
|
||||
{
|
||||
free_psram_heap(std::string(TAG) + "->odata", odata);
|
||||
}
|
||||
|
||||
if (ImageTMP)
|
||||
{
|
||||
ImageTMP->RGBImageRelease();
|
||||
}
|
||||
RGBImageRelease();
|
||||
|
||||
}
|
||||
|
||||
#include <string>
|
||||
#include "CRotateImage.h"
|
||||
#include "psram.h"
|
||||
|
||||
static const char *TAG = "C ROTATE IMG";
|
||||
|
||||
CRotateImage::CRotateImage(std::string _name, CImageBasis *_org, CImageBasis *_temp, bool _flip) : CImageBasis(_name)
|
||||
{
|
||||
rgb_image = _org->rgb_image;
|
||||
channels = _org->channels;
|
||||
width = _org->width;
|
||||
height = _org->height;
|
||||
bpp = _org->bpp;
|
||||
externalImage = true;
|
||||
ImageTMP = _temp;
|
||||
ImageOrg = _org;
|
||||
islocked = false;
|
||||
doflip = _flip;
|
||||
}
|
||||
|
||||
void CRotateImage::Rotate(float _angle, int _centerx, int _centery)
|
||||
{
|
||||
int org_width, org_height;
|
||||
float m[2][3];
|
||||
|
||||
float x_center = _centerx;
|
||||
float y_center = _centery;
|
||||
_angle = _angle / 180 * M_PI;
|
||||
|
||||
if (doflip)
|
||||
{
|
||||
org_width = width;
|
||||
org_height = height;
|
||||
height = org_width;
|
||||
width = org_height;
|
||||
x_center = x_center - (org_width/2) + (org_height/2);
|
||||
y_center = y_center + (org_width/2) - (org_height/2);
|
||||
if (ImageOrg)
|
||||
{
|
||||
ImageOrg->height = height;
|
||||
ImageOrg->width = width;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
org_width = width;
|
||||
org_height = height;
|
||||
}
|
||||
|
||||
m[0][0] = cos(_angle);
|
||||
m[0][1] = sin(_angle);
|
||||
m[0][2] = (1 - m[0][0]) * x_center - m[0][1] * y_center;
|
||||
|
||||
m[1][0] = -m[0][1];
|
||||
m[1][1] = m[0][0];
|
||||
m[1][2] = m[0][1] * x_center + (1 - m[0][0]) * y_center;
|
||||
|
||||
if (doflip)
|
||||
{
|
||||
m[0][2] = m[0][2] + (org_width/2) - (org_height/2);
|
||||
m[1][2] = m[1][2] - (org_width/2) + (org_height/2);
|
||||
}
|
||||
|
||||
int memsize = width * height * channels;
|
||||
uint8_t* odata;
|
||||
if (ImageTMP)
|
||||
{
|
||||
odata = ImageTMP->RGBImageLock();
|
||||
}
|
||||
else
|
||||
{
|
||||
odata = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->odata", memsize, MALLOC_CAP_SPIRAM);
|
||||
}
|
||||
|
||||
|
||||
int x_source, y_source;
|
||||
stbi_uc* p_target;
|
||||
stbi_uc* p_source;
|
||||
|
||||
RGBImageLock();
|
||||
|
||||
for (int x = 0; x < width; ++x)
|
||||
for (int y = 0; y < height; ++y)
|
||||
{
|
||||
p_target = odata + (channels * (y * width + x));
|
||||
|
||||
x_source = int(m[0][0] * x + m[0][1] * y);
|
||||
y_source = int(m[1][0] * x + m[1][1] * y);
|
||||
|
||||
x_source += int(m[0][2]);
|
||||
y_source += int(m[1][2]);
|
||||
|
||||
if ((x_source >= 0) && (x_source < org_width) && (y_source >= 0) && (y_source < org_height))
|
||||
{
|
||||
p_source = rgb_image + (channels * (y_source * org_width + x_source));
|
||||
for (int _channels = 0; _channels < channels; ++_channels)
|
||||
p_target[_channels] = p_source[_channels];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int _channels = 0; _channels < channels; ++_channels)
|
||||
p_target[_channels] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
// memcpy(rgb_image, odata, memsize);
|
||||
memCopy(odata, rgb_image, memsize);
|
||||
|
||||
if (!ImageTMP)
|
||||
{
|
||||
free_psram_heap(std::string(TAG) + "->odata", odata);
|
||||
}
|
||||
if (ImageTMP)
|
||||
ImageTMP->RGBImageRelease();
|
||||
|
||||
RGBImageRelease();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CRotateImage::RotateAntiAliasing(float _angle, int _centerx, int _centery)
|
||||
{
|
||||
int org_width, org_height;
|
||||
float m[2][3];
|
||||
|
||||
float x_center = _centerx;
|
||||
float y_center = _centery;
|
||||
_angle = _angle / 180 * M_PI;
|
||||
|
||||
if (doflip)
|
||||
{
|
||||
org_width = width;
|
||||
org_height = height;
|
||||
height = org_width;
|
||||
width = org_height;
|
||||
x_center = x_center - (org_width/2) + (org_height/2);
|
||||
y_center = y_center + (org_width/2) - (org_height/2);
|
||||
if (ImageOrg)
|
||||
{
|
||||
ImageOrg->height = height;
|
||||
ImageOrg->width = width;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
org_width = width;
|
||||
org_height = height;
|
||||
}
|
||||
|
||||
m[0][0] = cos(_angle);
|
||||
m[0][1] = sin(_angle);
|
||||
m[0][2] = (1 - m[0][0]) * x_center - m[0][1] * y_center;
|
||||
|
||||
m[1][0] = -m[0][1];
|
||||
m[1][1] = m[0][0];
|
||||
m[1][2] = m[0][1] * x_center + (1 - m[0][0]) * y_center;
|
||||
|
||||
if (doflip)
|
||||
{
|
||||
m[0][2] = m[0][2] + (org_width/2) - (org_height/2);
|
||||
m[1][2] = m[1][2] - (org_width/2) + (org_height/2);
|
||||
}
|
||||
|
||||
int memsize = width * height * channels;
|
||||
uint8_t* odata;
|
||||
if (ImageTMP)
|
||||
{
|
||||
odata = ImageTMP->RGBImageLock();
|
||||
}
|
||||
else
|
||||
{
|
||||
odata = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->odata", memsize, MALLOC_CAP_SPIRAM);
|
||||
}
|
||||
|
||||
|
||||
int x_source_1, y_source_1, x_source_2, y_source_2;
|
||||
float x_source, y_source;
|
||||
float quad_ul, quad_ur, quad_ol, quad_or;
|
||||
stbi_uc* p_target;
|
||||
stbi_uc *p_source_ul, *p_source_ur, *p_source_ol, *p_source_or;
|
||||
|
||||
RGBImageLock();
|
||||
|
||||
for (int x = 0; x < width; ++x)
|
||||
for (int y = 0; y < height; ++y)
|
||||
{
|
||||
p_target = odata + (channels * (y * width + x));
|
||||
|
||||
x_source = (m[0][0] * x + m[0][1] * y);
|
||||
y_source = (m[1][0] * x + m[1][1] * y);
|
||||
|
||||
x_source += (m[0][2]);
|
||||
y_source += (m[1][2]);
|
||||
|
||||
x_source_1 = (int)x_source;
|
||||
x_source_2 = x_source_1 + 1;
|
||||
y_source_1 = (int)y_source;
|
||||
y_source_2 = y_source_1 + 1;
|
||||
|
||||
quad_ul = (x_source_2 - x_source) * (y_source_2 - y_source);
|
||||
quad_ur = (1- (x_source_2 - x_source)) * (y_source_2 - y_source);
|
||||
quad_or = (x_source_2 - x_source) * (1-(y_source_2 - y_source));
|
||||
quad_ol = (1- (x_source_2 - x_source)) * (1-(y_source_2 - y_source));
|
||||
|
||||
|
||||
if ((x_source_1 >= 0) && (x_source_2 < org_width) && (y_source_1 >= 0) && (y_source_2 < org_height))
|
||||
{
|
||||
p_source_ul = rgb_image + (channels * (y_source_1 * org_width + x_source_1));
|
||||
p_source_ur = rgb_image + (channels * (y_source_1 * org_width + x_source_2));
|
||||
p_source_or = rgb_image + (channels * (y_source_2 * org_width + x_source_1));
|
||||
p_source_ol = rgb_image + (channels * (y_source_2 * org_width + x_source_2));
|
||||
for (int _channels = 0; _channels < channels; ++_channels)
|
||||
{
|
||||
p_target[_channels] = (int)((float)p_source_ul[_channels] * quad_ul
|
||||
+ (float)p_source_ur[_channels] * quad_ur
|
||||
+ (float)p_source_or[_channels] * quad_or
|
||||
+ (float)p_source_ol[_channels] * quad_ol);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int _channels = 0; _channels < channels; ++_channels)
|
||||
p_target[_channels] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
// memcpy(rgb_image, odata, memsize);
|
||||
memCopy(odata, rgb_image, memsize);
|
||||
|
||||
if (!ImageTMP)
|
||||
{
|
||||
free_psram_heap(std::string(TAG) + "->odata", odata);
|
||||
}
|
||||
if (ImageTMP)
|
||||
ImageTMP->RGBImageRelease();
|
||||
|
||||
RGBImageRelease();
|
||||
}
|
||||
|
||||
|
||||
void CRotateImage::Rotate(float _angle)
|
||||
{
|
||||
// ESP_LOGD(TAG, "width %d, height %d", width, height);
|
||||
Rotate(_angle, width / 2, height / 2);
|
||||
}
|
||||
|
||||
void CRotateImage::RotateAntiAliasing(float _angle)
|
||||
{
|
||||
// ESP_LOGD(TAG, "width %d, height %d", width, height);
|
||||
RotateAntiAliasing(_angle, width / 2, height / 2);
|
||||
}
|
||||
|
||||
void CRotateImage::Translate(int _dx, int _dy)
|
||||
{
|
||||
int memsize = width * height * channels;
|
||||
uint8_t* odata;
|
||||
if (ImageTMP)
|
||||
{
|
||||
odata = ImageTMP->RGBImageLock();
|
||||
}
|
||||
else
|
||||
{
|
||||
odata = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->odata", memsize, MALLOC_CAP_SPIRAM);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int x_source, y_source;
|
||||
stbi_uc* p_target;
|
||||
stbi_uc* p_source;
|
||||
|
||||
RGBImageLock();
|
||||
|
||||
for (int x = 0; x < width; ++x)
|
||||
for (int y = 0; y < height; ++y)
|
||||
{
|
||||
p_target = odata + (channels * (y * width + x));
|
||||
|
||||
x_source = x - _dx;
|
||||
y_source = y - _dy;
|
||||
|
||||
if ((x_source >= 0) && (x_source < width) && (y_source >= 0) && (y_source < height))
|
||||
{
|
||||
p_source = rgb_image + (channels * (y_source * width + x_source));
|
||||
for (int _channels = 0; _channels < channels; ++_channels)
|
||||
p_target[_channels] = p_source[_channels];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int _channels = 0; _channels < channels; ++_channels)
|
||||
p_target[_channels] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
// memcpy(rgb_image, odata, memsize);
|
||||
memCopy(odata, rgb_image, memsize);
|
||||
if (!ImageTMP)
|
||||
{
|
||||
free_psram_heap(std::string(TAG) + "->odata", odata);
|
||||
}
|
||||
|
||||
if (ImageTMP)
|
||||
{
|
||||
ImageTMP->RGBImageRelease();
|
||||
}
|
||||
RGBImageRelease();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,29 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef CROTATEIMAGE_H
|
||||
#define CROTATEIMAGE_H
|
||||
|
||||
#include "CImageBasis.h"
|
||||
|
||||
|
||||
class CRotateImage: public CImageBasis
|
||||
{
|
||||
|
||||
public:
|
||||
CImageBasis *ImageTMP, *ImageOrg;
|
||||
bool doflip;
|
||||
CRotateImage(std::string name, std::string _image, bool _flip = false) : CImageBasis(name, _image) {ImageTMP = NULL; ImageOrg = NULL; doflip = _flip;};
|
||||
CRotateImage(std::string name, uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp, bool _flip = false) : CImageBasis(name, _rgb_image, _channels, _width, _height, _bpp) {ImageTMP = NULL; ImageOrg = NULL; doflip = _flip;};
|
||||
CRotateImage(std::string name, CImageBasis *_org, CImageBasis *_temp, bool _flip = false);
|
||||
|
||||
void Rotate(float _angle);
|
||||
void RotateAntiAliasing(float _angle);
|
||||
|
||||
void Rotate(float _angle, int _centerx, int _centery);
|
||||
void RotateAntiAliasing(float _angle, int _centerx, int _centery);
|
||||
|
||||
void Translate(int _dx, int _dy);
|
||||
void Mirror();
|
||||
};
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef CROTATEIMAGE_H
|
||||
#define CROTATEIMAGE_H
|
||||
|
||||
#include "CImageBasis.h"
|
||||
|
||||
|
||||
class CRotateImage: public CImageBasis
|
||||
{
|
||||
|
||||
public:
|
||||
CImageBasis *ImageTMP, *ImageOrg;
|
||||
bool doflip;
|
||||
CRotateImage(std::string name, std::string _image, bool _flip = false) : CImageBasis(name, _image) {ImageTMP = NULL; ImageOrg = NULL; doflip = _flip;};
|
||||
CRotateImage(std::string name, uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp, bool _flip = false) : CImageBasis(name, _rgb_image, _channels, _width, _height, _bpp) {ImageTMP = NULL; ImageOrg = NULL; doflip = _flip;};
|
||||
CRotateImage(std::string name, CImageBasis *_org, CImageBasis *_temp, bool _flip = false);
|
||||
|
||||
void Rotate(float _angle);
|
||||
void RotateAntiAliasing(float _angle);
|
||||
|
||||
void Rotate(float _angle, int _centerx, int _centery);
|
||||
void RotateAntiAliasing(float _angle, int _centerx, int _centery);
|
||||
|
||||
void Translate(int _dx, int _dy);
|
||||
};
|
||||
|
||||
#endif //CROTATEIMAGE_H
|
||||
@@ -333,3 +333,17 @@ CTfLiteClass::~CTfLiteClass()
|
||||
|
||||
psram_free_shared_tensor_arena_and_model_memory();
|
||||
}
|
||||
|
||||
#ifdef SUPRESS_TFLITE_ERRORS
|
||||
namespace tflite
|
||||
{
|
||||
//tflite::ErrorReporter
|
||||
// int OwnMicroErrorReporter::Report(const char* format, va_list args)
|
||||
|
||||
int OwnMicroErrorReporter::Report(const char* format, va_list args)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
manifest_hash: 63f5c6c9f0bcebc7b9ca12d2aa8b26b2c5f5218d377dc4b2375d9b9ca1df7815
|
||||
target: esp32
|
||||
version: 1.0.0
|
||||
dependencies:
|
||||
espressif/esp-nn:
|
||||
component_hash: b32869798bdb40dec6bc99caca48cd65d42f8a9f506b9ab9c598a076f891ede9
|
||||
source:
|
||||
pre_release: true
|
||||
service_url: https://api.components.espressif.com/
|
||||
type: service
|
||||
version: 1.0.2
|
||||
idf:
|
||||
component_hash: null
|
||||
source:
|
||||
type: idf
|
||||
version: 5.1.2
|
||||
manifest_hash: a5f7be33336cfab90d6c2eb74757b616296d8c1e61665336749ed18905905567
|
||||
target: esp32
|
||||
version: 1.0.0
|
||||
|
||||
@@ -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
|
||||
@@ -190,7 +191,7 @@
|
||||
#define Digital_Uncertainty 0.2
|
||||
#define DigitalBand 3
|
||||
#define Digital_Transition_Range_Predecessor 2
|
||||
#define Digital_Transition_Area_Predecessor 0.7 // 9.3 - 0.7
|
||||
#define Digital_Transition_Area_Predecessor 1.0 // 9.0 - 1.0
|
||||
#define Digital_Transition_Area_Forward 9.7 // Pre-run zero crossing only happens from approx. 9.7 onwards
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -46,7 +46,7 @@ void test_analogToDigit_Standard() {
|
||||
// Default: dig=6.8, ana=8.6 => erg=7
|
||||
// Transition = no
|
||||
// Offset = no
|
||||
TEST_ASSERT_EQUAL_INT(7, undertest->PointerEvalAnalogToDigitNew( 6.8, 8.6, 6, 9.2));
|
||||
TEST_ASSERT_EQUAL_INT(7, undertest->PointerEvalAnalogToDigitNew( 6.8, 8.6, 8, 9.2));
|
||||
|
||||
// https://github.com/jomjol/AI-on-the-edge-device/issues/1143#issuecomment-1274434805
|
||||
// Also hanging digit () with small pointer after 0 pass.
|
||||
@@ -101,4 +101,4 @@ void test_analogToDigit_Transition() {
|
||||
// Special feature: Digit runs with analogue. Therefore 1.8 (vs. 7.8)
|
||||
TEST_ASSERT_EQUAL_INT(1, undertest->PointerEvalAnalogToDigitNew( 1.8, 7.8, 7, 7.7));
|
||||
|
||||
}
|
||||
}
|
||||
@@ -108,9 +108,13 @@ void test_ZeigerEvalHybrid() {
|
||||
|
||||
// pre = 9.9 (0.0 raw)
|
||||
// zahl = 1.8
|
||||
TEST_ASSERT_EQUAL(2, undertest.PointerEvalHybridNew(1.8, 9.0, 9));
|
||||
|
||||
// if a digit have an early transition and the pointer is < 9.0
|
||||
TEST_ASSERT_EQUAL(1, undertest.PointerEvalHybridNew(1.8, 9.0, 9));
|
||||
|
||||
// pre = 8.8 (0.0 raw)
|
||||
// zahl = 1.8
|
||||
TEST_ASSERT_EQUAL(2, undertest.PointerEvalHybridNew(1.8, 8.9, 8));
|
||||
|
||||
// if a digit have an early transition and the pointer is < 9.0
|
||||
// prev (pointer) = 6.2, but on digital readout = 6.0 (prev is int parameter)
|
||||
// zahl = 4.6
|
||||
TEST_ASSERT_EQUAL(4, undertest.PointerEvalHybridNew(4.6, 6.0, 6));
|
||||
@@ -120,5 +124,4 @@ void test_ZeigerEvalHybrid() {
|
||||
//TEST_ASSERT_EQUAL(7, undertest.ZeigerEvalHybrid(6.7, -1.0, -1));
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -109,7 +109,7 @@ void testNegative_Issues() {
|
||||
setAllowNegatives(underTestPost, false);
|
||||
setPreValue(underTestPost, preValue_extended);
|
||||
std::string result = process_doFlow(underTestPost);
|
||||
TEST_ASSERT_EQUAL_STRING("Neg. Rate - Read: - Raw: 22017.98 - Pre: 22018.08 ", underTestPost->getReadoutError().c_str());
|
||||
TEST_ASSERT_EQUAL_STRING("Neg. Rate - Read: - Raw: 22017.98 - Pre: 22018.09 ", underTestPost->getReadoutError().c_str());
|
||||
// if negativ no result any more
|
||||
|
||||
TEST_ASSERT_EQUAL_STRING("", result.c_str());
|
||||
|
||||
@@ -476,12 +476,18 @@ void test_doFlowPP3() {
|
||||
expected_extended= "126.9231";
|
||||
|
||||
// extendResolution=false
|
||||
result = process_doFlow(analogs, digits, Digital100, false, false, 0);
|
||||
undertestPost = init_do_flow(analogs, digits, Digital100, false, false, 0);
|
||||
setAnalogdigitTransistionStart(undertestPost, 9.4); // Extreme late transition
|
||||
result = process_doFlow(undertestPost);
|
||||
TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
|
||||
delete undertestPost;
|
||||
|
||||
// checkConsistency=false und extendResolution=true
|
||||
result = process_doFlow(analogs, digits, Digital100, false, true, 0);
|
||||
undertestPost = init_do_flow(analogs, digits, Digital100, false, true, 0);
|
||||
setAnalogdigitTransistionStart(undertestPost, 9.4); // Extreme late transition
|
||||
result = process_doFlow(undertestPost);
|
||||
TEST_ASSERT_EQUAL_STRING(expected_extended, result.c_str());
|
||||
delete undertestPost;
|
||||
|
||||
// Fehler V12.0.1
|
||||
// https://github.com/jomjol/AI-on-the-edge-device/issues/1110#issuecomment-1282168030
|
||||
@@ -543,12 +549,13 @@ void test_doFlowPP4() {
|
||||
|
||||
std::string postProcess(std::vector<float> digits,
|
||||
std::vector<float> analogs,
|
||||
float analog2DigitalTransition=0.0)
|
||||
float analog2DigitalTransition=0.0,
|
||||
int decimalShift=0)
|
||||
{
|
||||
std::unique_ptr<UnderTestPost> undertestPost(init_do_flow(std::move(analogs),
|
||||
std::move(digits),
|
||||
Digital100,
|
||||
false, false));
|
||||
false, false, decimalShift));
|
||||
|
||||
setAnalogdigitTransistionStart(undertestPost.get(), analog2DigitalTransition);
|
||||
return process_doFlow(undertestPost.get());
|
||||
@@ -557,37 +564,39 @@ std::string postProcess(std::vector<float> digits,
|
||||
void test_doFlowLateTransition()
|
||||
{
|
||||
// in these test cases, the last digit before comma turns 3.6 too late
|
||||
float a2dt = 3.6;
|
||||
float a2dt = 3.4; // value when last digit reaches x.8 region
|
||||
|
||||
// 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());
|
||||
// Questionable? (Meter shows 011.0210 but it already needs to be 012.0210, before transition)
|
||||
// Slider0007: In my opionion this series starts clearly with 11.x
|
||||
// As I remember right, this is a real series from rainman110, therefore the following cases
|
||||
// also needs to be corrected the same way
|
||||
TEST_ASSERT_EQUAL_STRING("11.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());
|
||||
TEST_ASSERT_EQUAL_STRING("11.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());
|
||||
TEST_ASSERT_EQUAL_STRING("11.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());
|
||||
TEST_ASSERT_EQUAL_STRING("11.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());
|
||||
TEST_ASSERT_EQUAL_STRING("12.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());
|
||||
TEST_ASSERT_EQUAL_STRING("12.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());
|
||||
TEST_ASSERT_EQUAL_STRING("12.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;
|
||||
float a2dt = 7.8; // value when last digit reaches x.8 region
|
||||
|
||||
// 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());
|
||||
@@ -597,8 +606,207 @@ void test_doFlowEarlyTransition()
|
||||
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());
|
||||
|
||||
}
|
||||
|
||||
|
||||
void test_doFlowEarlyTransitionEdgeCase()
|
||||
{
|
||||
float a2dt = 8.;
|
||||
|
||||
// Silder0007: In my opinion this is a unrealistic case {0.0, **0.0**, 9.9, 9,0}, {5.0, 0.0}
|
||||
// More realistic values: {0.0, 0.9, 9.9, 9,0}, {5.0, 0.0}
|
||||
TEST_ASSERT_EQUAL_STRING("99.50", postProcess({0.0, 0.0, 9.0, 9.0}, {5.0, 0.0}, a2dt).c_str());
|
||||
|
||||
// fails with 99.50
|
||||
TEST_ASSERT_EQUAL_STRING("199.50", postProcess({0.0, 1.0, 9.0, 9.0}, {5.0, 0.0}, a2dt).c_str());
|
||||
|
||||
TEST_ASSERT_EQUAL_STRING("99.95", postProcess({0.0, 1.0, 0.0, 0.0}, {9.5, 5.0}, a2dt).c_str());
|
||||
}
|
||||
|
||||
void test_doFlowIssue2857()
|
||||
{
|
||||
// reported by gec75
|
||||
float a2dt = 9.2;
|
||||
int decimalShift = 3;
|
||||
TEST_ASSERT_EQUAL_STRING("252090.0", postProcess({ 2.0, 5.0, 1.9}, { 0.8, 8.8, 9.9, 0.1},
|
||||
a2dt, decimalShift).c_str());
|
||||
|
||||
// reported by Kornelius777
|
||||
decimalShift = 0;
|
||||
TEST_ASSERT_EQUAL_STRING("1017.8099", postProcess({ 0.0, 1.0, 0.0, 1.0, 7.0}, { 8.2, 0.9, 9.9, 9.8},
|
||||
a2dt, decimalShift).c_str());
|
||||
|
||||
// with hanging digit
|
||||
TEST_ASSERT_EQUAL_STRING("1017.8099", postProcess({ 0.0, 1.0, 0.0, 1.0, 6.9}, { 8.2, 0.9, 9.9, 9.8},
|
||||
a2dt, decimalShift).c_str());
|
||||
|
||||
// and deccimal shift
|
||||
decimalShift = -2;
|
||||
TEST_ASSERT_EQUAL_STRING("10.178099", postProcess({ 0.0, 1.0, 0.0, 1.0, 6.9}, { 8.2, 0.9, 9.9, 9.8},
|
||||
a2dt, decimalShift).c_str());
|
||||
|
||||
|
||||
// reported by marcniedersachsen
|
||||
decimalShift = 0;
|
||||
TEST_ASSERT_EQUAL_STRING("778.1480", postProcess({ 0.0, 7.0, 7.0, 7.9}, { 1.4, 4.7, 8.0, 0.5},
|
||||
a2dt, decimalShift).c_str());
|
||||
|
||||
decimalShift = 3;
|
||||
TEST_ASSERT_EQUAL_STRING("778148.0", postProcess({ 0.0, 7.0, 7.0, 7.9}, { 1.4, 4.7, 8.0, 0.5},
|
||||
a2dt, decimalShift).c_str());
|
||||
|
||||
// reported by ohkaja
|
||||
decimalShift = 0;
|
||||
TEST_ASSERT_EQUAL_STRING("1052.6669", postProcess({ 0.0, 1.0, 10.0, 4.9, 2.0}, { 6.7, 6.7, 6.9, 9.1},
|
||||
a2dt, decimalShift).c_str());
|
||||
|
||||
// FrankCGN01
|
||||
decimalShift = -3;
|
||||
a2dt = 9.7;
|
||||
TEST_ASSERT_EQUAL_STRING("159.3659", postProcess({ 0.9, 4.8, 8.9, 3.0, 6.0, 5.0}, { 9.6},
|
||||
a2dt, decimalShift).c_str());
|
||||
|
||||
// Second test in https://github.com/jomjol/AI-on-the-edge-device/issues/2857#issuecomment-1937452352
|
||||
// The last digit seems to be falsely recongnized. It looks like a regular "2" (no transition)
|
||||
// but it is recognized by the inference as "2.5".
|
||||
decimalShift = -3;
|
||||
TEST_ASSERT_EQUAL_STRING("159.5022", postProcess({ 0.9, 4.9, 8.9, 5.0, 0.0, 2.5}, { 2.2},
|
||||
a2dt, decimalShift).c_str());
|
||||
|
||||
// reported by penapena
|
||||
// Note: this is a strange example, as the last digit (4.4) seems to have very early transition
|
||||
decimalShift = 0;
|
||||
TEST_ASSERT_EQUAL_STRING("124.4981", postProcess({ 0.0, 1.0, 2.0, 4.4}, { 5.1, 9.8, 8.3, 1.6},
|
||||
a2dt, decimalShift).c_str());
|
||||
|
||||
// reported by warnmat
|
||||
decimalShift = 0;
|
||||
TEST_ASSERT_EQUAL_STRING("51.653", postProcess({ 0.1, 0.1, 5.0, 1.0}, { 6.7, 5.4, 3.1},
|
||||
a2dt, decimalShift).c_str());
|
||||
}
|
||||
|
||||
|
||||
void test_doFlowLateTransitionHanging()
|
||||
{
|
||||
float a2dt = 3.6;
|
||||
|
||||
// haverland: this is the case if the analog pointer is a bit before the digit.
|
||||
// It's the normal late transition up to 2.0 on analog must the digit transition ends
|
||||
// After 2.0 on analog it named "hanging digit" by me. It never reach the x.0 until the next
|
||||
// transition begins.
|
||||
// BUT. It makes the issue you have later, because all other unter 3.6 are negative values now.
|
||||
TEST_ASSERT_EQUAL_STRING("12.1210", postProcess({0.0, 1.0, 1.9}, {1.2, 2.2, 1.0, 0.0}, a2dt).c_str());
|
||||
|
||||
// Questionable? (meter shows 012.4210 , this is after transition)
|
||||
// Slider0007: In my opionion this series starts with 11.x with this a2dt value
|
||||
// As I remember right, this is a real series from rainman110, therefore the following cases
|
||||
// also needs to be corrected the same way
|
||||
TEST_ASSERT_EQUAL_STRING("11.4210", postProcess({0.0, 1.0, 1.9}, {4.3, 2.2, 1.0, 0.0}, a2dt).c_str());
|
||||
|
||||
TEST_ASSERT_EQUAL_STRING("11.6210", postProcess({0.0, 1.0, 1.9}, {6.3, 2.2, 1.0, 0.0}, a2dt).c_str());
|
||||
|
||||
TEST_ASSERT_EQUAL_STRING("12.3610", postProcess({0.0, 1.0, 2.5}, {3.5, 6.2, 1.0, 0.0}, a2dt).c_str());
|
||||
|
||||
TEST_ASSERT_EQUAL_STRING("12.4510", postProcess({0.0, 1.0, 3.0}, {4.5, 5.2, 1.0, 0.0}, a2dt).c_str());
|
||||
|
||||
TEST_ASSERT_EQUAL_STRING("12.4510", postProcess({0.0, 1.0, 2.9}, {4.5, 5.2, 1.0, 0.0}, a2dt).c_str());
|
||||
}
|
||||
|
||||
|
||||
void test_doFlowPP_rainman110()
|
||||
{
|
||||
|
||||
// https://github.com/jomjol/AI-on-the-edge-device/issues/2743
|
||||
// --> Extreme early digit transition. AnanlogDigitTransition needs to set to 3.5 (was limited to 6)
|
||||
std::vector<float> digits = {4.0, 1.0, 1.8}; // wrong result: 412.3983
|
||||
std::vector<float> analogs = {3.6, 9.9, 8.1, 3.5};
|
||||
UnderTestPost* undertestPost = init_do_flow(analogs, digits, Digital100, false, false, 0);
|
||||
setAnalogdigitTransistionStart(undertestPost, 3.5);
|
||||
TEST_ASSERT_EQUAL_STRING("411.3983", process_doFlow(undertestPost).c_str());
|
||||
delete undertestPost;
|
||||
|
||||
// https://github.com/jomjol/AI-on-the-edge-device/pull/2887
|
||||
// --> Extreme early digit transition. AnanlogDigitTransition needs to set to 3.5 (was limited to 6)
|
||||
digits = {4.0, 1.0, 7.9}; // wrong result: 417.2579
|
||||
analogs = {2.5, 5.8, 7.7, 9.0};
|
||||
|
||||
undertestPost = init_do_flow(analogs, digits, Digital100, false, false, 0);
|
||||
setAnalogdigitTransistionStart(undertestPost, 3.5);
|
||||
TEST_ASSERT_EQUAL_STRING("418.2579", process_doFlow(undertestPost).c_str());
|
||||
delete undertestPost;
|
||||
|
||||
// Edge Case
|
||||
digits = {9.9, 9.4};
|
||||
analogs = {5.0, 0.0};
|
||||
|
||||
undertestPost = init_do_flow(analogs, digits, Digital100, false, false, 0);
|
||||
setAnalogdigitTransistionStart(undertestPost, 8.0);
|
||||
TEST_ASSERT_EQUAL_STRING("99.50", process_doFlow(undertestPost).c_str());
|
||||
delete undertestPost;
|
||||
|
||||
// Edge Case
|
||||
digits = {1.0, 0.0, 0.0};
|
||||
analogs = {9.5, 5.0};
|
||||
undertestPost = init_do_flow(analogs, digits, Digital100, false, false, 0);
|
||||
setAnalogdigitTransistionStart(undertestPost, 8.0);
|
||||
TEST_ASSERT_EQUAL_STRING("99.95", process_doFlow(undertestPost).c_str());
|
||||
delete undertestPost;
|
||||
|
||||
// https://github.com/jomjol/AI-on-the-edge-device/pull/2887
|
||||
// Discussion 149365.9 vs. 149364.9
|
||||
digits = {0.9, 4.8, 9.0, 3.0, 6.0, 5.0};
|
||||
analogs = {9.6};
|
||||
|
||||
undertestPost = init_do_flow(analogs, digits, Digital100, false, false, 0);
|
||||
setAnalogdigitTransistionStart(undertestPost, 9.2);
|
||||
TEST_ASSERT_EQUAL_STRING("149364.9", process_doFlow(undertestPost).c_str());
|
||||
delete undertestPost;
|
||||
}
|
||||
|
||||
|
||||
void test_doFlowPP_rainman110_transition()
|
||||
{
|
||||
// https://github.com/jomjol/AI-on-the-edge-device/pull/2887
|
||||
// Edge cases
|
||||
std::vector<float> digits = {4.0, 1.0, 7.9};
|
||||
std::vector<float> analogs = {1.4, 5.8, 7.7, 9.0};
|
||||
|
||||
UnderTestPost* undertestPost = init_do_flow(analogs, digits, Digital100, false, false, 0);
|
||||
setAnalogdigitTransistionStart(undertestPost, 3.5);
|
||||
std::string result = process_doFlow(undertestPost);
|
||||
TEST_ASSERT_EQUAL_STRING("418.1579", result.c_str());
|
||||
delete undertestPost;
|
||||
|
||||
// https://github.com/jomjol/AI-on-the-edge-device/pull/2887
|
||||
// Edge cases
|
||||
digits = {4.0, 1.0, 7.9};
|
||||
analogs = {3.4, 5.8, 7.7, 9.0};
|
||||
|
||||
undertestPost = init_do_flow(analogs, digits, Digital100, false, false, 0);
|
||||
setAnalogdigitTransistionStart(undertestPost, 3.5);
|
||||
result = process_doFlow(undertestPost);
|
||||
TEST_ASSERT_EQUAL_STRING("418.3579", result.c_str());
|
||||
delete undertestPost;
|
||||
|
||||
// https://github.com/jomjol/AI-on-the-edge-device/pull/2887
|
||||
// Edge cases
|
||||
digits = {4.0, 1.0, 8.5};
|
||||
analogs = {3.7, 5.8, 7.7, 9.0};
|
||||
|
||||
undertestPost = init_do_flow(analogs, digits, Digital100, false, false, 0);
|
||||
setAnalogdigitTransistionStart(undertestPost, 3.5);
|
||||
result = process_doFlow(undertestPost);
|
||||
TEST_ASSERT_EQUAL_STRING("418.3579", result.c_str());
|
||||
delete undertestPost;
|
||||
|
||||
// https://github.com/jomjol/AI-on-the-edge-device/pull/2887
|
||||
// Edge cases
|
||||
digits = {4.0, 1.0, 8.9};
|
||||
analogs = {4.0, 5.8, 7.7, 9.0};
|
||||
|
||||
undertestPost = init_do_flow(analogs, digits, Digital100, false, false, 0);
|
||||
setAnalogdigitTransistionStart(undertestPost, 3.5);
|
||||
result = process_doFlow(undertestPost);
|
||||
TEST_ASSERT_EQUAL_STRING("418.4579", result.c_str());
|
||||
delete undertestPost;
|
||||
}
|
||||
|
||||
@@ -138,6 +138,21 @@ void task_UnityTesting(void *pvParameter)
|
||||
RUN_TEST(test_doFlowPP3);
|
||||
printf("---------------------------------------------------------------------------\n");
|
||||
RUN_TEST(test_doFlowPP4);
|
||||
printf("---------------------------------------------------------------------------\n");
|
||||
RUN_TEST(test_doFlowLateTransition);
|
||||
printf("---------------------------------------------------------------------------\n");
|
||||
RUN_TEST(test_doFlowEarlyTransition);
|
||||
printf("---------------------------------------------------------------------------\n");
|
||||
RUN_TEST(test_doFlowEarlyTransitionEdgeCase);
|
||||
printf("---------------------------------------------------------------------------\n");
|
||||
RUN_TEST(test_doFlowIssue2857);
|
||||
printf("---------------------------------------------------------------------------\n");
|
||||
RUN_TEST(test_doFlowLateTransitionHanging);
|
||||
printf("---------------------------------------------------------------------------\n");
|
||||
RUN_TEST(test_doFlowPP_rainman110);
|
||||
printf("---------------------------------------------------------------------------\n");
|
||||
RUN_TEST(test_doFlowPP_rainman110_transition);
|
||||
|
||||
UNITY_END();
|
||||
|
||||
while(1);
|
||||
@@ -151,24 +166,9 @@ extern "C" void app_main()
|
||||
{
|
||||
initGPIO();
|
||||
Init_NVS_SDCard();
|
||||
esp_log_level_set("*", ESP_LOG_DEBUG); // set all components to ERROR level
|
||||
esp_log_level_set("*", ESP_LOG_ERROR); // set all components to ERROR level
|
||||
|
||||
UNITY_BEGIN();
|
||||
RUN_TEST(testNegative_Issues);
|
||||
RUN_TEST(testNegative);
|
||||
/*
|
||||
RUN_TEST(test_analogToDigit_Standard);
|
||||
RUN_TEST(test_analogToDigit_Transition);
|
||||
RUN_TEST(test_doFlowPP);
|
||||
RUN_TEST(test_doFlowPP1);
|
||||
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);
|
||||
*/
|
||||
UNITY_END();
|
||||
// Create dedicated testing task (heap size can be configured - large enough to handle a lot of testing cases)
|
||||
// ********************************************
|
||||
xTaskCreate(&task_UnityTesting, "task_UnityTesting", 12 * 1024, NULL, tskIDLE_PRIORITY+2, NULL);
|
||||
}
|
||||
|
||||
@@ -1,17 +1,32 @@
|
||||
demo
|
||||
WaitBeforeTakingPicture
|
||||
ImageQuality
|
||||
ImageSize
|
||||
LEDIntensity
|
||||
Brightness
|
||||
Contrast
|
||||
Saturation
|
||||
FixedExposure
|
||||
CamFrameSize
|
||||
CamGainceiling
|
||||
CamQuality
|
||||
CamAutoSharpness
|
||||
CamSharpness
|
||||
CamSpecialEffect
|
||||
CamWbMode
|
||||
CamAwb
|
||||
CamAwbGain
|
||||
CamAec
|
||||
CamAec2
|
||||
CamAeLevel
|
||||
CamAecValue
|
||||
CamAgc
|
||||
CamAgcGain
|
||||
CamBpc
|
||||
CamWpc
|
||||
CamRawGma
|
||||
CamLenc
|
||||
CamDcw
|
||||
CamZoom
|
||||
CamZoomSize
|
||||
CamZoomOffsetX
|
||||
CamZoomOffsetY
|
||||
demo
|
||||
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.
|
||||
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!
|
||||
|
||||
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.
|
||||
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!
|
||||
|
||||
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.
|
||||
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!
|
||||
|
||||
Image Brightness (`-2` .. `2`)
|
||||
|
||||
15
param-docs/parameter-pages/TakeImage/CamAeLevel.md
Normal file
15
param-docs/parameter-pages/TakeImage/CamAeLevel.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Parameter `CamAeLevel`
|
||||
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!
|
||||
|
||||
Auto-Exposure Compensation. Lower values produce darker image.
|
||||
|
||||
Range (`-2` .. `2`)
|
||||
13
param-docs/parameter-pages/TakeImage/CamAec.md
Normal file
13
param-docs/parameter-pages/TakeImage/CamAec.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# Parameter `CamAec`
|
||||
Default Value: `true`
|
||||
|
||||
!!! 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!
|
||||
|
||||
Auto-Exposure Control Algorithm
|
||||
13
param-docs/parameter-pages/TakeImage/CamAec2.md
Normal file
13
param-docs/parameter-pages/TakeImage/CamAec2.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# Parameter `CamAec2`
|
||||
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/CamAecValue.md
Normal file
15
param-docs/parameter-pages/TakeImage/CamAecValue.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Parameter `CamAecValue`
|
||||
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!
|
||||
|
||||
set Manuall-Exposure Control Value
|
||||
|
||||
Range (`0` .. `1200`)
|
||||
10
param-docs/parameter-pages/TakeImage/CamAgc.md
Normal file
10
param-docs/parameter-pages/TakeImage/CamAgc.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# Parameter `CamAgc`
|
||||
Default Value: `true`
|
||||
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
|
||||
!!! Note
|
||||
After changing this parameter you need to update your reference image and alignment markers!
|
||||
|
||||
This sets the Automatic Gain Control, how the camera responds to the overall level of light in the image.
|
||||
13
param-docs/parameter-pages/TakeImage/CamAgcGain.md
Normal file
13
param-docs/parameter-pages/TakeImage/CamAgcGain.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# Parameter `CamAgcGain`
|
||||
Default Value: ` `
|
||||
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
|
||||
!!! Note
|
||||
After changing this parameter you need to update your reference image and alignment markers!
|
||||
|
||||
!!! Note
|
||||
This is visible when AGC is off. Gain is an amplification of the values read from the image sensor.
|
||||
|
||||
Range (`0` .. `30`)
|
||||
13
param-docs/parameter-pages/TakeImage/CamAutoSharpness.md
Normal file
13
param-docs/parameter-pages/TakeImage/CamAutoSharpness.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# Parameter `CamAutoSharpness`
|
||||
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!
|
||||
|
||||
AutoSharpness
|
||||
10
param-docs/parameter-pages/TakeImage/CamAwb.md
Normal file
10
param-docs/parameter-pages/TakeImage/CamAwb.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# Parameter `CamAwb`
|
||||
Default Value: ` `
|
||||
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
|
||||
!!! Note
|
||||
After changing this parameter you need to update your reference image and alignment markers!
|
||||
|
||||
Auto White Balance
|
||||
10
param-docs/parameter-pages/TakeImage/CamAwbGain.md
Normal file
10
param-docs/parameter-pages/TakeImage/CamAwbGain.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# Parameter `CamAwbGain`
|
||||
Default Value: ` `
|
||||
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
|
||||
!!! Note
|
||||
After changing this parameter you need to update your reference image and alignment markers!
|
||||
|
||||
Auto White Balance Gain
|
||||
10
param-docs/parameter-pages/TakeImage/CamBpc.md
Normal file
10
param-docs/parameter-pages/TakeImage/CamBpc.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# Parameter `CamBpc`
|
||||
Default Value: `true`
|
||||
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
|
||||
!!! Note
|
||||
After changing this parameter you need to update your reference image and alignment markers!
|
||||
|
||||
Black Pixel Correction
|
||||
10
param-docs/parameter-pages/TakeImage/CamBrightness.md
Normal file
10
param-docs/parameter-pages/TakeImage/CamBrightness.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# Parameter `CamBrightness`
|
||||
Default Value: `0`
|
||||
|
||||
!!! 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!
|
||||
|
||||
Image Brightness (`-2` .. `2`)
|
||||
5
param-docs/parameter-pages/TakeImage/CamColorbar.md
Normal file
5
param-docs/parameter-pages/TakeImage/CamColorbar.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# Parameter `CamColorbar`
|
||||
Default Value: `false`
|
||||
|
||||
!!! Note
|
||||
This parameter can also be set on the Reference Image configuration page!
|
||||
11
param-docs/parameter-pages/TakeImage/CamContrast.md
Normal file
11
param-docs/parameter-pages/TakeImage/CamContrast.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# Parameter `CamContrast`
|
||||
Default Value: `0`
|
||||
|
||||
!!! 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!
|
||||
|
||||
Image Contrast (`-2` .. `2`)
|
||||
|
||||
13
param-docs/parameter-pages/TakeImage/CamDcw.md
Normal file
13
param-docs/parameter-pages/TakeImage/CamDcw.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# Parameter `CamDcw`
|
||||
Default Value: `true`
|
||||
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
|
||||
!!! Note
|
||||
After changing this parameter you need to update your reference image and alignment markers!
|
||||
|
||||
!!! Note
|
||||
When DCW is on, the image that you receive will be the size that you requested (VGA, QQVGA, etc).
|
||||
When DCW is off, the image that you receive will be one of UXGA, SVGA, or CIF. In other words, literally the actual image size as read from the sensor without any scaling.
|
||||
Note that if DCW is off, and you pick a different image size, this implicitly turns DCW back on again (although this isn't reflected in the options).
|
||||
10
param-docs/parameter-pages/TakeImage/CamDenoise.md
Normal file
10
param-docs/parameter-pages/TakeImage/CamDenoise.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# Parameter `CamDenoise`
|
||||
Default Value: ` `
|
||||
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
|
||||
!!! Note
|
||||
After changing this parameter you need to update your reference image and alignment markers!
|
||||
|
||||
Denoise Image (not supported)
|
||||
21
param-docs/parameter-pages/TakeImage/CamGainceiling.md
Normal file
21
param-docs/parameter-pages/TakeImage/CamGainceiling.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# Parameter `CamGainceiling`
|
||||
Default Value: `x2`
|
||||
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
|
||||
!!! Note
|
||||
After changing this parameter you need to update your reference image and alignment markers!
|
||||
|
||||
!!! Note
|
||||
This is visible when AGC is on.
|
||||
|
||||
Available options:
|
||||
|
||||
- `x2`
|
||||
- `x4`
|
||||
- `x8`
|
||||
- `x16`
|
||||
- `x32`
|
||||
- `x64`
|
||||
- `x128`
|
||||
10
param-docs/parameter-pages/TakeImage/CamHmirror.md
Normal file
10
param-docs/parameter-pages/TakeImage/CamHmirror.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# Parameter `CamHmirror`
|
||||
Default Value: `false`
|
||||
|
||||
!!! 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!
|
||||
|
||||
Option for initially mirroring the image on the original x-axis.
|
||||
10
param-docs/parameter-pages/TakeImage/CamLenc.md
Normal file
10
param-docs/parameter-pages/TakeImage/CamLenc.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# Parameter `CamLenc`
|
||||
Default Value: `true`
|
||||
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
|
||||
!!! Note
|
||||
After changing this parameter you need to update your reference image and alignment markers!
|
||||
|
||||
Lens Correction
|
||||
10
param-docs/parameter-pages/TakeImage/CamQuality.md
Normal file
10
param-docs/parameter-pages/TakeImage/CamQuality.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# Parameter `CamQuality`
|
||||
Default Value: `12`
|
||||
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
|
||||
Quality index for pictures: `8` (highest quality) ... `63` (lowest quality)
|
||||
|
||||
!!! Warning
|
||||
Value below 12 could result in system instabilities!
|
||||
10
param-docs/parameter-pages/TakeImage/CamRawGma.md
Normal file
10
param-docs/parameter-pages/TakeImage/CamRawGma.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# Parameter `CamRawGma`
|
||||
Default Value: ` `
|
||||
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
|
||||
!!! Note
|
||||
After changing this parameter you need to update your reference image and alignment markers!
|
||||
|
||||
RawGma
|
||||
11
param-docs/parameter-pages/TakeImage/CamSaturation.md
Normal file
11
param-docs/parameter-pages/TakeImage/CamSaturation.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# Parameter `CamSaturation`
|
||||
Default Value: `0`
|
||||
|
||||
!!! 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!
|
||||
|
||||
Image Saturation (`-2` .. `2`)
|
||||
|
||||
13
param-docs/parameter-pages/TakeImage/CamSharpness.md
Normal file
13
param-docs/parameter-pages/TakeImage/CamSharpness.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# Parameter `CamSharpness`
|
||||
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!
|
||||
|
||||
Range (`-2` .. `2`)
|
||||
21
param-docs/parameter-pages/TakeImage/CamSpecialEffect.md
Normal file
21
param-docs/parameter-pages/TakeImage/CamSpecialEffect.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# Parameter `CamSpecialEffect`
|
||||
Default Value: `no_effect`
|
||||
|
||||
!!! 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!
|
||||
|
||||
Available options:
|
||||
|
||||
- `no_effect`
|
||||
- `negative`
|
||||
- `grayscale`
|
||||
- `red`
|
||||
- `green`
|
||||
- `blue`
|
||||
- `retro`
|
||||
10
param-docs/parameter-pages/TakeImage/CamVflip.md
Normal file
10
param-docs/parameter-pages/TakeImage/CamVflip.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# Parameter `CamVflip`
|
||||
Default Value: `false`
|
||||
|
||||
!!! 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!
|
||||
|
||||
Option for initially flip the image on the original y-axis.
|
||||
18
param-docs/parameter-pages/TakeImage/CamWbMode.md
Normal file
18
param-docs/parameter-pages/TakeImage/CamWbMode.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# Parameter `CamWbMode`
|
||||
Default Value: `auto`
|
||||
|
||||
!!! 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!
|
||||
|
||||
White Balance Mode
|
||||
|
||||
Available options:
|
||||
|
||||
- `auto`
|
||||
- `sunny`
|
||||
- `cloudy`
|
||||
- `office`
|
||||
- `home`
|
||||
10
param-docs/parameter-pages/TakeImage/CamWpc.md
Normal file
10
param-docs/parameter-pages/TakeImage/CamWpc.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# Parameter `CamWpc`
|
||||
Default Value: `true`
|
||||
|
||||
!!! 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!
|
||||
|
||||
White Pixel Correction
|
||||
13
param-docs/parameter-pages/TakeImage/CamZoom.md
Normal file
13
param-docs/parameter-pages/TakeImage/CamZoom.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# Parameter `CamZoom`
|
||||
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.
|
||||
14
param-docs/parameter-pages/TakeImage/CamZoomOffsetX.md
Normal file
14
param-docs/parameter-pages/TakeImage/CamZoomOffsetX.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# Parameter `CamZoomOffsetX`
|
||||
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/CamZoomOffsetY.md
Normal file
14
param-docs/parameter-pages/TakeImage/CamZoomOffsetY.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# Parameter `CamZoomOffsetY`
|
||||
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.
|
||||
13
param-docs/parameter-pages/TakeImage/CamZoomSize.md
Normal file
13
param-docs/parameter-pages/TakeImage/CamZoomSize.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# Parameter `CamZoomSize`
|
||||
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!
|
||||
|
||||
`CamZoomSize` only applies when `Zoom` is enabled.
|
||||
@@ -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.
|
||||
BIN
sd-card/config/ana-cont_1300_s2.tflite
Normal file
BIN
sd-card/config/ana-cont_1300_s2.tflite
Normal file
Binary file not shown.
@@ -1,114 +1,136 @@
|
||||
[TakeImage]
|
||||
;RawImagesLocation = /log/source
|
||||
WaitBeforeTakingPicture = 5
|
||||
;RawImagesRetention = 15
|
||||
Brightness = 0
|
||||
Contrast = 0
|
||||
Saturation = 0
|
||||
LEDIntensity = 50
|
||||
ImageQuality = 12
|
||||
ImageSize = VGA
|
||||
FixedExposure = false
|
||||
Demo = false
|
||||
|
||||
[Alignment]
|
||||
InitialRotate = 0.0
|
||||
InitialMirror = false
|
||||
SearchFieldX = 20
|
||||
SearchFieldY = 20
|
||||
AlignmentAlgo = Default
|
||||
FlipImageSize = false
|
||||
/config/ref0.jpg 103 271
|
||||
/config/ref1.jpg 442 142
|
||||
|
||||
[Digits]
|
||||
Model = /config/dig-cont_0620_s3_q.tflite
|
||||
CNNGoodThreshold = 0.5
|
||||
;ROIImagesLocation = /log/digit
|
||||
;ROIImagesRetention = 3
|
||||
main.dig1 294 126 30 54 false
|
||||
main.dig2 343 126 30 54 false
|
||||
main.dig3 391 126 30 54 false
|
||||
|
||||
[Analog]
|
||||
Model = /config/ana-cont_1208_s2_q.tflite
|
||||
CNNGoodThreshold = 0.5
|
||||
;ROIImagesLocation = /log/analog
|
||||
;ROIImagesRetention = 3
|
||||
main.ana1 432 230 92 92 false
|
||||
main.ana2 379 332 92 92 false
|
||||
main.ana3 283 374 92 92 false
|
||||
main.ana4 155 328 92 92 false
|
||||
|
||||
[PostProcessing]
|
||||
main.DecimalShift = 0
|
||||
main.AnalogDigitalTransitionStart = 9.2
|
||||
PreValueUse = true
|
||||
PreValueAgeStartup = 720
|
||||
main.AllowNegativeRates = false
|
||||
main.MaxRateValue = 0.05
|
||||
;main.MaxRateType = AbsoluteChange
|
||||
main.ExtendedResolution = false
|
||||
main.IgnoreLeadingNaN = false
|
||||
ErrorMessage = true
|
||||
CheckDigitIncreaseConsistency = false
|
||||
|
||||
;[MQTT]
|
||||
;Uri = mqtt://IP-ADRESS:1883
|
||||
;MainTopic = watermeter
|
||||
;ClientID = watermeter
|
||||
;user = USERNAME
|
||||
;password = PASSWORD
|
||||
RetainMessages = false
|
||||
HomeassistantDiscovery = false
|
||||
;MeterType = other
|
||||
;CACert = /config/certs/RootCA.pem
|
||||
;ClientCert = /config/certs/client.pem.crt
|
||||
;ClientKey = /config/certs/client.pem.key
|
||||
|
||||
;[InfluxDB]
|
||||
;Uri = undefined
|
||||
;Database = undefined
|
||||
;Measurement = undefined
|
||||
;user = undefined
|
||||
;password = undefined
|
||||
|
||||
;[InfluxDBv2]
|
||||
;Uri = undefined
|
||||
;Bucket = undefined
|
||||
;Measurement = undefined
|
||||
;Org = undefined
|
||||
;Token = undefined
|
||||
;main.Fieldname = undefined
|
||||
|
||||
;[GPIO]
|
||||
;MainTopicMQTT = wasserzaehler/GPIO
|
||||
;IO0 = input disabled 10 false false
|
||||
;IO1 = input disabled 10 false false
|
||||
;IO3 = input disabled 10 false false
|
||||
;IO4 = built-in-led disabled 10 false false
|
||||
;IO12 = input-pullup disabled 10 false false
|
||||
;IO13 = input-pullup disabled 10 false false
|
||||
LEDType = WS2812
|
||||
LEDNumbers = 2
|
||||
LEDColor = 150 150 150
|
||||
|
||||
[AutoTimer]
|
||||
AutoStart = true
|
||||
Interval = 5
|
||||
|
||||
[DataLogging]
|
||||
DataLogActive = true
|
||||
DataFilesRetention = 3
|
||||
|
||||
[Debug]
|
||||
LogLevel = 1
|
||||
LogfilesRetention = 3
|
||||
|
||||
[System]
|
||||
TimeZone = CET-1CEST,M3.5.0,M10.5.0/3
|
||||
;TimeServer = pool.ntp.org
|
||||
;Hostname = undefined
|
||||
RSSIThreshold = -75
|
||||
CPUFrequency = 160
|
||||
SetupMode = true
|
||||
[TakeImage]
|
||||
;RawImagesLocation = /log/source
|
||||
;RawImagesRetention = 15
|
||||
WaitBeforeTakingPicture = 2
|
||||
CamGainceiling = x4
|
||||
CamQuality = 8
|
||||
CamBrightness = 0
|
||||
CamContrast = 0
|
||||
CamSaturation = 0
|
||||
CamSharpness = 1
|
||||
CamAutoSharpness = false
|
||||
CamSpecialEffect = no_effect
|
||||
CamWbMode = auto
|
||||
CamAwb = true
|
||||
CamAwbGain = true
|
||||
CamAec = true
|
||||
CamAec2 = true
|
||||
CamAeLevel = 2
|
||||
CamAecValue = 500
|
||||
CamAgc = true
|
||||
CamAgcGain = 0
|
||||
CamBpc = true
|
||||
CamWpc = true
|
||||
CamRawGma = true
|
||||
CamLenc = true
|
||||
CamHmirror = false
|
||||
CamVflip = false
|
||||
CamDcw = true
|
||||
CamZoom = false
|
||||
CamZoomOffsetX = 0
|
||||
CamZoomOffsetY = 0
|
||||
CamZoomSize = 0
|
||||
LEDIntensity = 50
|
||||
Demo = false
|
||||
|
||||
[Alignment]
|
||||
InitialRotate = 0.0
|
||||
InitialMirror = false
|
||||
SearchFieldX = 20
|
||||
SearchFieldY = 20
|
||||
AlignmentAlgo = Default
|
||||
FlipImageSize = false
|
||||
/config/ref0.jpg 103 271
|
||||
/config/ref1.jpg 442 142
|
||||
|
||||
[Digits]
|
||||
Model = /config/dig-cont_0700_s3_q.tflite
|
||||
CNNGoodThreshold = 0.5
|
||||
;ROIImagesLocation = /log/digit
|
||||
;ROIImagesRetention = 3
|
||||
main.dig1 294 126 30 54 false
|
||||
main.dig2 343 126 30 54 false
|
||||
main.dig3 391 126 30 54 false
|
||||
|
||||
[Analog]
|
||||
Model = /config/ana-cont_1300_s2.tflite
|
||||
CNNGoodThreshold = 0.5
|
||||
;ROIImagesLocation = /log/analog
|
||||
;ROIImagesRetention = 3
|
||||
main.ana1 432 230 92 92 false
|
||||
main.ana2 379 332 92 92 false
|
||||
main.ana3 283 374 92 92 false
|
||||
main.ana4 155 328 92 92 false
|
||||
|
||||
[PostProcessing]
|
||||
main.DecimalShift = 0
|
||||
main.AnalogDigitalTransitionStart = 9.2
|
||||
PreValueUse = true
|
||||
PreValueAgeStartup = 720
|
||||
main.AllowNegativeRates = false
|
||||
main.MaxRateValue = 0.05
|
||||
;main.MaxRateType = AbsoluteChange
|
||||
main.ExtendedResolution = false
|
||||
main.IgnoreLeadingNaN = false
|
||||
ErrorMessage = true
|
||||
CheckDigitIncreaseConsistency = false
|
||||
|
||||
;[MQTT]
|
||||
;Uri = mqtt://IP-ADRESS:1883
|
||||
;MainTopic = watermeter
|
||||
;ClientID = watermeter
|
||||
;user = USERNAME
|
||||
;password = PASSWORD
|
||||
RetainMessages = false
|
||||
HomeassistantDiscovery = false
|
||||
;MeterType = other
|
||||
;CACert = /config/certs/RootCA.pem
|
||||
;ClientCert = /config/certs/client.pem.crt
|
||||
;ClientKey = /config/certs/client.pem.key
|
||||
|
||||
;[InfluxDB]
|
||||
;Uri = undefined
|
||||
;Database = undefined
|
||||
;Measurement = undefined
|
||||
;user = undefined
|
||||
;password = undefined
|
||||
|
||||
;[InfluxDBv2]
|
||||
;Uri = undefined
|
||||
;Bucket = undefined
|
||||
;Measurement = undefined
|
||||
;Org = undefined
|
||||
;Token = undefined
|
||||
;main.Fieldname = undefined
|
||||
|
||||
;[GPIO]
|
||||
;MainTopicMQTT = wasserzaehler/GPIO
|
||||
;IO0 = input disabled 10 false false
|
||||
;IO1 = input disabled 10 false false
|
||||
;IO3 = input disabled 10 false false
|
||||
;IO4 = built-in-led disabled 10 false false
|
||||
;IO12 = input-pullup disabled 10 false false
|
||||
;IO13 = input-pullup disabled 10 false false
|
||||
LEDType = WS2812
|
||||
LEDNumbers = 2
|
||||
LEDColor = 150 150 150
|
||||
|
||||
[AutoTimer]
|
||||
AutoStart = true
|
||||
Interval = 5
|
||||
|
||||
[DataLogging]
|
||||
DataLogActive = true
|
||||
DataFilesRetention = 3
|
||||
|
||||
[Debug]
|
||||
LogLevel = 1
|
||||
LogfilesRetention = 3
|
||||
|
||||
[System]
|
||||
TimeZone = CET-1CEST,M3.5.0,M10.5.0/3
|
||||
;TimeServer = pool.ntp.org
|
||||
;Hostname = undefined
|
||||
RSSIThreshold = -75
|
||||
CPUFrequency = 160
|
||||
SetupMode = true
|
||||
|
||||
BIN
sd-card/config/dig-class11_1701_s2.tflite
Normal file
BIN
sd-card/config/dig-class11_1701_s2.tflite
Normal file
Binary file not shown.
BIN
sd-card/config/dig-cont_0640_s3_q.tflite
Normal file
BIN
sd-card/config/dig-cont_0640_s3_q.tflite
Normal file
Binary file not shown.
BIN
sd-card/config/dig-cont_0700_s3_q.tflite
Normal file
BIN
sd-card/config/dig-cont_0700_s3_q.tflite
Normal file
Binary file not shown.
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>
|
||||
@@ -113,86 +113,120 @@
|
||||
<hr />
|
||||
|
||||
<table>
|
||||
<colgroup>
|
||||
<col span="1" style="width: 33.3%;">
|
||||
<col span="1" style="width: 33.3%;">
|
||||
<col span="1" style="width: 33.3%;">
|
||||
</colgroup>
|
||||
<tr>
|
||||
<td>Marker:
|
||||
<select id="index" name="reference" onchange="ChangeSelection()">
|
||||
<option value="0" selected>Marker 1</option>
|
||||
<option value="1" >Marker 2</option>
|
||||
</select>
|
||||
</td>
|
||||
<td colspan="2" style="padding-left: 22px; color: grey;">Filename: <output type="text" name="name" id="name" onchange="namechanged()"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding-top: 10px">x: <input type="number" name="refx" id="refx" step=1 onchange="valuemanualchanged()"></td>
|
||||
<td style="padding-top: 10px">dx: <input type="number" name="refdx" id="refdx" step=1 onchange="valuemanualchanged()"></td>
|
||||
<td rowspan="2" style="padding-top: 10px;"><input class="button" type="button" value="Update Marker" onclick="CutOutReference()"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>y: <input type="number" name="refy" id="refy" step=1 onchange="valuemanualchanged()"></td>
|
||||
<td>dy: <input type="number" name="refdy" id="refdy" step=1 onchange="valuemanualchanged()"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: bottom;">Selected Image Area:</td>
|
||||
<td style="vertical-align: bottom;">Resulting Marker:</td>
|
||||
<td><input class="button" type="button" id="enhancecontrast" value="Enhance Image Contrast" onclick="EnhanceContrast()"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="height:70px; vertical-align: top;"><img id="img_ref_org" src = ""></td> <!--/img_tmp/ref_zw_org.jpg-->
|
||||
<td style="height:70px; vertical-align: top;"><img id="img_ref" src = ""></td> <!--/img_tmp/ref_zw.jpg-->
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align:bottom;"><b>Reference Image:</b></td>
|
||||
<td></td>
|
||||
<td><input style="font-weight:bold;" class="button" type="submit" name="saveroi" id="savemarker" onclick="SaveToConfig()" value="Save New Marker">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="3"><canvas id="canvas" crossorigin></canvas></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<colgroup>
|
||||
<col span="1" style="width: 33.3%;">
|
||||
<col span="1" style="width: 33.3%;">
|
||||
<col span="1" style="width: 33.3%;">
|
||||
</colgroup>
|
||||
|
||||
<tr>
|
||||
<td>Marker:
|
||||
<select id="index" name="reference" onchange="ChangeSelection()">
|
||||
<option value="0" selected>Marker 1</option>
|
||||
<option value="1" >Marker 2</option>
|
||||
</select>
|
||||
</td>
|
||||
<td colspan="2" style="padding-left: 22px; color: grey;">Filename: <output type="text" name="name" id="name" onchange="namechanged()"></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td style="padding-top: 10px">x: <input type="number" name="refx" id="refx" step=1 onchange="valuemanualchanged()"></td>
|
||||
<td style="padding-top: 10px">dx: <input type="number" name="refdx" id="refdx" step=1 onchange="valuemanualchanged()"></td>
|
||||
<td rowspan="2" style="padding-top: 10px;"><input class="button" type="button" value="Update Marker" onclick="CutOutReference()"></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>y: <input type="number" name="refy" id="refy" step=1 onchange="valuemanualchanged()"></td>
|
||||
<td>dy: <input type="number" name="refdy" id="refdy" step=1 onchange="valuemanualchanged()"></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td style="vertical-align: bottom;">Selected Image Area:</td>
|
||||
<td style="vertical-align: bottom;">Resulting Marker:</td>
|
||||
<td><input class="button" type="button" id="enhancecontrast" value="Enhance Image Contrast" onclick="EnhanceContrast()"></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td style="height:70px; vertical-align: top;"><img id="img_ref_org" src = ""></td> <!--/img_tmp/ref_zw_org.jpg-->
|
||||
<td style="height:70px; vertical-align: top;"><img id="img_ref" src = ""></td> <!--/img_tmp/ref_zw.jpg-->
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td style="vertical-align:bottom;"><b>Reference Image:</b></td>
|
||||
<td></td>
|
||||
<td>
|
||||
<input style="font-weight:bold;" class="button" type="submit" name="saveroi" id="savemarker" onclick="SaveToConfig()" value="Save New Marker">
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td colspan="3"><canvas id="canvas" crossorigin></canvas></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<script type="text/javascript" src="common.js?v=$COMMIT_HASH"></script>
|
||||
<script type="text/javascript" src="readconfigcommon.js?v=$COMMIT_HASH"></script>
|
||||
<script type="text/javascript" src="readconfigparam.js?v=$COMMIT_HASH"></script>
|
||||
|
||||
<script language="JavaScript">
|
||||
var canvas = document.getElementById('canvas'),
|
||||
ctx = canvas.getContext('2d'),
|
||||
imageObj = new Image(),
|
||||
rect = {},
|
||||
drag = false,
|
||||
aktindex = 0,
|
||||
refInfo,
|
||||
enhanceCon = false,
|
||||
param;
|
||||
domainname = getDomainname();
|
||||
param;
|
||||
var canvas = document.getElementById('canvas'),
|
||||
ctx = canvas.getContext('2d'),
|
||||
imageObj = new Image(),
|
||||
rect = {},
|
||||
drag = false,
|
||||
aktindex = 0,
|
||||
refInfo,
|
||||
enhanceCon = false,
|
||||
domainname = getDomainname(),
|
||||
neueref1,
|
||||
neueref2,
|
||||
cofcat,
|
||||
param;
|
||||
|
||||
function doReboot() {
|
||||
if (confirm("Are you sure you want to reboot? Did you save your changes?")) {
|
||||
var stringota = getDomainname() + "/reboot";
|
||||
window.location = stringota;
|
||||
window.location.href = stringota;
|
||||
window.location.assign(stringota);
|
||||
window.location.replace(stringota);
|
||||
if (confirm("Are you sure you want to reboot? Did you save your changes?")) {
|
||||
var stringota = getDomainname() + "/reboot";
|
||||
window.location = stringota;
|
||||
window.location.href = stringota;
|
||||
window.location.assign(stringota);
|
||||
window.location.replace(stringota);
|
||||
}
|
||||
}
|
||||
|
||||
function ChangeSelection(){
|
||||
aktindex = parseInt(document.getElementById("index").value);
|
||||
UpdateReference();
|
||||
|
||||
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 +242,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 +253,17 @@ function EnhanceContrast(){
|
||||
|
||||
async function task() {
|
||||
while (true) {
|
||||
var ret = MakeContrastImageZW(refInfo[aktindex], enhanceCon, domainname);
|
||||
if (ret) {
|
||||
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 {
|
||||
@@ -258,8 +298,7 @@ function UpdateReference(){
|
||||
draw();
|
||||
}
|
||||
|
||||
_filenameurl = refInfo[aktindex]["name"].replace("/config/", "/img_tmp/");
|
||||
|
||||
var _filenameurl = refInfo[aktindex]["name"].replace("/config/", "/img_tmp/");
|
||||
var url = domainname + "/fileserver" + _filenameurl + "?" + Date.now();
|
||||
document.getElementById("img_ref").src = url;
|
||||
|
||||
@@ -276,260 +315,291 @@ 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) {
|
||||
var canvas = document.getElementById('canvas');
|
||||
var context = canvas.getContext('2d');
|
||||
|
||||
function loadCanvas(dataURL) {
|
||||
var canvas = document.getElementById('canvas');
|
||||
var context = canvas.getContext('2d');
|
||||
imageObj.onload = function() {
|
||||
canvas.width = this.width;
|
||||
canvas.height = this.height;
|
||||
drawImage();
|
||||
};
|
||||
|
||||
imageObj.onload = function() {
|
||||
canvas.width = this.width;
|
||||
canvas.height = this.height;
|
||||
drawImage();
|
||||
};
|
||||
imageObj.src = dataURL;
|
||||
}
|
||||
|
||||
imageObj.src = dataURL;
|
||||
}
|
||||
|
||||
|
||||
function getCoords(elem) { // crossbrowser version
|
||||
var box = elem.getBoundingClientRect();
|
||||
var body = document.body;
|
||||
var docEl = document.documentElement;
|
||||
var scrollTop = window.pageYOffset || docEl.scrollTop || body.scrollTop;
|
||||
var scrollLeft = window.pageXOffset || docEl.scrollLeft || body.scrollLeft;
|
||||
var clientTop = docEl.clientTop || body.clientTop || 0;
|
||||
var clientLeft = docEl.clientLeft || body.clientLeft || 0;
|
||||
var top = box.top + scrollTop - clientTop;
|
||||
var left = box.left + scrollLeft - clientLeft;
|
||||
return { top: Math.round(top), left: Math.round(left) };
|
||||
}
|
||||
|
||||
|
||||
/* hash #description open the details part of the page */
|
||||
function openDescription() {
|
||||
if(window.location.hash) {
|
||||
var hash = window.location.hash.substring(1); //Puts hash in variable, and removes the # character
|
||||
if(hash == 'description')
|
||||
document.getElementById("desc_details").open = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function init() {
|
||||
openDescription();
|
||||
domainname = getDomainname();
|
||||
loadConfig(domainname);
|
||||
ParseConfig();
|
||||
param = getConfigParameters();
|
||||
|
||||
document.getElementById("savemarker").disabled = true;
|
||||
document.getElementById("enhancecontrast").disabled = true;
|
||||
|
||||
canvas.addEventListener('mousedown', mouseDown, false);
|
||||
canvas.addEventListener('mouseup', mouseUp, false);
|
||||
canvas.addEventListener('mousemove', mouseMove, false);
|
||||
loadCanvas(domainname + "/fileserver/config/reference.jpg");
|
||||
|
||||
CopyReferenceToImgTmp(domainname);
|
||||
refInfo = GetReferencesInfo();
|
||||
|
||||
UpdateReference();
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
document.getElementById("overlay").style.display = "block";
|
||||
document.getElementById("overlaytext").innerHTML = "Updating marker...";
|
||||
|
||||
function sleep(ms) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
async function task() {
|
||||
while (true) {
|
||||
var ret = MakeRefZW(refInfo[aktindex], domainname);
|
||||
if (ret) {
|
||||
UpdateReference();
|
||||
document.getElementById("enhancecontrast").disabled = false;
|
||||
document.getElementById("savemarker").disabled = false;
|
||||
document.getElementById("overlay").style.display = "none";
|
||||
return;
|
||||
}
|
||||
else {
|
||||
// Get status
|
||||
var xhttp = new XMLHttpRequest();
|
||||
try {
|
||||
xhttp.open("GET", domainname + "/statusflow", false);
|
||||
xhttp.send();
|
||||
}
|
||||
catch (error){}
|
||||
|
||||
document.getElementById("overlaytext").innerHTML = "Device is busy, waiting until the Digitalization Round got completed (this can take several minutes)...<br><br>Current step: " + xhttp.responseText;
|
||||
console.log("Device is busy, waiting 5s then checking again...");
|
||||
await sleep(5000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setTimeout(function() { // Delay so the overlay gets shown
|
||||
task();
|
||||
}, 1);
|
||||
}
|
||||
|
||||
function drawGrid(){
|
||||
var canvas = document.getElementById('canvas');
|
||||
var ctx = canvas.getContext('2d');
|
||||
w = canvas.width;
|
||||
h = canvas.height;
|
||||
ctx.save();
|
||||
ctx.strokeStyle = '#00FF00';
|
||||
|
||||
for (i = h/2; i < h; i += 100)
|
||||
{
|
||||
ctx.moveTo(0, i);
|
||||
ctx.lineTo(w, i);
|
||||
ctx.stroke();
|
||||
ctx.moveTo(0, h-i);
|
||||
ctx.lineTo(w, h-i);
|
||||
ctx.stroke();
|
||||
}
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
function draw() {
|
||||
var canvas = document.getElementById('canvas');
|
||||
var context = canvas.getContext('2d');
|
||||
context.drawImage(imageObj, 0, 0);
|
||||
lw = 4
|
||||
context.lineWidth = lw;
|
||||
context.strokeStyle = "#FF0000";
|
||||
var x0 = parseInt(rect.startX) - parseInt(lw/2);
|
||||
var y0 = parseInt(rect.startY) - parseInt(lw/2);
|
||||
var dx = parseInt(rect.w) + parseInt(lw);
|
||||
var dy = parseInt(rect.h) + parseInt(lw);
|
||||
context.strokeRect(x0, y0, dx, dy);
|
||||
}
|
||||
|
||||
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;
|
||||
function getCoords(elem) { // crossbrowser version
|
||||
var box = elem.getBoundingClientRect();
|
||||
var body = document.body;
|
||||
var docEl = document.documentElement;
|
||||
var scrollTop = window.pageYOffset || docEl.scrollTop || body.scrollTop;
|
||||
var scrollLeft = window.pageXOffset || docEl.scrollLeft || body.scrollLeft;
|
||||
var clientTop = docEl.clientTop || body.clientTop || 0;
|
||||
var clientLeft = docEl.clientLeft || body.clientLeft || 0;
|
||||
var top = box.top + scrollTop - clientTop;
|
||||
var left = box.left + scrollLeft - clientLeft;
|
||||
return { top: Math.round(top), left: Math.round(left) };
|
||||
}
|
||||
|
||||
/* hash #description open the details part of the page */
|
||||
function openDescription() {
|
||||
if(window.location.hash) {
|
||||
var hash = window.location.hash.substring(1); //Puts hash in variable, and removes the # character
|
||||
if(hash == 'description') {
|
||||
document.getElementById("desc_details").open = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function mouseDown(e) {
|
||||
zw = getCoords(this)
|
||||
rect.startX = e.pageX - zw.left;
|
||||
rect.startY = e.pageY - zw.top;
|
||||
document.getElementById("refx").value = rect.startX;
|
||||
document.getElementById("refy").value = rect.startY;
|
||||
drag = true;
|
||||
function 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 mouseUp() {
|
||||
drag = false;
|
||||
if (rect.w < 0) {
|
||||
rect.w = -rect.w
|
||||
rect.startX-=rect.w
|
||||
var _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();
|
||||
|
||||
if (!loadConfig(domainname)) {
|
||||
firework.launch('Configuration could not be loaded! Please reload the page!', 'danger', 30000);
|
||||
return;
|
||||
}
|
||||
|
||||
ParseConfig();
|
||||
param = getConfigParameters();
|
||||
cofcat = getConfigCategory();
|
||||
|
||||
document.getElementById("savemarker").disabled = true;
|
||||
document.getElementById("enhancecontrast").disabled = true;
|
||||
|
||||
canvas.addEventListener('mousedown', mouseDown, false);
|
||||
canvas.addEventListener('mouseup', mouseUp, false);
|
||||
canvas.addEventListener('mousemove', mouseMove, false);
|
||||
loadCanvas(domainname + "/fileserver/config/reference.jpg");
|
||||
|
||||
//CopyReferenceToImgTmp(domainname);
|
||||
refInfo = GetReferencesInfo();
|
||||
|
||||
//UpdateReference();
|
||||
LoadReference();
|
||||
drawImage();
|
||||
draw();
|
||||
}
|
||||
|
||||
function drawImage(){
|
||||
var canvas = document.getElementById('canvas');
|
||||
var context = canvas.getContext('2d');
|
||||
|
||||
context.clearRect(0,0,imageObj.width,imageObj.height);
|
||||
context.save();
|
||||
context.drawImage(imageObj, 0, 0);
|
||||
// context.restore();
|
||||
}
|
||||
|
||||
function 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...";
|
||||
|
||||
function sleep(ms) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
async function task() {
|
||||
while (true) {
|
||||
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;
|
||||
}
|
||||
if (rect.h < 0) {
|
||||
rect.h = -rect.h
|
||||
rect.startY-=rect.h
|
||||
else {
|
||||
// Get status
|
||||
var xhttp = new XMLHttpRequest();
|
||||
try {
|
||||
xhttp.open("GET", domainname + "/statusflow", false);
|
||||
xhttp.send();
|
||||
}
|
||||
catch (error){}
|
||||
|
||||
document.getElementById("overlaytext").innerHTML = "Device is busy, waiting until the Digitalization Round got completed (this can take several minutes)...<br><br>Current step: " + xhttp.responseText;
|
||||
console.log("Device is busy, waiting 5s then checking again...");
|
||||
await sleep(5000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setTimeout(function() { // Delay so the overlay gets shown
|
||||
task();
|
||||
}, 1);
|
||||
}
|
||||
|
||||
function drawGrid(){
|
||||
var canvas = document.getElementById('canvas');
|
||||
var ctx = canvas.getContext('2d');
|
||||
var w = canvas.width;
|
||||
var h = canvas.height;
|
||||
ctx.save();
|
||||
ctx.strokeStyle = '#00FF00';
|
||||
|
||||
for (i = h/2; i < h; i += 100) {
|
||||
ctx.moveTo(0, i);
|
||||
ctx.lineTo(w, i);
|
||||
ctx.stroke();
|
||||
ctx.moveTo(0, h-i);
|
||||
ctx.lineTo(w, h-i);
|
||||
ctx.stroke();
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
function draw() {
|
||||
var canvas = document.getElementById('canvas');
|
||||
var context = canvas.getContext('2d');
|
||||
context.drawImage(imageObj, 0, 0);
|
||||
var lw = 4
|
||||
context.lineWidth = lw;
|
||||
context.strokeStyle = "#FF0000";
|
||||
var x0 = parseInt(rect.startX) - parseInt(lw/2);
|
||||
var y0 = parseInt(rect.startY) - parseInt(lw/2);
|
||||
var dx = parseInt(rect.w) + parseInt(lw);
|
||||
var dy = parseInt(rect.h) + parseInt(lw);
|
||||
context.strokeRect(x0, y0, dx, dy);
|
||||
}
|
||||
|
||||
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() {
|
||||
drag = false;
|
||||
|
||||
if (rect.w < 0) {
|
||||
rect.w = -rect.w
|
||||
rect.startX-=rect.w
|
||||
}
|
||||
|
||||
if (rect.h < 0) {
|
||||
rect.h = -rect.h
|
||||
rect.startY-=rect.h
|
||||
}
|
||||
|
||||
document.getElementById("refdx").value = rect.w;
|
||||
document.getElementById("refdy").value = rect.h;
|
||||
document.getElementById("refx").value = rect.startX;
|
||||
document.getElementById("refy").value = rect.startY;
|
||||
}
|
||||
|
||||
function mouseMove(e) {
|
||||
if (drag) {
|
||||
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;
|
||||
document.getElementById("refdy").value = rect.h;
|
||||
document.getElementById("refx").value = rect.startX;
|
||||
document.getElementById("refy").value = rect.startY;
|
||||
draw();
|
||||
}
|
||||
else {
|
||||
draw();
|
||||
var canvas = document.getElementById('canvas');
|
||||
var context = canvas.getContext('2d');
|
||||
|
||||
function mouseMove(e) {
|
||||
if (drag) {
|
||||
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;
|
||||
document.getElementById("refdy").value = rect.h;
|
||||
draw();
|
||||
}
|
||||
else {
|
||||
draw();
|
||||
var canvas = document.getElementById('canvas');
|
||||
var context = canvas.getContext('2d');
|
||||
|
||||
zw = getCoords(this);
|
||||
x = e.pageX - zw.left;
|
||||
y = e.pageY - zw.top;
|
||||
var zw = getCoords(this);
|
||||
var x = e.pageX - zw.left;
|
||||
var y = e.pageY - zw.top;
|
||||
|
||||
context.lineWidth = 2;
|
||||
context.strokeStyle = "#00FF00";
|
||||
context.beginPath();
|
||||
context.moveTo(0,y);
|
||||
context.lineTo(canvas.width, y);
|
||||
context.moveTo(x, 0);
|
||||
context.lineTo(x, canvas.height);
|
||||
context.stroke();
|
||||
}
|
||||
context.lineWidth = 2;
|
||||
context.strokeStyle = "#00FF00";
|
||||
context.beginPath();
|
||||
context.moveTo(0,y);
|
||||
context.lineTo(canvas.width, y);
|
||||
context.moveTo(x, 0);
|
||||
context.lineTo(x, canvas.height);
|
||||
context.stroke();
|
||||
}
|
||||
}
|
||||
|
||||
function namechanged()
|
||||
{
|
||||
_name = document.getElementById("name").value;
|
||||
refInfo[aktindex]["name"] = _name;
|
||||
function namechanged() {
|
||||
_name = document.getElementById("name").value;
|
||||
refInfo[aktindex]["name"] = _name;
|
||||
}
|
||||
|
||||
function valuemanualchanged(){
|
||||
if (!drag) {
|
||||
rect.w = document.getElementById("refdx").value;
|
||||
rect.h = document.getElementById("refdy").value;
|
||||
rect.startX = document.getElementById("refx").value;
|
||||
rect.startY = document.getElementById("refy").value;
|
||||
draw();
|
||||
}
|
||||
|
||||
function valuemanualchanged(){
|
||||
if (!drag) {
|
||||
rect.w = document.getElementById("refdx").value;
|
||||
rect.h = document.getElementById("refdy").value;
|
||||
rect.startX = document.getElementById("refx").value;
|
||||
rect.startY = document.getElementById("refy").value;
|
||||
draw();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
init();
|
||||
init();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
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 |
@@ -21,21 +21,21 @@
|
||||
var streamPopup;
|
||||
var streamFlashlight = false;
|
||||
var streamWindowFeatures =
|
||||
'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';
|
||||
'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=260,width=640px,height=480px';
|
||||
|
||||
function loadPage(page) {
|
||||
function loadPage(page) {
|
||||
console.log("loadPage( " + page + " )");
|
||||
|
||||
if (streamPopup) // Ensure that stream popup is closed because it's blocking web interface
|
||||
if (streamPopup) { // Ensure that stream popup is closed because it's blocking web interface
|
||||
streamPopup.close();
|
||||
}
|
||||
|
||||
asyncPageLoad(page);
|
||||
}
|
||||
|
||||
|
||||
async function asyncPageLoad(page ) {
|
||||
console.log(" loading " + page + " ...");
|
||||
document.cookie = "page="+page + "; path=/";
|
||||
@@ -46,7 +46,6 @@
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function resetMenu() {
|
||||
[].forEach.call(document.querySelectorAll('.submenu'), function (el) {
|
||||
el.style.visibility = 'visible';
|
||||
@@ -54,18 +53,20 @@
|
||||
}
|
||||
|
||||
function getCookie(cname) {
|
||||
let name = cname + "=";
|
||||
let decodedCookie = decodeURIComponent(document.cookie);
|
||||
let ca = decodedCookie.split(';');
|
||||
for(let i = 0; i <ca.length; i++) {
|
||||
let c = ca[i];
|
||||
while (c.charAt(0) == ' ') {
|
||||
c = c.substring(1);
|
||||
}
|
||||
if (c.indexOf(name) == 0) {
|
||||
return c.substring(name.length, c.length);
|
||||
}
|
||||
}
|
||||
let name = cname + "=";
|
||||
let decodedCookie = decodeURIComponent(document.cookie);
|
||||
let ca = decodedCookie.split(';');
|
||||
for(let i = 0; i <ca.length; i++) {
|
||||
let c = ca[i];
|
||||
|
||||
while (c.charAt(0) == ' ') {
|
||||
c = c.substring(1);
|
||||
}
|
||||
|
||||
if (c.indexOf(name) == 0) {
|
||||
return c.substring(name.length, c.length);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
</script>
|
||||
@@ -88,21 +89,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>References <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>
|
||||
|
||||
|
||||
@@ -153,7 +154,7 @@
|
||||
HA_send_discovery_visibility();
|
||||
|
||||
if (getCookie("page") == "" || getCookie("page") == "reboot_page.html?v=$COMMIT_HASH") {
|
||||
document.cookie = "page=overview.html?v=$COMMIT_HASH" + "; path=/";
|
||||
document.cookie = "page=overview.html?v=$COMMIT_HASH" + "; path=/";
|
||||
}
|
||||
console.log("Loading page: " + getCookie("page"));
|
||||
document.getElementById('maincontent').src = getCookie("page");
|
||||
@@ -181,19 +182,18 @@
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
function HA_send_discovery_visibility() {
|
||||
loadConfig(domainname);
|
||||
ParseConfig();
|
||||
category = getConfigCategory();
|
||||
param = getConfigParameters();
|
||||
if (category["MQTT"]["enabled"] && param["MQTT"]["HomeassistantDiscovery"]["value1"] == "true") {
|
||||
|
||||
if (category["MQTT"]["enabled"] && param["MQTT"]["HomeassistantDiscovery"].value == "true") {
|
||||
document.getElementById("ManualControl").style.display="";
|
||||
document.getElementById("HASendDiscovery").style.display="";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function HA_send_discovery() {
|
||||
console.log("HA Discovery scheduled");
|
||||
var url = getDomainname() + '/mqtt_publish_discovery';
|
||||
@@ -207,15 +207,17 @@
|
||||
xhttp.send();
|
||||
}
|
||||
|
||||
|
||||
function start_livestream(streamFlashlight) {
|
||||
if (streamPopup)
|
||||
if (streamPopup) {
|
||||
streamPopup.close();
|
||||
}
|
||||
|
||||
if (streamFlashlight)
|
||||
if (streamFlashlight) {
|
||||
streamPopup = window.open(getDomainname() + '/stream?flashlight=true','LivestreamWithlight',streamWindowFeatures);
|
||||
else
|
||||
}
|
||||
else {
|
||||
streamPopup = window.open(getDomainname() + '/stream','Livestream',streamWindowFeatures);
|
||||
}
|
||||
|
||||
streamPopup.focus();
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user