MotionDetection.ino 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. #define MAX_RESOLUTION_VGA
  2. #include "esp32cam.h"
  3. #include "esp32cam/JpegDecoder.h"
  4. #include "esp32cam/motion/Detector.h"
  5. #include "esp32cam/motion/SimpleChange.h"
  6. Eloquent::Esp32cam::Cam cam;
  7. Eloquent::Esp32cam::JpegDecoder decoder;
  8. Eloquent::Esp32cam::Motion::SimpleChange algorithm;
  9. Eloquent::Esp32cam::Motion::Detector detector(algorithm);
  10. void motion_detection_setup() {
  11. cam.aithinker();
  12. cam.highQuality();
  13. cam.vga();
  14. cam.highestSaturation();
  15. /**
  16. * For motion detection to perform well, I suggest
  17. * you disable automatic controls, otherwise
  18. * the camera sensor will artificially alter the
  19. * pixels and those will be mis-labelled as foreground
  20. */
  21. cam.disableAutomaticWhiteBalance();
  22. cam.disableAutomaticExposureControl();
  23. cam.disableGainControl();
  24. /**
  25. * Configure the detector
  26. */
  27. /**
  28. * use the first N frames to train the algorithm
  29. */
  30. detector.trainFor(30);
  31. /**
  32. * re-run the training aftern N frames
  33. * (at 33 FPS, 33 * 600 = 10 minutes)
  34. */
  35. detector.retrainAfter(33ULL * 600);
  36. /**
  37. * detection motion when 20% or more pixels of the frame
  38. * are labelled as background
  39. */
  40. detector.triggerAbove(0.2);
  41. /**
  42. * try to remove spurious foreground pixels
  43. */
  44. detector.denoise();
  45. /**
  46. * Configure algorithm
  47. * (each algorithm has its own set of parameters)
  48. */
  49. /**
  50. * label pixel as foreground if its value changed
  51. * by more than 20 (in a range from 0 to 255)
  52. */
  53. algorithm.differBy(20);
  54. /**
  55. * when updating the pixel value, how much shall we
  56. * take into consideration its previous value?
  57. * The higher this value, the stronger influence
  58. * the pixel history has w.r.t. its current value
  59. * The update formula is
  60. * updated value = a * old value + (1 - a) * new value
  61. * Where a in in the range 0 - 1 (1 excluded)
  62. */
  63. algorithm.smooth(0.9);
  64. /**
  65. * when a pixel is labelled as foreground, should we
  66. * update its value or not?
  67. * It is updated by default, so if that's what you want,
  68. * remove the following line.
  69. */
  70. algorithm.onlyUpdateBackground();
  71. while (!cam.begin())
  72. Serial.println(cam.getErrorMessage());
  73. }
  74. void motion_detection_loop() {
  75. if (!cam.capture()) {
  76. Serial.println(cam.getErrorMessage());
  77. return;
  78. }
  79. if (!decoder.decode(cam)) {
  80. Serial.println(decoder.getErrorMessage());
  81. return;
  82. }
  83. /**
  84. * Update the background model
  85. * If there's an error, print it
  86. *
  87. * Note: while training, `update()` will return False
  88. * even if it cannot really considered an error.
  89. * If you want to check if the error is due to training or not,
  90. * you can check for `detector.isTraining()`
  91. */
  92. if (!detector.update(decoder.luma)) {
  93. Serial.println(detector.getErrorMessage());
  94. return;
  95. }
  96. /**
  97. * Test if motion was detected
  98. */
  99. if (detector.triggered()) {
  100. Serial.println("Motion!");
  101. }
  102. /**
  103. * After the call to `triggered()`, you can debug the internal
  104. * status of the detector if you want to find out why it triggered or not
  105. */
  106. Serial.println(detector.getTriggerStatus());
  107. }