title: esp32_cam read and process image
body: <p>I am trying to use tensorflow-lite on a esp32_cam to classify images.
  I defined the following sub-tasks that i need to solve:</p>
  <ol>
  <li>Take photo</li>
  <li>Reduce size of photo to (e.g.) 28x28 pixels grayscale</li>
  <li>run inference with trained model</li>
  </ol>
  <p>For now I am stuck between point 1 and 2 and cannot get it solved.
  What i have done so far:
  I save an image into buffer using <code>esp_camera_fb_get()</code>. Afterwards I put the values from the buffer inside a 2D array.
  However, when I print out some of these values, they never become 0 nor 255, even though I coverd the whole lens or put a bright light source close to it.</p>
  <p>I have four questions:</p>
  <ol>
  <li>How do i correctly record an image?</li>
  <li>How can I convert it into a 2D array?</li>
  <li>How can I downsample the size from (e.g.) 160x120 to 28x28?</li>
  <li>how can I correctly <code>Serial.print()</code> each pixel value to copy the values and plot them on my computer (e.g. with python matplotlib)</li>
  </ol>
  <p><code>#define  CAMERA_MODEL_AI_THINKER</code></p>
  <pre><code> #include &lt;esp_camera.h&gt;
   #include &quot;camera_pins.h&quot;
  
   #define FRAME_SIZE FRAMESIZE_QQVGA
   #define WIDTH 160
   #define HEIGHT 120    
  
   uint16_t img_array [HEIGHT][WIDTH] = { 0 };
  
  
   bool setup_camera(framesize_t);
   void frame_to_array(camera_fb_t * frame);
   void print_image_shape(camera_fb_t * frame);
   bool capture_image();
  
   void setup() {
       Serial.begin(115200);
       Serial.println(setup_camera(FRAME_SIZE) ? &quot;OK&quot; : &quot;ERR INIT&quot;);
   }
  
   void loop() {
       if (!capture_image()) {
           Serial.println(&quot;Failed capture&quot;);
           delay(2000);
  
           return;
       }
  
       //print_features();
       delay(3000);
   }
  
  
  
   bool setup_camera(framesize_t frameSize) {
       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.pixel_format = PIXFORMAT_GRAYSCALE;
       config.frame_size = frameSize;
       config.jpeg_quality = 12;
       config.fb_count = 1;
  
       bool ok = esp_camera_init(&amp;config) == ESP_OK;
  
       sensor_t *sensor = esp_camera_sensor_get();
       sensor-&gt;set_framesize(sensor, frameSize);
  
       return ok;
   }
  
  
  
   bool capture_image() {
  
       camera_fb_t * frame = NULL;
       frame = esp_camera_fb_get();
  
       print_image_shape(frame);
  
       frame_to_array(frame);
  
       esp_camera_fb_return(frame);
  
       if (!frame)
           return false;
  
       return true;
   }
  
  
   void print_image_shape(camera_fb_t * frame){
  
       // print shape of image and total length (=heigth*width)
       Serial.print(&quot;Width: &quot;);
       Serial.print(frame-&gt;width);
       Serial.print(&quot;\tHeigth: &quot;);
       Serial.print(frame-&gt;height);
       Serial.print(&quot;\tLength: &quot;);
       Serial.println(frame-&gt;len);
   }
  
   void frame_to_array(camera_fb_t * frame){
  
       int len = frame-&gt;len;
       char imgBuffer[frame-&gt;len];
       int counter = 0;
  
       uint16_t img_array [HEIGHT][WIDTH] = { 0 };
  
       int h_counter = 0;
       int w_counter = 0;
  
       // write values from buffer into 2D Array
       for (int h=0; h &lt; HEIGHT; h++){
           //Serial.println(h);
           for (int w=0; w &lt; WIDTH; w++){
               //Serial.println(w);
               int position = h*(len/HEIGHT)+w;
  
               //Serial.println(position);
               img_array[h][w] = {frame-&gt;buf[position]};
  
               //Serial.print(img_array[h][w]);
               //Serial.print(&quot;,&quot;);
               //delay(2);
           }
       }
  
  
       //Serial.println(&quot;Current frame:&quot;);
  
       Serial.println(&quot;=====================&quot;);
  
   }
  </code></pre>
  <p>camera_pin.h:</p>
  <pre><code>#if defined(CAMERA_MODEL_WROVER_KIT)
  #define PWDN_GPIO_NUM    -1
  #define RESET_GPIO_NUM   -1
  #define XCLK_GPIO_NUM    21
  #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      19
  #define Y4_GPIO_NUM      18
  #define Y3_GPIO_NUM       5
  #define Y2_GPIO_NUM       4
  #define VSYNC_GPIO_NUM   25
  #define HREF_GPIO_NUM    23
  #define PCLK_GPIO_NUM    22
  
  #elif defined(CAMERA_MODEL_ESP_EYE)
  #define PWDN_GPIO_NUM    -1
  #define RESET_GPIO_NUM   -1
  #define XCLK_GPIO_NUM    4
  #define SIOD_GPIO_NUM    18
  #define SIOC_GPIO_NUM    23
  
  #define Y9_GPIO_NUM      36
  #define Y8_GPIO_NUM      37
  #define Y7_GPIO_NUM      38
  #define Y6_GPIO_NUM      39
  #define Y5_GPIO_NUM      35
  #define Y4_GPIO_NUM      14
  #define Y3_GPIO_NUM      13
  #define Y2_GPIO_NUM      34
  #define VSYNC_GPIO_NUM   5
  #define HREF_GPIO_NUM    27
  #define PCLK_GPIO_NUM    25
  
  #elif defined(CAMERA_MODEL_M5STACK_PSRAM)
  #define PWDN_GPIO_NUM     -1
  #define RESET_GPIO_NUM    15
  #define XCLK_GPIO_NUM     27
  #define SIOD_GPIO_NUM     25
  #define SIOC_GPIO_NUM     23
  
  #define Y9_GPIO_NUM       19
  #define Y8_GPIO_NUM       36
  #define Y7_GPIO_NUM       18
  #define Y6_GPIO_NUM       39
  #define Y5_GPIO_NUM        5
  #define Y4_GPIO_NUM       34
  #define Y3_GPIO_NUM       35
  #define Y2_GPIO_NUM       32
  #define VSYNC_GPIO_NUM    22
  #define HREF_GPIO_NUM     26
  #define PCLK_GPIO_NUM     21
  
  #elif defined(CAMERA_MODEL_M5STACK_WIDE)
  #define PWDN_GPIO_NUM     -1
  #define RESET_GPIO_NUM    15
  #define XCLK_GPIO_NUM     27
  #define SIOD_GPIO_NUM     22
  #define SIOC_GPIO_NUM     23
  
  #define Y9_GPIO_NUM       19
  #define Y8_GPIO_NUM       36
  #define Y7_GPIO_NUM       18
  #define Y6_GPIO_NUM       39
  #define Y5_GPIO_NUM        5
  #define Y4_GPIO_NUM       34
  #define Y3_GPIO_NUM       35
  #define Y2_GPIO_NUM       32
  #define VSYNC_GPIO_NUM    25
  #define HREF_GPIO_NUM     26
  #define PCLK_GPIO_NUM     21
  
  #elif defined(CAMERA_MODEL_AI_THINKER)
  #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
  
  #else
  #error &quot;Camera model not selected&quot;
  #endif
  </code></pre>