Изменение настроек камеры ESP32-CAM OV2640: яркость, разрешение, качество, контрастность и другое

В этом руководстве показано, как изменить настройки камеры ESP32-CAM OV2640, такие как контрастность, яркость, разрешение, качество, насыщенность и другие параметры с помощью Arduino IDE.

Как изменить настройки камеры ESP32-CAM: контрастность, яркость, разрешение, качество, насыщенность, экспозиция

Инструкции в этом руководстве работают для любой отладочной платы ESP32 с камерой, если она оснащена камерой OV2640.

Установка дополнения ESP32

Мы будем программировать плату ESP32 с помощью Arduino IDE. Поэтому вам нужна установленная Arduino IDE, а также дополнение ESP32:

Настройки камеры OV2640

В проекте ESP32 Camera Web Server веб-сервер предоставлял множество опций для изменения настроек изображения. Посмотрите на следующий скриншот – там есть ползунки, которые можно перемещать для изменения настроек изображения.

Настройки камеры OV2640 ESP32-CAM AI Thinker

В этом уроке мы покажем вам, как реализовать эти изменения в вашем коде, независимо от того, какой проект вы создаёте: фотографирование или потоковое видео.

Мы рекомендуем сначала пройти проект Camera Web Server и поиграть с настройками изображения, чтобы увидеть, что делает каждая настройка:

В зависимости от того, где расположена ваша камера, вы можете захотеть изменить некоторые настройки для получения лучшего изображения. Экспериментируя с этим веб-сервером, вы получите представление о том, что нужно изменить и какие значения установить для получения лучшего изображения. Как только вы узнаете лучшие настройки для вашей камеры, вы можете применить их в других проектах.

Изменение настроек камеры ESP32-CAM: скетч Arduino

Чтобы изменить настройки изображения, после инициализации камеры используйте следующие строки:

sensor_t * s = esp_camera_sensor_get()

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);       // 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_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
s->set_lenc(s, 1);           // 0 = disable , 1 = enable
s->set_hmirror(s, 0);        // 0 = disable , 1 = enable
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_brightness()

Установка яркости

-2 to 2

set_contrast()

Установка контрастности

-2 to 2

set_saturation()

Установка насыщенности

-2 to 2

set_special_effect()

Установка спецэффекта

0 – No Effect
1 – Negative
2 – Grayscale
3 – Red Tint
4 – Green Tint
5 – Blue Tint
6 – Sepia

set_whitebal()

Установка баланса белого

0 – disable
1 – enable

set_awb_gain()

Установка усиления баланса белого

0 – disable
1 – enable

set_wb_mode()

Установка режима баланса белого

0 – Auto
1 – Sunny
2 – Cloudy
3 – Office
4 – Home

set_exposure_ctrl()

Управление экспозицией

0 – disable
1 – enable

set_aec2()

0 – disable
1 – enable

set_ae_level()

-2 to 2

set_aec_value()

0 to 1200

set_gain_ctrl()

0 – disable
1 – enable

set_agc_gain()

0 to 30

set_gainceiling()

0 to 6

set_bpc()

0 – disable
1 – enable

set_wpc()

0 – disable
1 – enable

set_raw_gma()

0 – disable
1 – enable

set_lenc()

Коррекция линзы

0 – disable
1 – enable

set_hmirror()

Горизонтальное зеркало

0 – disable
1 – enable

set_vflip()

Вертикальный переворот

0 – disable
1 – enable

set_dcw()

0 – disable
1 – enable

set_colorbar()

Установка цветовой полосы

0 – disable
1 – enable

Как видите, изменение настроек камеры довольно простое. Вам нужно просто использовать эти строки кода после инициализации камеры. После этого вы можете использовать обычные функции и код для управления камерой. Чтобы лучше понять, как их использовать, вы можете следовать следующему примеру.

Функции в таблице расположены в том же порядке, что и в примере Camera Web Server, чтобы было проще определить, какие функции и значения следует использовать для получения лучшего изображения в вашем сценарии.

Пример изменения настроек камеры ESP32-CAM

Чтобы показать вам, как применить настройки изображения в вашем коде, мы создали простой пример. Следующий код делает фотографию каждые 10 секунд и сохраняет её на карту microSD. В коде есть раздел, который позволяет изменить настройки камеры.

/*********
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/esp32-cam-ov2640-camera-settings/
*********/

#include "esp_camera.h"
#include "FS.h"                // SD Card ESP32
#include "SD_MMC.h"            // SD Card ESP32
#include "soc/soc.h"           // Disable brownout problems
#include "soc/rtc_cntl_reg.h"  // Disable brownout problems
#include "driver/rtc_io.h"

