Просмотр исходного кода

Adding simple motion detection

Erwin Ried 2 лет назад
Родитель
Сommit
130a51fce4
2 измененных файлов с 124 добавлено и 0 удалено
  1. 119 0
      esp32cam_marauder/MotionDetection.ino
  2. 5 0
      esp32cam_marauder/esp32cam_marauder.ino

+ 119 - 0
esp32cam_marauder/MotionDetection.ino

@@ -0,0 +1,119 @@
+#define MAX_RESOLUTION_VGA
+
+#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());
+}
+
+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()) {
+    Serial.println("Motion!");
+  }
+
+  /**
+     * 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());
+}

+ 5 - 0
esp32cam_marauder/esp32cam_marauder.ino

@@ -169,6 +169,11 @@ void setup()
           for (;;)
             qr_reader_loop();
 
+        case 'm':  // Motion detection
+          motion_detection_setup();
+          for (;;)
+            motion_detection_loop();
+
         default:  // Camera stream
           cam_stream_setup();
           for (;;)