From c0af22cf6ea4ce113406b79f7950b2435732e75e Mon Sep 17 00:00:00 2001 From: Stefan Raeck Date: Sun, 28 Jan 2024 14:42:05 +0100 Subject: [PATCH 1/2] Camera with fixed exposure, grayscale mode, get only 388x144 window showing LCD of heat meter --- esp32-cam-webserver.ino | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/esp32-cam-webserver.ino b/esp32-cam-webserver.ino index 64d6483a..229c8de1 100644 --- a/esp32-cam-webserver.ino +++ b/esp32-cam-webserver.ino @@ -415,22 +415,22 @@ void StartCamera() { * https://github.com/espressif/esp32-camera/blob/master/driver/include/sensor.h#L149 */ - //s->set_framesize(s, FRAMESIZE_SVGA); // FRAMESIZE_[QQVGA|HQVGA|QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA|QXGA(ov3660)]); - //s->set_quality(s, val); // 10 to 63 + s->set_framesize(s, FRAMESIZE_SVGA); // FRAMESIZE_[QQVGA|HQVGA|QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA|QXGA(ov3660)]); + s->set_quality(s, 35); // 10 to 63 ----> lower value is higher quality! <---- //s->set_brightness(s, 0); // -2 to 2 //s->set_contrast(s, 0); // -2 to 2 //s->set_saturation(s, 0); // -2 to 2 - //s->set_special_effect(s, 0); // 0 to 6 (0 - No Effect, 1 - Negative, 2 - Grayscale, 3 - Red Tint, 4 - Green Tint, 5 - Blue Tint, 6 - Sepia) - //s->set_whitebal(s, 1); // aka 'awb' in the UI; 0 = disable , 1 = enable - //s->set_awb_gain(s, 1); // 0 = disable , 1 = enable - //s->set_wb_mode(s, 0); // 0 to 4 - if awb_gain enabled (0 - Auto, 1 - Sunny, 2 - Cloudy, 3 - Office, 4 - Home) - //s->set_exposure_ctrl(s, 1); // 0 = disable , 1 = enable - //s->set_aec2(s, 0); // 0 = disable , 1 = enable - //s->set_ae_level(s, 0); // -2 to 2 - //s->set_aec_value(s, 300); // 0 to 1200 - //s->set_gain_ctrl(s, 1); // 0 = disable , 1 = enable - //s->set_agc_gain(s, 0); // 0 to 30 - //s->set_gainceiling(s, (gainceiling_t)0); // 0 to 6 + s->set_special_effect(s, 2); // 0 to 6 (0 - No Effect, 1 - Negative, 2 - Grayscale, 3 - Red Tint, 4 - Green Tint, 5 - Blue Tint, 6 - Sepia) + s->set_whitebal(s, 0); // aka 'awb' in the UI; 0 = disable , 1 = enable + s->set_awb_gain(s, 1); // 0 = disable , 1 = enable + s->set_wb_mode(s, 0); // 0 to 4 - if awb_gain enabled (0 - Auto, 1 - Sunny, 2 - Cloudy, 3 - Office, 4 - Home) + s->set_exposure_ctrl(s, 0); // 0 = disable , 1 = enable + s->set_aec2(s, 0); // 0 = disable , 1 = enable + s->set_ae_level(s, 0); // -2 to 2 + s->set_aec_value(s, 29); // 0 to 1200 + s->set_gain_ctrl(s, 0); // 0 = disable , 1 = enable + s->set_agc_gain(s, 0); // 0 to 30 + s->set_gainceiling(s, (gainceiling_t)0); // 0 to 6 //s->set_bpc(s, 0); // 0 = disable , 1 = enable //s->set_wpc(s, 1); // 0 = disable , 1 = enable //s->set_raw_gma(s, 1); // 0 = disable , 1 = enable @@ -439,6 +439,15 @@ void StartCamera() { //s->set_vflip(s, 0); // 0 = disable , 1 = enable //s->set_dcw(s, 1); // 0 = disable , 1 = enable //s->set_colorbar(s, 0); // 0 = disable , 1 = enable + ////set_res_raw(sensor_t *sensor, int startX, int startY, int endX, int endY, int offsetX, int offsetY, int totalX, int totalY, int outputX, int outputY, bool scale, bool binning) + //// set_window(sensor, (ov2640_sensor_mode_t)startX, offsetX, offsetY, totalX, totalY, outputX, outputY); + //// OV2640_MODE_CIF=2 + //// ox oy sx sy + //// 80 90 150 56 @320x240 + //// 100 111 188 69 @400x296 + //// 100 108 188 141 + //s->set_res_raw(s, 2, 0, 0, 0, 100, 104, 192, 72, 192, 72, false, false); + s->set_res_raw(s, 1, 0, 0, 0, 200, 208, 384, 144, 384, 144, false, false); } // We now have camera with default init } From f3c1dbb5ef84ed645f43fc5ac97b68471e7d05b7 Mon Sep 17 00:00:00 2001 From: Stefan Raeck Date: Sun, 28 Jan 2024 14:43:47 +0100 Subject: [PATCH 2/2] Detect camera frames with digits visible on heat meter LCD by checking JPG size --- app_httpd.cpp | 40 +++++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/app_httpd.cpp b/app_httpd.cpp index f2b11a90..72b6975b 100644 --- a/app_httpd.cpp +++ b/app_httpd.cpp @@ -228,6 +228,12 @@ static esp_err_t stream_handler(httpd_req_t *req){ uint8_t * _jpg_buf = NULL; char * part_buf[64]; + size_t min = SIZE_MAX; + size_t max = 0; + size_t avg; + size_t step = 0; + uint8_t count = 0; + streamKill = false; Serial.println("Stream requested"); @@ -270,16 +276,32 @@ static esp_err_t stream_handler(httpd_req_t *req){ _jpg_buf = fb->buf; } } - if(res == ESP_OK){ - size_t hlen = snprintf((char *)part_buf, 64, _STREAM_PART, _jpg_buf_len); - res = httpd_resp_send_chunk(req, (const char *)part_buf, hlen); - } - if(res == ESP_OK){ - res = httpd_resp_send_chunk(req, (const char *)_jpg_buf, _jpg_buf_len); - } - if(res == ESP_OK){ - res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY)); + + max -= step; + min += step; + if(_jpg_buf_len > max) max = _jpg_buf_len; + if(_jpg_buf_len < min) min = _jpg_buf_len; + avg = (max + min) >> 1; + step = avg >> 10; + if(step == 0) step = 1; + + if(_jpg_buf_len > avg) { + if(++count == 3) { + if(res == ESP_OK){ + size_t hlen = snprintf((char *)part_buf, 64, _STREAM_PART, _jpg_buf_len); + res = httpd_resp_send_chunk(req, (const char *)part_buf, hlen); + } + if(res == ESP_OK){ + res = httpd_resp_send_chunk(req, (const char *)_jpg_buf, _jpg_buf_len); + } + if(res == ESP_OK){ + res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY)); + } + } + } else { + count = 0; } + if(fb){ esp_camera_fb_return(fb); fb = NULL;