diff --git a/code/components/jomjol_controlcamera/ClassControllCamera.cpp b/code/components/jomjol_controlcamera/ClassControllCamera.cpp index c3b69397..33b00bc8 100644 --- a/code/components/jomjol_controlcamera/ClassControllCamera.cpp +++ b/code/components/jomjol_controlcamera/ClassControllCamera.cpp @@ -31,6 +31,8 @@ #include "driver/ledc.h" #include "MainFlowControl.h" +#include "ov2640_sharpness.h" + #if (ESP_IDF_VERSION_MAJOR >= 5) #include "soc/periph_defs.h" #include "esp_private/periph_ctrl.h" @@ -53,9 +55,9 @@ static const char* _STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary=" static const char* _STREAM_BOUNDARY = "\r\n--" PART_BOUNDARY "\r\n"; static const char* _STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: %u\r\n\r\n"; -// OV Camera SDE Indirect Register Access -#define OV_IRA_BPADDR 0x7C -#define OV_IRA_BPDATA 0x7D +// OV2640 Camera SDE Indirect Register Access +#define OV2640_IRA_BPADDR 0x7C +#define OV2640_IRA_BPDATA 0x7D static camera_config_t camera_config = { @@ -170,66 +172,93 @@ static size_t jpg_encode_stream(void * arg, size_t index, const void* data, size } -bool CCamera::SetBrightnessContrastSaturation(int _brightness, int _contrast, int _saturation, int _autoExposureLevel, bool _grayscale, bool _negative, bool _aec2) +bool CCamera::SetBrightnessContrastSaturation(int _brightness, int _contrast, int _saturation, int _autoExposureLevel, bool _grayscale, bool _negative, bool _aec2, int _sharpnessLevel) { _brightness = min(2, max(-2, _brightness)); _contrast = min(2, max(-2, _contrast)); _saturation = min(2, max(-2, _saturation)); _autoExposureLevel = min(2, max(-2, _autoExposureLevel)); + bool _autoSharpness = false; + if (_sharpnessLevel <= -4) + _autoSharpness = true; + _sharpnessLevel = min(3, max(-3, _sharpnessLevel)); sensor_t * s = esp_camera_sensor_get(); if (s) { + // camera gives precedence to negative over grayscale, so it's easier to do negative ourselves. + // if (_negative) { + // s->set_special_effect(s, 1); // 0 - no effect, 1 - negative, 2 - grayscale, 3 - reddish, 4 - greenish, 5 - blue, 6 - retro + // } + if (_grayscale) { + s->set_special_effect(s, 2); // 0 - no effect, 1 - negative, 2 - grayscale, 3 - reddish, 4 - greenish, 5 - blue, 6 - retro + } + // auto exposure controls s->set_aec2(s, _aec2 ? 1 : 0); s->set_ae_level(s, _autoExposureLevel); // -2 to 2 s->set_gainceiling(s, GAINCEILING_2X); // GAINCEILING_2X 4X 8X 16X 32X 64X 128X // post processing + if (_autoSharpness) { + s->set_sharpness(s, 0); // auto-sharpness is not officially supported, default to 0 + } s->set_saturation(s, _saturation); s->set_contrast(s, _contrast); s->set_brightness(s, _brightness); - /* Workaround - bug in cam library - enable bits are set without using bitwise OR logic -> only latest enable setting is used */ - /* Library version: https://github.com/espressif/esp32-camera/commit/5c8349f4cf169c8a61283e0da9b8cff10994d3f3 */ - /* Reference: https://esp32.com/viewtopic.php?f=19&t=14376#p93178 */ - /* The memory structure is as follows for - byte_0 = enable_bits - byte_0->bit0 = enable saturation and hue --> OK - byte_0->bit1 = enable saturation --> OK - byte_0->bit2 = enable brightness and contrast --> OK - byte_0->bit3 = enable green -> blue spitial effect (Antique and blunish and greenish and readdish and b&w) enable - byte_0->bit4 = anable gray -> read spitial effect (Antique and blunish and greenish and readdish and b&w) enable - byte_0->bit5 = remove (UV) in YUV color system - byte_0->bit6 = enable negative - byte_0->bit7 = remove (Y) in YUV color system - byte_1 = saturation1 0-255 --> ? - byte_2 = hue 0-255 --> OK - byte_3 = saturation2 0-255 --> OK - byte_4 = reenter saturation2 in documents --> ? - byte_5 = spital effect green -> blue 0-255 --> ? - byte_6 = spital effect gray -> read 0-255 --> ? - byte_7 = contrast lower byte 0-255 --> OK - byte_8 = contrast higher byte 0-255 --> OK - byte_9 = brightness 0-255 --> OK - byte_10= if byte_10==4 contrast effective --> ? - */ + camera_sensor_info_t *sensor_info = esp_camera_sensor_get_info(&(s->id)); + if (sensor_info != NULL) { + if (sensor_info->model == CAMERA_OV2640) { + if (_autoSharpness) { + ov2640_enable_auto_sharpness(s); + } else { + ov2640_set_sharpness(s, _sharpnessLevel); + } - //s->set_reg(s, 0x7C, 0xFF, 2); // Optional feature - hue setting: Select byte 2 in register 0x7C to set hue value - //s->set_reg(s, 0x7D, 0xFF, 0); // Optional feature - hue setting: Hue value 0 - 255 - int indirectReg0 = 0x07; // Set bit 0, 1, 2 to enable saturation, contrast, brightness and hue control - if (_grayscale) { - indirectReg0 |= 0x18; + /* Workaround - bug in cam library - enable bits are set without using bitwise OR logic -> only latest enable setting is used */ + /* Library version: https://github.com/espressif/esp32-camera/commit/5c8349f4cf169c8a61283e0da9b8cff10994d3f3 */ + /* Reference: https://esp32.com/viewtopic.php?f=19&t=14376#p93178 */ + /* The memory structure is as follows for + byte_0 = enable_bits + byte_0->bit0 = enable saturation and hue --> OK + byte_0->bit1 = enable saturation --> OK + byte_0->bit2 = enable brightness and contrast --> OK + byte_0->bit3 = enable green -> blue spitial effect (Antique and blunish and greenish and readdish and b&w) enable + byte_0->bit4 = anable gray -> read spitial effect (Antique and blunish and greenish and readdish and b&w) enable + byte_0->bit5 = remove (UV) in YUV color system + byte_0->bit6 = enable negative + byte_0->bit7 = remove (Y) in YUV color system + byte_1 = saturation1 0-255 --> ? + byte_2 = hue 0-255 --> OK + byte_3 = saturation2 0-255 --> OK + byte_4 = reenter saturation2 in documents --> ? + byte_5 = spital effect green -> blue 0-255 --> ? + byte_6 = spital effect gray -> read 0-255 --> ? + byte_7 = contrast lower byte 0-255 --> OK + byte_8 = contrast higher byte 0-255 --> OK + byte_9 = brightness 0-255 --> OK + byte_10= if byte_10==4 contrast effective --> ? + */ + + //s->set_reg(s, 0x7C, 0xFF, 2); // Optional feature - hue setting: Select byte 2 in register 0x7C to set hue value + //s->set_reg(s, 0x7D, 0xFF, 0); // Optional feature - hue setting: Hue value 0 - 255 + int indirectReg0 = 0x07; // Set bit 0, 1, 2 to enable saturation, contrast, brightness and hue control + if (_grayscale) { + indirectReg0 |= 0x18; + } + // camera gives precedence to negative over grayscale, so it's easier to do negative ourselves. + // if (_negative) { + // indirectReg0 |= 0x40; + // } + // Indirect register access + s->set_reg(s, 0xFF, 0x01, 0); // Select DSP bank + s->set_reg(s, OV2640_IRA_BPADDR, 0xFF, 0x00); // Address 0x00 + s->set_reg(s, OV2640_IRA_BPDATA, 0xFF, indirectReg0); + s->set_reg(s, OV2640_IRA_BPADDR, 0xFF, 0x05); // Address 0x05 + s->set_reg(s, OV2640_IRA_BPDATA, 0xFF, 0x80); + s->set_reg(s, OV2640_IRA_BPDATA, 0xFF, 0x80); + } } - if (_negative) { - indirectReg0 |= 0x40; - } - // Indirect register access - s->set_reg(s, 0xFF, 0x01, 0); // Select DSP bank - s->set_reg(s, OV_IRA_BPADDR, 0xFF, 0x00); // Address 0x00 - s->set_reg(s, OV_IRA_BPDATA, 0xFF, indirectReg0); - s->set_reg(s, OV_IRA_BPADDR, 0xFF, 0x05); // Address 0x05 - s->set_reg(s, OV_IRA_BPDATA, 0xFF, 0x80); - s->set_reg(s, OV_IRA_BPDATA, 0xFF, 0x80); } else { LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "SetBrightnessContrastSaturation: Failed to get control structure"); @@ -245,6 +274,8 @@ bool CCamera::SetBrightnessContrastSaturation(int _brightness, int _contrast, in imageGrayscale = _grayscale; imageNegative = _negative; imageAec2 = _aec2; + imageAutoSharpness = _autoSharpness; + imageSharpnessLevel = _sharpnessLevel; ESP_LOGD(TAG, "brightness %d, contrast: %d, saturation %d, autoExposureLevel %d, grayscale %d", brightness, contrast, saturation, autoExposureLevel, (int)imageGrayscale); @@ -471,6 +502,10 @@ esp_err_t CCamera::CaptureToBasisImage(CImageBasis *_Image, int delay) return ESP_OK; } + if (imageNegative) { + _zwImage->Negative(); + } + stbi_uc* p_target; stbi_uc* p_source; int channels = 3; diff --git a/code/components/jomjol_controlcamera/ClassControllCamera.h b/code/components/jomjol_controlcamera/ClassControllCamera.h index 607bec95..064eefb9 100644 --- a/code/components/jomjol_controlcamera/ClassControllCamera.h +++ b/code/components/jomjol_controlcamera/ClassControllCamera.h @@ -42,6 +42,8 @@ class CCamera { int imageZoomOffsetY = 0; bool imageNegative = false; bool imageAec2 = false; + bool imageAutoSharpness = false; + int imageSharpnessLevel = 0; #ifdef GRAYSCALE_AS_DEFAULT bool imageGrayscale = true; #else @@ -56,7 +58,7 @@ class CCamera { 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 zoomEnabled, int zoomMode, int zoomOffsetX, int zoomOffsetY); - bool SetBrightnessContrastSaturation(int _brightness, int _contrast, int _saturation, int _autoExposureLevel, bool _grayscale, bool _negative, bool _aec2); + bool SetBrightnessContrastSaturation(int _brightness, int _contrast, int _saturation, int _autoExposureLevel, bool _grayscale, bool _negative, bool _aec2, int _sharpnessLevel); void SetZoom(bool zoomEnabled, int zoomMode, int zoomOffsetX, int zoomOffsetY); void GetCameraParameter(httpd_req_t *req, int &qual, framesize_t &resol, bool &zoomEnabled, int &zoomMode, int &zoomOffsetX, int &zoomOffsetY); void SetLEDIntensity(float _intrel); diff --git a/code/components/jomjol_controlcamera/ov2640_sharpness.cpp b/code/components/jomjol_controlcamera/ov2640_sharpness.cpp new file mode 100644 index 00000000..6970b27c --- /dev/null +++ b/code/components/jomjol_controlcamera/ov2640_sharpness.cpp @@ -0,0 +1,124 @@ +#include +#include "esp_camera.h" +#include "ov2640_sharpness.h" + + +#define OV2640_MAXLEVEL_SHARPNESS 6 + +const static uint8_t OV2640_SHARPNESS_AUTO[]= +{ + 0xFF, 0x00, 0xff, + 0x92, 0x01, 0xff, + 0x93, 0x20, 0x20, + 0x00, 0x00, 0x00 +}; + +const static uint8_t OV2640_SHARPNESS_MANUAL[]= +{ + 0xFF, 0x00, 0xff, + 0x92, 0x01, 0xff, + 0x93, 0x00, 0x20, + 0x00, 0x00, 0x00 +}; + +const static uint8_t OV2640_SHARPNESS_LEVEL0[]= +{ + 0xFF, 0x00, 0xff, + 0x92, 0x01, 0xff, + 0x93, 0xc0, 0x1f, + 0x00, 0x00, 0x00 +}; +const static uint8_t OV2640_SHARPNESS_LEVEL1[]= +{ + 0xFF, 0x00, 0xff, + 0x92, 0x01, 0xff, + 0x93, 0xc1, 0x1f, + 0x00, 0x00, 0x00 +}; +const static uint8_t OV2640_SHARPNESS_LEVEL2[]= +{ + 0xFF, 0x00, 0xff, + 0x92, 0x01, 0xff, + 0x93, 0xc2, 0x1f, + 0x00, 0x00, 0x00 +}; +const static uint8_t OV2640_SHARPNESS_LEVEL3[]= +{ + 0xFF, 0x00, 0xff, + 0x92, 0x01, 0xff, + 0x93, 0xc4, 0x1f, + 0x00, 0x00, 0x00 +}; +const static uint8_t OV2640_SHARPNESS_LEVEL4[]= +{ + 0xFF, 0x00, 0xff, + 0x92, 0x01, 0xff, + 0x93, 0xc8, 0x1f, + 0x00, 0x00, 0x00 +}; +const static uint8_t OV2640_SHARPNESS_LEVEL5[]= +{ + 0xFF, 0x00, 0xff, + 0x92, 0x01, 0xff, + 0x93, 0xd0, 0x1f, + 0x00, 0x00, 0x00 +}; +const static uint8_t OV2640_SHARPNESS_LEVEL6[]= +{ + 0xFF, 0x00, 0xff, + 0x92, 0x01, 0xff, + 0x93, 0xdf, 0x1f, + 0x00, 0x00, 0x00 +}; + +const static uint8_t *OV2640_SETTING_SHARPNESS[]= +{ + OV2640_SHARPNESS_LEVEL0, // -3 sharpness + OV2640_SHARPNESS_LEVEL1, + OV2640_SHARPNESS_LEVEL2, + OV2640_SHARPNESS_LEVEL3, + OV2640_SHARPNESS_LEVEL4, + OV2640_SHARPNESS_LEVEL5, + OV2640_SHARPNESS_LEVEL6 // +3 sharpness +}; + +static int table_mask_write(sensor_t *sensor, const uint8_t* ptab) +{ + uint8_t address; + uint8_t value; + uint8_t orgval; + uint8_t mask; + const uint8_t *pdata = ptab; + + if (pdata == NULL) + return -1; + + while (1) + { + address = *pdata++; + value = *pdata++; + mask = *pdata++; + if ((address == 0) && (value == 0) && (mask == 0)) + break; + sensor->set_reg(sensor, address, mask, value); + } + + return 0; +} + +int ov2640_enable_auto_sharpness(sensor_t *sensor) +{ + table_mask_write(sensor, OV2640_SHARPNESS_AUTO); + return 0; +} + + +int ov2640_set_sharpness(sensor_t *sensor, int sharpness) +{ + if ((sharpness < -3) || (sharpness > OV2640_MAXLEVEL_SHARPNESS - 3)) + return -1; + + table_mask_write(sensor, OV2640_SHARPNESS_MANUAL); + table_mask_write(sensor, OV2640_SETTING_SHARPNESS[sharpness + 3]); + return 0; +} diff --git a/code/components/jomjol_controlcamera/ov2640_sharpness.h b/code/components/jomjol_controlcamera/ov2640_sharpness.h new file mode 100644 index 00000000..19b157ce --- /dev/null +++ b/code/components/jomjol_controlcamera/ov2640_sharpness.h @@ -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 diff --git a/code/components/jomjol_flowcontroll/ClassFlowTakeImage.cpp b/code/components/jomjol_flowcontroll/ClassFlowTakeImage.cpp index ed045e1f..d2e65f34 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowTakeImage.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowTakeImage.cpp @@ -84,6 +84,7 @@ bool ClassFlowTakeImage::ReadParameter(FILE* pfile, string& aktparamgraph) int _brightness = -100; int _contrast = -100; int _saturation = -100; + int _sharpness = 0; int _autoExposureLevel = 0; if (aktparamgraph.size() == 0) @@ -178,6 +179,11 @@ bool ClassFlowTakeImage::ReadParameter(FILE* pfile, string& aktparamgraph) _saturation = stoi(splitted[1]); } + if ((toUpper(splitted[0]) == "SHARPNESS") && (splitted.size() > 1)) + { + _sharpness = stoi(splitted[1]); + } + if ((toUpper(splitted[0]) == "FIXEDEXPOSURE") && (splitted.size() > 1)) { if (toUpper(splitted[1]) == "TRUE") @@ -199,7 +205,7 @@ bool ClassFlowTakeImage::ReadParameter(FILE* pfile, string& aktparamgraph) } } - Camera.SetBrightnessContrastSaturation(_brightness, _contrast, _saturation, _autoExposureLevel, ImageGrayscale, ImageNegative, ImageAec2); + Camera.SetBrightnessContrastSaturation(_brightness, _contrast, _saturation, _autoExposureLevel, ImageGrayscale, ImageNegative, ImageAec2, _sharpness); Camera.SetQualitySize(ImageQuality, ImageSize, ZoomEnabled, ZoomMode, zoomOffsetX, zoomOffsetY); image_width = Camera.image_width; diff --git a/code/components/jomjol_flowcontroll/MainFlowControl.cpp b/code/components/jomjol_flowcontroll/MainFlowControl.cpp index 36effbb7..1d3fcb64 100644 --- a/code/components/jomjol_flowcontroll/MainFlowControl.cpp +++ b/code/components/jomjol_flowcontroll/MainFlowControl.cpp @@ -703,6 +703,7 @@ esp_err_t handler_editflow(httpd_req_t *req) bool zoom = false; bool negative = false; bool aec2 = false; + int sharpnessLevel = 0; #ifdef GRAYSCALE_AS_DEFAULT bool grayscale = true; #else @@ -732,6 +733,10 @@ esp_err_t handler_editflow(httpd_req_t *req) std::string _ae = std::string(_valuechar); aelevel = stoi(_ae); } + if (httpd_query_key_value(_query, "sh", _valuechar, 30) == ESP_OK) { + std::string _sh = std::string(_valuechar); + sharpnessLevel = stoi(_sh); + } if (httpd_query_key_value(_query, "gs", _valuechar, 30) == ESP_OK) { std::string _gr = std::string(_valuechar); if (stoi(_gr) != 0) @@ -776,7 +781,7 @@ esp_err_t handler_editflow(httpd_req_t *req) // ESP_LOGD(TAG, "Parameter host: %s", _host.c_str()); // string zwzw = "Do " + _task + " start\n"; ESP_LOGD(TAG, zwzw.c_str()); Camera.SetZoom(zoom, zoommode, zoomoffsetx, zoomoffsety); - Camera.SetBrightnessContrastSaturation(bri, con, sat, aelevel, grayscale, negative, aec2); + Camera.SetBrightnessContrastSaturation(bri, con, sat, aelevel, grayscale, negative, aec2, sharpnessLevel); Camera.SetLEDIntensity(intens); ESP_LOGD(TAG, "test_take - vor TakeImage"); std::string zw = flowctrl.doSingleStep("[TakeImage]", _host); diff --git a/code/components/jomjol_image_proc/CImageBasis.cpp b/code/components/jomjol_image_proc/CImageBasis.cpp index cef08bf0..8038b01e 100644 --- a/code/components/jomjol_image_proc/CImageBasis.cpp +++ b/code/components/jomjol_image_proc/CImageBasis.cpp @@ -636,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; diff --git a/code/components/jomjol_image_proc/CImageBasis.h b/code/components/jomjol_image_proc/CImageBasis.h index 4b2b329d..ca9ba14b 100644 --- a/code/components/jomjol_image_proc/CImageBasis.h +++ b/code/components/jomjol_image_proc/CImageBasis.h @@ -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); diff --git a/sd-card/html/edit_reference.html b/sd-card/html/edit_reference.html index 7eaa2db7..44cfea40 100644 --- a/sd-card/html/edit_reference.html +++ b/sd-card/html/edit_reference.html @@ -184,7 +184,7 @@ - + Auto exposure: @@ -193,6 +193,17 @@ 0 + + + + + Sharpness: + + + + 0 + + @@ -257,11 +268,13 @@ _brightness = document.getElementById("TakeImage_Brightness_value1").value; _contrast = document.getElementById("TakeImage_Contrast_value1").value; _saturation = document.getElementById("TakeImage_Saturation_value1").value; + _sharpness = document.getElementById("TakeImage_Sharpness_value1").value; _ae = document.getElementById("TakeImage_AutoExposureLevel_value1").value; url = getDomainname() + "/editflow?task=test_take&bri=" + _brightness; - url = url + "&con=" + _contrast + "&sat=" + _saturation + "&int=" + _intensity + "&ae=" + _ae + "&gs=" + _grayscale + "&ne=" + _negative + "&a2=" + _aec2; + url = url + "&con=" + _contrast + "&sat=" + _saturation + "&sh=" + _sharpness + "&int=" + _intensity + "&gs=" + _grayscale + "&ne=" + _negative + "&z=" + _zoom; if (_zoom != '0') - url = url + "&z=" + _zoom + "&zm=" + _zm + "&x=" + _x + "&y=" + _y; + url = url + "&zm=" + _zm + "&x=" + _x + "&y=" + _y; + url = url + "&ae=" + _ae + "&a2=" + _aec2; } else { @@ -320,6 +333,7 @@ document.getElementById("TakeImage_Brightness_value1").disabled = false; document.getElementById("TakeImage_Contrast_value1").disabled = false; document.getElementById("TakeImage_Saturation_value1").disabled = false; + document.getElementById("TakeImage_Sharpness_value1").disabled = false; document.getElementById("TakeImage_LEDIntensity_value1").disabled = false; } else @@ -374,6 +388,7 @@ document.getElementById("TakeImage_Brightness_value1").disabled = true; document.getElementById("TakeImage_Saturation_value1").disabled = true; document.getElementById("TakeImage_Contrast_value1").disabled = true; + document.getElementById("TakeImage_Sharpness_value1").disabled = true; document.getElementById("TakeImage_LEDIntensity_value1").disabled = true; document.getElementById("mirror").disabled = false; document.getElementById("flip").disabled = false; @@ -450,6 +465,7 @@ ReadParameter(param, "TakeImage", "Brightness", false); ReadParameter(param, "TakeImage", "Contrast", false); ReadParameter(param, "TakeImage", "Saturation", false); + ReadParameter(param, "TakeImage", "Sharpness", false); ReadParameter(param, "TakeImage", "LEDIntensity", false); ReadParameter(param, "TakeImage", "AutoExposureLevel", false); } @@ -523,6 +539,7 @@ param["TakeImage"]["Brightness"]["enabled"] = true; param["TakeImage"]["Contrast"]["enabled"] = true; param["TakeImage"]["Saturation"]["enabled"] = true; + param["TakeImage"]["Sharpness"]["enabled"] = true; param["TakeImage"]["Grayscale"]["enabled"] = true; param["TakeImage"]["Negative"]["enabled"] = true; @@ -593,6 +610,11 @@ param["TakeImage"]["Saturation"]["found"] = true; param["TakeImage"]["Saturation"]["value1"] = "0"; } + if (!param["TakeImage"]["Sharpness"]["found"]) + { + param["TakeImage"]["Sharpness"]["found"] = true; + param["TakeImage"]["Sharpness"]["value1"] = "0"; + } UpdateInput(); showReference(param); @@ -604,6 +626,7 @@ WriteParameter(param, category, "TakeImage", "Brightness", false, true); WriteParameter(param, category, "TakeImage", "Contrast", false, true); WriteParameter(param, category, "TakeImage", "Saturation", false, true); + WriteParameter(param, category, "TakeImage", "Sharpness", false, true); WriteParameter(param, category, "TakeImage", "LEDIntensity", false); if (param["TakeImage"]["Grayscale"].value1 == "true") { document.getElementById("grayscale").checked = true; @@ -724,6 +747,11 @@ context.clearRect(0,0,canvas.width,canvas.height); context.save(); + negative = document.getElementById("negative").checked; + if (negative) { + context.filter = 'invert(1)'; + } + if (isActReference) { context.drawImage(imageObj,0,0); diff --git a/sd-card/html/readconfigparam.js b/sd-card/html/readconfigparam.js index ccd7a5a6..1be26ff2 100644 --- a/sd-card/html/readconfigparam.js +++ b/sd-card/html/readconfigparam.js @@ -117,6 +117,7 @@ function ParseConfig() { ParamAddValue(param, catname, "Brightness"); ParamAddValue(param, catname, "Contrast"); ParamAddValue(param, catname, "Saturation"); + ParamAddValue(param, catname, "Sharpness"); ParamAddValue(param, catname, "LEDIntensity"); ParamAddValue(param, catname, "ImageQuality"); ParamAddValue(param, catname, "ImageSize");