diff --git a/code/components/jomjol_controlcamera/ClassControllCamera.cpp b/code/components/jomjol_controlcamera/ClassControllCamera.cpp index 784e724c..c3b69397 100644 --- a/code/components/jomjol_controlcamera/ClassControllCamera.cpp +++ b/code/components/jomjol_controlcamera/ClassControllCamera.cpp @@ -170,7 +170,7 @@ 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 CCamera::SetBrightnessContrastSaturation(int _brightness, int _contrast, int _saturation, int _autoExposureLevel, bool _grayscale, bool _negative, bool _aec2) { _brightness = min(2, max(-2, _brightness)); _contrast = min(2, max(-2, _contrast)); @@ -180,6 +180,7 @@ bool CCamera::SetBrightnessContrastSaturation(int _brightness, int _contrast, in sensor_t * s = esp_camera_sensor_get(); if (s) { // 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 @@ -215,23 +216,20 @@ bool CCamera::SetBrightnessContrastSaturation(int _brightness, int _contrast, in //s->set_reg(s, 0x7C, 0xFF, 2); // Optional feature - hue setting: Select byte 2 in register 0x7C to set hue value //s->set_reg(s, 0x7D, 0xFF, 0); // Optional feature - hue setting: Hue value 0 - 255 + int indirectReg0 = 0x07; // Set bit 0, 1, 2 to enable saturation, contrast, brightness and hue control if (_grayscale) { - // 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, 0x1F); // Set bit 0, 1, 2 to enable saturation, contrast, brightness and hue control - 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 { - // 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, 7); // Set bit 0, 1, 2 to enable saturation, contrast, brightness and hue control - 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); + indirectReg0 |= 0x18; } + 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 +243,8 @@ bool CCamera::SetBrightnessContrastSaturation(int _brightness, int _contrast, in saturation = _saturation; autoExposureLevel = _autoExposureLevel; imageGrayscale = _grayscale; + imageNegative = _negative; + imageAec2 = _aec2; ESP_LOGD(TAG, "brightness %d, contrast: %d, saturation %d, autoExposureLevel %d, grayscale %d", brightness, contrast, saturation, autoExposureLevel, (int)imageGrayscale); diff --git a/code/components/jomjol_controlcamera/ClassControllCamera.h b/code/components/jomjol_controlcamera/ClassControllCamera.h index 33427ec8..607bec95 100644 --- a/code/components/jomjol_controlcamera/ClassControllCamera.h +++ b/code/components/jomjol_controlcamera/ClassControllCamera.h @@ -40,6 +40,8 @@ class CCamera { int imageZoomMode = 0; int imageZoomOffsetX = 0; int imageZoomOffsetY = 0; + bool imageNegative = false; + bool imageAec2 = false; #ifdef GRAYSCALE_AS_DEFAULT bool imageGrayscale = true; #else @@ -54,7 +56,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 SetBrightnessContrastSaturation(int _brightness, int _contrast, int _saturation, int _autoExposureLevel, bool _grayscale, bool _negative, bool _aec2); 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_flowcontroll/ClassFlowTakeImage.cpp b/code/components/jomjol_flowcontroll/ClassFlowTakeImage.cpp index 471af6b1..ed045e1f 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowTakeImage.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowTakeImage.cpp @@ -54,6 +54,8 @@ void ClassFlowTakeImage::SetInitialParameter(void) ZoomMode = 0; zoomOffsetX = 0; zoomOffsetY = 0; + ImageNegative = false; + ImageAec2 = false; #ifdef GRAYSCALE_AS_DEFAULT ImageGrayscale = true; #else @@ -122,6 +124,20 @@ bool ClassFlowTakeImage::ReadParameter(FILE* pfile, string& aktparamgraph) else if (toUpper(splitted[1]) == "FALSE") ImageGrayscale = false; } + if ((toUpper(splitted[0]) == "NEGATIVE") && (splitted.size() > 1)) + { + if (toUpper(splitted[1]) == "TRUE") + ImageNegative = true; + else if (toUpper(splitted[1]) == "FALSE") + ImageNegative = false; + } + if ((toUpper(splitted[0]) == "AEC2") && (splitted.size() > 1)) + { + if (toUpper(splitted[1]) == "TRUE") + ImageAec2 = true; + else if (toUpper(splitted[1]) == "FALSE") + ImageAec2 = false; + } if ((toUpper(splitted[0]) == "AUTOEXPOSURELEVEL") && (splitted.size() > 1)) _autoExposureLevel = std::stod(splitted[1]); @@ -183,7 +199,7 @@ bool ClassFlowTakeImage::ReadParameter(FILE* pfile, string& aktparamgraph) } } - Camera.SetBrightnessContrastSaturation(_brightness, _contrast, _saturation, _autoExposureLevel, ImageGrayscale); + Camera.SetBrightnessContrastSaturation(_brightness, _contrast, _saturation, _autoExposureLevel, ImageGrayscale, ImageNegative, ImageAec2); Camera.SetQualitySize(ImageQuality, ImageSize, ZoomEnabled, ZoomMode, zoomOffsetX, zoomOffsetY); image_width = Camera.image_width; diff --git a/code/components/jomjol_flowcontroll/ClassFlowTakeImage.h b/code/components/jomjol_flowcontroll/ClassFlowTakeImage.h index 94152bf3..d83f393e 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowTakeImage.h +++ b/code/components/jomjol_flowcontroll/ClassFlowTakeImage.h @@ -22,6 +22,8 @@ protected: int zoomOffsetX = 0; int zoomOffsetY = 0; bool ImageGrayscale; + bool ImageNegative; + bool ImageAec2; int ImageQuality; time_t TimeImageTaken; string namerawimage; diff --git a/code/components/jomjol_flowcontroll/MainFlowControl.cpp b/code/components/jomjol_flowcontroll/MainFlowControl.cpp index 0c78dbcb..36effbb7 100644 --- a/code/components/jomjol_flowcontroll/MainFlowControl.cpp +++ b/code/components/jomjol_flowcontroll/MainFlowControl.cpp @@ -701,6 +701,8 @@ esp_err_t handler_editflow(httpd_req_t *req) int zoomoffsetx = 0; int zoomoffsety = 0; bool zoom = false; + bool negative = false; + bool aec2 = false; #ifdef GRAYSCALE_AS_DEFAULT bool grayscale = true; #else @@ -737,6 +739,20 @@ esp_err_t handler_editflow(httpd_req_t *req) else grayscale = false; } + if (httpd_query_key_value(_query, "ne", _valuechar, 30) == ESP_OK) { + std::string _ne = std::string(_valuechar); + if (stoi(_ne) != 0) + negative = true; + else + negative = false; + } + if (httpd_query_key_value(_query, "a2", _valuechar, 30) == ESP_OK) { + std::string _a2 = std::string(_valuechar); + if (stoi(_a2) != 0) + aec2 = true; + else + aec2 = false; + } if (httpd_query_key_value(_query, "z", _valuechar, 30) == ESP_OK) { std::string _zoom = std::string(_valuechar); if (stoi(_zoom) != 0) @@ -760,7 +776,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); + Camera.SetBrightnessContrastSaturation(bri, con, sat, aelevel, grayscale, negative, aec2); Camera.SetLEDIntensity(intens); ESP_LOGD(TAG, "test_take - vor TakeImage"); std::string zw = flowctrl.doSingleStep("[TakeImage]", _host); diff --git a/sd-card/html/edit_reference.html b/sd-card/html/edit_reference.html index f8c61bf1..7eaa2db7 100644 --- a/sd-card/html/edit_reference.html +++ b/sd-card/html/edit_reference.html @@ -179,6 +179,12 @@ + + + + + + Auto exposure: @@ -237,6 +243,8 @@ if (param["TakeImage"]["Brightness"].found && param["TakeImage"]["Brightness"].enabled) { _grayscale = document.getElementById("grayscale").checked ? "1" : "0"; + _negative = document.getElementById("negative").checked ? "1" : "0"; + _aec2 = document.getElementById("aec2").checked ? "1" : "0"; _zoom = document.getElementById("zoom").checked ? "1" : "0"; _zm = document.getElementById("zoommode").value; if (_zm == "") _zm = "0"; @@ -251,7 +259,7 @@ _saturation = document.getElementById("TakeImage_Saturation_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; + url = url + "&con=" + _contrast + "&sat=" + _saturation + "&int=" + _intensity + "&ae=" + _ae + "&gs=" + _grayscale + "&ne=" + _negative + "&a2=" + _aec2; if (_zoom != '0') url = url + "&z=" + _zoom + "&zm=" + _zm + "&x=" + _x + "&y=" + _y; } @@ -282,6 +290,8 @@ } document.getElementById("grayscale").disabled = false; + document.getElementById("negative").disabled = false; + document.getElementById("aec2").disabled = false; document.getElementById("zoom").disabled = false; document.getElementById("zoommode").disabled = false; document.getElementById("zoomoffsetx").disabled = false; @@ -349,6 +359,8 @@ document.getElementById("flip").checked = true; document.getElementById("grayscale").disabled = true; + document.getElementById("negative").disabled = true; + document.getElementById("aec2").disabled = true; document.getElementById("zoom").disabled = true; document.getElementById("zoommode").disabled = true; document.getElementById("zoomoffsetx").disabled = true; @@ -414,6 +426,16 @@ else param["TakeImage"]["Grayscale"].value1 = "false"; + if ((param["TakeImage"]["Negative"].found == true) && (document.getElementById("negative").checked)) + param["TakeImage"]["Negative"].value1 = "true"; + else + param["TakeImage"]["Negative"].value1 = "false"; + + if ((param["TakeImage"]["Aec2"].found == true) && (document.getElementById("aec2").checked)) + param["TakeImage"]["Aec2"].value1 = "true"; + else + param["TakeImage"]["Aec2"].value1 = "false"; + if ((param["TakeImage"]["Zoom"].found == true) && (document.getElementById("zoom").checked)) param["TakeImage"]["Zoom"].value1 = "true"; else @@ -503,6 +525,8 @@ param["TakeImage"]["Saturation"]["enabled"] = true; param["TakeImage"]["Grayscale"]["enabled"] = true; + param["TakeImage"]["Negative"]["enabled"] = true; + param["TakeImage"]["Aec2"]["enabled"] = true; param["TakeImage"]["Zoom"]["enabled"] = true; param["TakeImage"]["ZoomMode"]["enabled"] = true; param["TakeImage"]["ZoomOffsetX"]["enabled"] = true; @@ -513,6 +537,16 @@ param["TakeImage"]["Grayscale"]["found"] = true; param["TakeImage"]["Grayscale"].value1 = "false"; } + if (!param["TakeImage"]["Negative"]["found"]) + { + param["TakeImage"]["Negative"]["found"] = true; + param["TakeImage"]["Negative"].value1 = "false"; + } + if (!param["TakeImage"]["Aec2"]["found"]) + { + param["TakeImage"]["Aec2"]["found"] = true; + param["TakeImage"]["Aec2"].value1 = "false"; + } if (!param["TakeImage"]["Zoom"]["found"]) { param["TakeImage"]["Zoom"]["found"] = true; @@ -576,6 +610,16 @@ } else { document.getElementById("grayscale").checked = false; } + if (param["TakeImage"]["Negative"].value1 == "true") { + document.getElementById("negative").checked = true; + } else { + document.getElementById("negative").checked = false; + } + if (param["TakeImage"]["Aec2"].value1 == "true") { + document.getElementById("aec2").checked = true; + } else { + document.getElementById("aec2").checked = false; + } if (param["TakeImage"]["Zoom"].value1 == "true") { document.getElementById("zoom").checked = true; } else { diff --git a/sd-card/html/readconfigparam.js b/sd-card/html/readconfigparam.js index 126ce768..ccd7a5a6 100644 --- a/sd-card/html/readconfigparam.js +++ b/sd-card/html/readconfigparam.js @@ -125,6 +125,8 @@ function ParseConfig() { ParamAddValue(param, catname, "ZoomOffsetX"); ParamAddValue(param, catname, "ZoomOffsetY"); ParamAddValue(param, catname, "Grayscale"); + ParamAddValue(param, catname, "Negative"); + ParamAddValue(param, catname, "Aec2"); ParamAddValue(param, catname, "AutoExposureLevel"); ParamAddValue(param, catname, "FixedExposure");