MotionDetection.ino 3.2 KB

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