// Pin definition for CAMERA_MODEL_AI_THINKER
// Change pin definition if you're using another ESP32 with camera module
#define PWDN_GPIO_NUM     32
#define RESET_GPIO_NUM    -1
#define XCLK_GPIO_NUM      0
#define SIOD_GPIO_NUM     26
#define SIOC_GPIO_NUM     27
#define Y9_GPIO_NUM       35
#define Y8_GPIO_NUM       34
#define Y7_GPIO_NUM       39
#define Y6_GPIO_NUM       36
#define Y5_GPIO_NUM       21
#define Y4_GPIO_NUM       19
#define Y3_GPIO_NUM       18
#define Y2_GPIO_NUM        5
#define VSYNC_GPIO_NUM    25
#define HREF_GPIO_NUM     23
#define PCLK_GPIO_NUM     22

// Keep track of number of pictures
unsigned int pictureNumber = 0;

//Stores the camera configuration parameters
camera_config_t config;

void setup() {
  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector

  Serial.begin(115200);

  //Initialize the camera
  Serial.print("Initializing the camera module...");
  configInitCamera();
  Serial.println("Ok!");

  //Initialize MicroSD
  Serial.print("Initializing the MicroSD card module... ");
  initMicroSDCard();
}

void loop() {
  //Path where new picture will be saved in SD Card
  String path = "/picture" + String(pictureNumber) +".jpg";
  Serial.printf("Picture file name: %s\n", path.c_str());

  //Take and Save Photo
  takeSavePhoto(path);
  pictureNumber++;
  delay(10000);
}

void configInitCamera(){
  config.ledc_channel = LEDC_CHANNEL_0;
  config.ledc_timer = LEDC_TIMER_0;
  config.pin_d0 = Y2_GPIO_NUM;
  config.pin_d1 = Y3_GPIO_NUM;
  config.pin_d2 = Y4_GPIO_NUM;
  config.pin_d3 = Y5_GPIO_NUM;
  config.pin_d4 = Y6_GPIO_NUM;
  config.pin_d5 = Y7_GPIO_NUM;
  config.pin_d6 = Y8_GPIO_NUM;
  config.pin_d7 = Y9_GPIO_NUM;
  config.pin_xclk = XCLK_GPIO_NUM;
  config.pin_pclk = PCLK_GPIO_NUM;
  config.pin_vsync = VSYNC_GPIO_NUM;
  config.pin_href = HREF_GPIO_NUM;
  config.pin_sccb_sda = SIOD_GPIO_NUM;
  config.pin_sccb_scl = SIOC_GPIO_NUM;
  config.pin_pwdn = PWDN_GPIO_NUM;
  config.pin_reset = RESET_GPIO_NUM;
  config.xclk_freq_hz = 20000000;
  config.pixel_format = PIXFORMAT_JPEG; //YUV422,GRAYSCALE,RGB565,JPEG

  // Select lower framesize if the camera doesn't support PSRAM
  if(psramFound()){
    config.frame_size = FRAMESIZE_UXGA; // FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA
    config.jpeg_quality = 10; //10-63 lower number means higher quality
    config.fb_count = 2;
  } else {
    config.frame_size = FRAMESIZE_SVGA;
    config.jpeg_quality = 12;
    config.fb_count = 1;
  }

  // Initialize the Camera
  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("Camera init failed with error 0x%x", err);
    return;
  }

  sensor_t * s = esp_camera_sensor_get();
  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);       // 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_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
  s->set_lenc(s, 1);           // 0 = disable , 1 = enable
  s->set_hmirror(s, 0);        // 0 = disable , 1 = enable
  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
}

void initMicroSDCard(){
  // Start Micro SD card
  Serial.println("Starting SD Card");
  if(!SD_MMC.begin()){
    Serial.println("SD Card Mount Failed");
    return;
  }
  uint8_t cardType = SD_MMC.cardType();
  if(cardType == CARD_NONE){
    Serial.println("No SD Card attached");
    return;
  }
}

void takeSavePhoto(String path){
  // Take Picture with Camera
  camera_fb_t  * fb = esp_camera_fb_get();

  if(!fb) {
    Serial.println("Camera capture failed");
    return;
  }

  // Save picture to microSD card
  fs::FS &fs = SD_MMC;
  File file = fs.open(path.c_str(), FILE_WRITE);
  if(!file){
    Serial.println("Failed to open file in writing mode");
  }
  else {
    file.write(fb->buf, fb->len); // payload (image), payload length
    Serial.printf("Saved file to path: %s\n", path.c_str());
  }
  file.close();

  //return the frame buffer back to the driver for reuse
  esp_camera_fb_return(fb);
}

Исходный код

Для упрощения мы создали функцию configInitCamera(), которая содержит все команды для инициализации камеры.

Назначение GPIO OV2640

Сначала назначаются GPIO-пины.

