ESP32-S3-WROOM Freenove Board can't take grayscale photo

User avatar
BehicMV
Posts: 5
Joined: Fri Mar 31, 2023 11:20 am

ESP32-S3-WROOM Freenove Board can't take grayscale photo

Postby BehicMV » Mon Jan 29, 2024 12:49 pm

Hi,
I have a ESP32-S3-WROOM module which has camera and micro SD card module. I can take a snapshot a PIXELFORMAT_JPEG photo. However, when I change the pixelformat with "PIXELFORMAT_GRAYSCALE", I cant save a valid photo.

Average SVGA colored JPEG photo takes about 25-35 kB space. However the pixelformat grayscale files takes 480.000 B constant. Also the files could not open. (Corrupted). Here is my code:

Code: Select all

/**********************************************************************
  Filename    : Camera and SDcard
  Description : Use the onboard buttons to take photo and save them to an SD card.
  Auther      : www.freenove.com
  Modification: 2022/11/02
**********************************************************************/
#include "esp_camera.h"
#define CAMERA_MODEL_ESP32S3_EYE
#include "camera_pins.h"
#include "ws2812.h"
#include "sd_read_write.h"

#define BUTTON_PIN  0

void setup() {
  Serial.begin(115200);
  Serial.setDebugOutput(false);
  Serial.println();
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  ws2812Init();
  sdmmcInit();
  //removeDir(SD_MMC, "/camera");
  createDir(SD_MMC, "/camera");
  listDir(SD_MMC, "/camera", 0);
  if(cameraSetup()==1){
    ws2812SetColor(2);
  }
  else{
    ws2812SetColor(1);
    return;
  }
}

void loop() {
  if(digitalRead(BUTTON_PIN)==LOW){
    delay(20);
    if(digitalRead(BUTTON_PIN)==LOW){
      ws2812SetColor(3);
      while(digitalRead(BUTTON_PIN)==LOW);
      camera_fb_t * fb = NULL;
      fb = esp_camera_fb_get();
      if (fb != NULL) {
        int photo_index = readFileNum(SD_MMC, "/camera");
        if(photo_index!=-1)
        {
          String path = "/camera/" + String(photo_index) +".jpg";
          writejpg(SD_MMC, path.c_str(), fb->buf, fb->len);
        }
        esp_camera_fb_return(fb);
      }
      else {
        Serial.println("Camera capture failed.");
      }
      ws2812SetColor(2);
    }
  }
}

int cameraSetup(void) {
  camera_config_t config;
  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;
  config.frame_size = FRAMESIZE_UXGA;
  config.pixel_format = PIXFORMAT_GRAYSCALE; // for streaming
  config.grab_mode = CAMERA_GRAB_WHEN_EMPTY;
  config.fb_location = CAMERA_FB_IN_PSRAM;
  config.jpeg_quality = 12;
  config.fb_count = 1;
  
  // if PSRAM IC present, init with UXGA resolution and higher JPEG quality
  // for larger pre-allocated frame buffer.
  if(psramFound()){
    config.jpeg_quality = 10;
    config.fb_count = 2;
    config.grab_mode = CAMERA_GRAB_LATEST;
  } else {
    // Limit the frame size when PSRAM is not available
    config.frame_size = FRAMESIZE_SVGA;
    config.fb_location = CAMERA_FB_IN_DRAM;
  }

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

  sensor_t * s = esp_camera_sensor_get();
  // initial sensors are flipped vertically and colors are a bit saturated
  s->set_vflip(s, 1); // flip it back
  s->set_brightness(s, 1); // up the brightness just a bit
  s->set_saturation(s, 0); // lower the saturation

  Serial.println("Camera configuration complete!");
  return 1;
}
Also here is the writejpg function:

Code: Select all

void writejpg(fs::FS &fs, const char * path, const uint8_t *buf, size_t size){
    File file = fs.open(path, FILE_WRITE);
    if(!file){
      Serial.println("Failed to open file for writing");
       ws2812SetColor(1);
        delay(100);
      return;
    }
    file.write(buf, size);
     // Define the chunk size
    const size_t chunkSize = 2048;

    // Write to serial in chunks
    for(size_t i = 0; i < size; i += chunkSize) {
        // Calculate the size of the current chunk
        size_t currentChunkSize = ((i + chunkSize) <= size) ? chunkSize : (size - i);

        // Write the current chunk to serial
        Serial.write(buf + i, currentChunkSize);
        Serial.println();
    }
    Serial.printf("Saved file to path: %s\r\n", path);
}

I also printed out the the image data to the Serial monitor. It is completely useless than JPEG pixel format image data.Weird thing is the saved files are 480 kB constant.

So anyone has an idea about this problem? Any idea can be useful.
Attachments
Board.jpg
The ESP32-S3-WROOM Module that I have.
Board.jpg (544.96 KiB) Viewed 922 times
Screenshot from 2024-01-29 15-44-48.png
Screenshot from 2024-01-29 15-44-48.png (35.76 KiB) Viewed 922 times
Screenshot from 2024-01-29 15-44-00.png
480kB constant file sizes.
Screenshot from 2024-01-29 15-44-00.png (11.57 KiB) Viewed 922 times

User avatar
BehicMV
Posts: 5
Joined: Fri Mar 31, 2023 11:20 am

Re: ESP32-S3-WROOM Freenove Board can't take grayscale photo

Postby BehicMV » Wed Jan 31, 2024 8:04 am

Found it. The 480kB data is raw grayscale data which requires jpeg conversion. And there is a function for compressing this kind of compressions called "frame2jpg()".

Hope it helps!

Who is online

Users browsing this forum: No registered users and 96 guests