| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- #define MAX_RESOLUTION_VGA
- // Using EloquentEsp32cam library
- #include "esp32cam.h"
- #include "esp32cam/JpegDecoder.h"
- #include "esp32cam/motion/Detector.h"
- #include "esp32cam/motion/SimpleChange.h"
- Eloquent::Esp32cam::Cam cam;
- Eloquent::Esp32cam::JpegDecoder decoder;
- Eloquent::Esp32cam::Motion::SimpleChange algorithm;
- Eloquent::Esp32cam::Motion::Detector detector(algorithm);
- void motion_detection_setup() {
- cam.aithinker();
- cam.highQuality();
- cam.vga();
- cam.highestSaturation();
- /**
- * For motion detection to perform well, I suggest
- * you disable automatic controls, otherwise
- * the camera sensor will artificially alter the
- * pixels and those will be mis-labelled as foreground
- */
- cam.disableAutomaticWhiteBalance();
- cam.disableAutomaticExposureControl();
- cam.disableGainControl();
- /**
- * Configure the detector
- */
- /**
- * use the first N frames to train the algorithm
- */
- detector.trainFor(30);
- /**
- * re-run the training aftern N frames
- * (at 33 FPS, 33 * 600 = 10 minutes)
- */
- detector.retrainAfter(33ULL * 600);
- /**
- * detection motion when 20% or more pixels of the frame
- * are labelled as background
- */
- detector.triggerAbove(0.2);
- /**
- * try to remove spurious foreground pixels
- */
- detector.denoise();
- /**
- * Configure algorithm
- * (each algorithm has its own set of parameters)
- */
- /**
- * label pixel as foreground if its value changed
- * by more than 20 (in a range from 0 to 255)
- */
- algorithm.differBy(20);
- /**
- * when updating the pixel value, how much shall we
- * take into consideration its previous value?
- * The higher this value, the stronger influence
- * the pixel history has w.r.t. its current value
- * The update formula is
- * updated value = a * old value + (1 - a) * new value
- * Where a in in the range 0 - 1 (1 excluded)
- */
- algorithm.smooth(0.9);
- /**
- * when a pixel is labelled as foreground, should we
- * update its value or not?
- * It is updated by default, so if that's what you want,
- * remove the following line.
- */
- algorithm.onlyUpdateBackground();
- while (!cam.begin())
- Serial.println(cam.getErrorMessage());
- }
- unsigned long nextMotionAlert = 0;
- void motion_detection_loop() {
- if (!cam.capture()) {
- Serial.println(cam.getErrorMessage());
- return;
- }
- if (!decoder.decode(cam)) {
- Serial.println(decoder.getErrorMessage());
- return;
- }
- /**
- * Update the background model
- * If there's an error, print it
- *
- * Note: while training, `update()` will return False
- * even if it cannot really considered an error.
- * If you want to check if the error is due to training or not,
- * you can check for `detector.isTraining()`
- */
- if (!detector.update(decoder.luma)) {
- Serial.println(detector.getErrorMessage());
- return;
- }
- /**
- * Test if motion was detected
- */
- if (detector.triggered() && millis()>nextMotionAlert) {
- Serial.println("Motion!");
- nextMotionAlert = millis()+1000;
- }
- /**
- * After the call to `triggered()`, you can debug the internal
- * status of the detector if you want to find out why it triggered or not
- */
- Serial.println(detector.getTriggerStatus());
- }
|