In this short post I will show you how to use the EloquentArduino library to extract an RGB histogram from your ESP32-cam images for computer vision tasks.
An RGB histogram is actually composed of 3 distinct histograms, one for each color channel, that describe how many pixels in the image have a given value. So, on the x
axis you have the possibile values (from 0 to 255), on the y
axis you have the count of pixels that have that specific value.
Since differentiating each single value would give a quite "sparse" histogram, it is often desiderable to bin the values. Binning (or bucketing) means that instead of counting how many pixels have a given exact value, we count how many pixels fall in a certain range: in this way, pixels that have a value of 1 or 2, for example, are grouped together into the same bin.
The EloquentArduino library makes it a piece of cake to compute the RGB histogram of an ESP32-cam image. You only have to set the number of bins you want.
EloquentArduino
library version 1.1.9 from the Arduino IDE Library Manager!#define CAMERA_MODEL_M5STACK_WIDE
#define FRAME_SIZE FRAMESIZE_QVGA
#define NUM_BINS 32
#include <EloquentArduino.h>
#include <eloquentarduino/vision/camera/ESP32Camera.h>
#include <eloquentarduino/vision/processing/RGBHistogram.h>
Eloquent::Vision::Camera::ESP32Camera camera(PIXFORMAT_RGB565);
Eloquent::Vision::Processing::RGBHistogram<NUM_BINS> hist;
/**
* Function prototype
*/
void printHistogram(uint16_t *hist, char bar = '|', uint8_t divisor = 10);
/**
*
*/
void setup() {
Serial.begin(115200);
camera.begin(FRAME_SIZE);
delay(4000);
}
/**
*
*/
void loop() {
camera_fb_t *frame = camera.capture();
// actually compute histogram
hist.update(frame->buf, frame->len);
// the hist object has the attributes rHistogram, gHistrogram, bHistogram
// that contain the calculated histograms
printHistogram(hist.gHistogram);
delay(4000);
}
/**
* Print histogram on the serial monitor
*/
void printHistogram(uint16_t *hist, char bar, uint8_t divisor) {
// for each bin
for (uint8_t i = 0; i < NUM_BINS; i++) {
Serial.printf("%-2d ", i);
// print row proportional to its height
for (uint16_t j = hist[i] / divisor; j > 0; j--) {
Serial.print(bar);
}
Serial.println();
}
}
The above code does very few things:
- it uses the
ESP32Camera
class to take a photo in RGB565 format from the camera - it uses the
RGBHistogram
class to compute the R, G, B histograms from that photo - it prints the histogram to the Serial monitor for debugging purposes
What you actually do with the histogram is really up to you: computer vision is a wide topic!
Check the full project code on Github and remember to star!