config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
config.pin_d0 = Y2_GPIO_NUM;
config.pin_d1 = Y3_GPIO_NUM;
config.pin_d2 = Y4_GPIO_NUM;
config.pin_d3 = Y5_GPIO_NUM;
config.pin_d4 = Y6_GPIO_NUM;
config.pin_d5 = Y7_GPIO_NUM;
config.pin_d6 = Y8_GPIO_NUM;
config.pin_d7 = Y9_GPIO_NUM;
config.pin_xclk = XCLK_GPIO_NUM;
config.pin_pclk = PCLK_GPIO_NUM;
config.pin_vsync = VSYNC_GPIO_NUM;
config.pin_href = HREF_GPIO_NUM;
config.pin_sscb_sda = SIOD_GPIO_NUM;
config.pin_sscb_scl = SIOC_GPIO_NUM;
config.pin_pwdn = PWDN_GPIO_NUM;
config.pin_reset = RESET_GPIO_NUM;

Частота камеры:

config.xclk_freq_hz = 20000000;

Формат изображения, качество и размер кадра OV2640

Формат изображения:

config.pixel_format = PIXFORMAT_JPEG; //YUV422,GRAYSCALE,RGB565,JPEG

Формат изображения может быть одним из следующих вариантов:

  • PIXFORMAT_YUV422

  • PIXFORMAT_GRAYSCALE

  • PIXFORMAT_RGB565

  • PIXFORMAT_JPEG

Затем устанавливаются размер кадра, качество jpeg и количество фреймбуферов. Мы выбираем разные настройки в зависимости от того, используете ли вы камеру с PSRAM или без PSRAM.

// Select lower framesize if the camera doesn't support PSRAM
if(psramFound()){
  config.frame_size = FRAMESIZE_UXGA; // FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA
  config.jpeg_quality = 10; //10-63 lower number means higher quality
  config.fb_count = 2;
} else {
  config.frame_size = FRAMESIZE_SVGA;
  config.jpeg_quality = 12;
  config.fb_count = 1;
}

Размер кадра может быть установлен в одно из этих значений:

  • FRAMESIZE_UXGA (1600 x 1200)

  • FRAMESIZE_QVGA (320 x 240)

  • FRAMESIZE_CIF (352 x 288)

  • FRAMESIZE_VGA (640 x 480)

  • FRAMESIZE_SVGA (800 x 600)

  • FRAMESIZE_XGA (1024 x 768)

  • FRAMESIZE_SXGA (1280 x 1024)

Качество изображения (jpeg_quality) может быть числом от 0 до 63. Меньшее число означает более высокое качество. Однако очень низкие значения качества изображения, особенно при более высоком разрешении, могут привести к сбою ESP32-CAM или к тому, что он не сможет правильно сделать фотографии.

Поэтому, если вы заметите, что изображения, сделанные ESP32-CAM, обрезаны наполовину или имеют странные цвета, это, вероятно, знак того, что вам нужно снизить качество (выбрать более высокое число).

Инициализация камеры OV2640

Следующие строки инициализируют камеру:

// Initialize the Camera
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
  Serial.printf("Camera init failed with error 0x%x", err);
  return;
}

После этого вы можете добавить строки кода, которые мы показали ранее, для изменения настроек изображения.

Настройки OV2640: яркость, контрастность, насыщенность, баланс белого, экспозиция и другое

Значения, установленные в следующих строках, являются значениями по умолчанию. Вы можете изменить их для настройки параметров изображения.

sensor_t * s = esp_camera_sensor_get();
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);       // 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_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
s->set_lenc(s, 1);           // 0 = disable , 1 = enable
s->set_hmirror(s, 0);        // 0 = disable , 1 = enable
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

Демонстрация

Измените настройки камеры в коде, чтобы отрегулировать изображение. Затем загрузите код на ESP32-CAM.

Нажмите кнопку RST на ESP32-CAM, и он начнёт делать фотографии. Затем извлеките карту microSD, чтобы просмотреть фотографии.

Ниже вы можете увидеть несколько изображений, сделанных с различными настройками.

ESP32-CAM фото с включённым эффектом Grayscale

ESP32-CAM: фото с включённым эффектом Grayscale

ESP32-CAM фото с яркостью, установленной на 2

ESP32-CAM: фото с яркостью, установленной на 2

ESP32-CAM с контрастностью 2 и насыщенностью -2

ESP32-CAM: контрастность установлена на 2, насыщенность на -2

ESP32-CAM фото с настройками по умолчанию

ESP32-CAM: фото с настройками по умолчанию

По моему мнению, в этих условиях лучшие настройки для получения лучшего изображения: контрастность установлена на 2, а насыщенность на -2.

Заключение

В этом уроке вы узнали, как изменить настройки камеры для регулировки изображения, получаемого с камеры OV2640.

Это может быть полезно, потому что в зависимости от того, где вы разместите камеру, вам может потребоваться изменить настройки для получения лучшего изображения.

Вы можете использовать функции, которые мы показали здесь, в любом из ваших проектов с ESP32-CAM для настройки параметров. У нас есть несколько проектов с ESP32-CAM, которые могут вам понравиться: