def detect_motion(self, camera, debug_detection): motionDetected = False timeStart = time.time() #--- if (CamMotionDetector._frame_processed_count >= 10): CamMotionDetector._frame_processed_fps = CamMotionDetector._frame_processed_count / ( timeStart - CamMotionDetector._frame_processed_start_time) CamMotionDetector._frame_processed_count = 0 CamMotionDetector._frame_processed_start_time = timeStart else: CamMotionDetector._frame_processed_count += 1 #--- # finish to dump previous ymi file before to process next dectection if (CamMotionDetector._frame_before_ymi_dump < 0): pass elif (CamMotionDetector._frame_before_ymi_dump > 0): CamMotionDetector._frame_before_ymi_dump -= 1 else: # Dump images used for detection up to detection time filename = self._motionDetectedPrefixFilename + ".ymi" filepath = self._motionDebugPath + filename write_image_buffer(filepath) FtpUploader.upload_move(self.remotePath, filename, filepath) CamMotionDetector._frame_before_ymi_dump = -1 #--- stream = io.BytesIO() camera.capture(stream, format='yuv', resize=(CamMotionDetector._detectionImageWidth, CamMotionDetector._detectionImageHeight), use_video_port=True) stream.seek(0) time1 = time.time() - timeStart timeStart2 = time.time() if self._buffer1 is None: #self._buffer1 = bytearray(stream.getbuffer()) self._buffer1 = stream.getbuffer() else: #--- Motion Detection ----------------------------------------------- # Compare current_image to prior_image to detect motion. # Buffer packed 4 byte per pixel, line after line. (RGBA)(RGBA) # process on a copy improve performance by 30%. but we cannot modify image buffer anymore #self._buffer2 = bytearray(stream.getbuffer()) self._buffer2 = stream.getbuffer() motionDetected = detect_motion(self._buffer1, self._buffer2) self._buffer1 = self._buffer2 time2 = time.time() - timeStart2 #self._counter_debug_dump += 1 # Debug when threshold is reached #if (motionDetected or self._counter_debug_dump >= 10): if (motionDetected and debug_detection): #self._counter_debug_dump = 0 timeStart3 = time.time() nowtime = datetime.now() camera_name = config.config['camera']['name'] self._motionDetectedPrefixFilename = "%s-%04d%02d%02d-%02d%02d%02d" % ( camera_name, nowtime.year, nowtime.month, nowtime.day, nowtime.hour, nowtime.minute, nowtime.second) self.remotePath = ("%04d" % (nowtime.year), "%02d" % (nowtime.month), "%02d/" % (nowtime.day)) #--- # Schedule YMI file generation (if not yet scheduled) if (CamMotionDetector._frame_before_ymi_dump < 0): CamMotionDetector._frame_before_ymi_dump = 180 #--- filename = self._motionDetectedPrefixFilename + ".tiff" filepath = self._motionDebugPath + filename img = Image.frombuffer( "CMYK", (self._detectionImageWidth, self._detectionImageHeight), self._debugImageData, 'raw', "CMYK", 0, 1) img.save(filepath) FtpUploader.upload_move(self.remotePath, filename, filepath) #--- if (motionDetected): filename = self._motionDetectedPrefixFilename + ".txt" else: filename = self._motionDetectedPrefixFilename + "-debug.txt" filepath = self._motionDebugPath + filename time3 = time.time() - timeStart3 with open(filepath, "w") as file: file.write( "Cam Motion Detector: [%d,%d] noiseLevel=%d noiseLevelForHistory=%d sensitivity=%d\n" % (self._detectionImageWidth, self._detectionImageHeight, CamMotionDetector._noiseLevel, CamMotionDetector._noiseLevelForHistory, CamMotionDetector._sensitivity)) file.write( "Motion Detection: {:.0f} fps (capture {:.0f} ms | processing {:.0f} ms | dump {:.0f} ms)\n" .format(CamMotionDetector._frame_processed_fps, 1000 * time1, 1000 * time2, 1000 * time3)) file.write(motion_message()) FtpUploader.upload_move(self.remotePath, filename, filepath) #--- #--- time4 = time.time() - timeStart return motionDetected
def detect_motion(self, camera, debug_detection): motionDetected = False timeStart = time.time() # --- if CamMotionDetector._frame_processed_count >= 10: CamMotionDetector._frame_processed_fps = CamMotionDetector._frame_processed_count / ( timeStart - CamMotionDetector._frame_processed_start_time ) CamMotionDetector._frame_processed_count = 0 CamMotionDetector._frame_processed_start_time = timeStart else: CamMotionDetector._frame_processed_count += 1 # --- # finish to dump previous ymi file before to process next dectection if CamMotionDetector._frame_before_ymi_dump < 0: pass elif CamMotionDetector._frame_before_ymi_dump > 0: CamMotionDetector._frame_before_ymi_dump -= 1 else: # Dump images used for detection up to detection time filename = self._motionDetectedPrefixFilename + ".ymi" filepath = self._motionDebugPath + filename write_image_buffer(filepath) FtpUploader.upload_move(self.remotePath, filename, filepath) CamMotionDetector._frame_before_ymi_dump = -1 # --- stream = io.BytesIO() camera.capture( stream, format="yuv", resize=(CamMotionDetector._detectionImageWidth, CamMotionDetector._detectionImageHeight), use_video_port=True, ) stream.seek(0) time1 = time.time() - timeStart timeStart2 = time.time() if self._buffer1 is None: # self._buffer1 = bytearray(stream.getbuffer()) self._buffer1 = stream.getbuffer() else: # --- Motion Detection ----------------------------------------------- # Compare current_image to prior_image to detect motion. # Buffer packed 4 byte per pixel, line after line. (RGBA)(RGBA) # process on a copy improve performance by 30%. but we cannot modify image buffer anymore # self._buffer2 = bytearray(stream.getbuffer()) self._buffer2 = stream.getbuffer() motionDetected = detect_motion(self._buffer1, self._buffer2) self._buffer1 = self._buffer2 time2 = time.time() - timeStart2 # self._counter_debug_dump += 1 # Debug when threshold is reached # if (motionDetected or self._counter_debug_dump >= 10): if motionDetected and debug_detection: # self._counter_debug_dump = 0 timeStart3 = time.time() nowtime = datetime.now() camera_name = config.config["camera"]["name"] self._motionDetectedPrefixFilename = "%s-%04d%02d%02d-%02d%02d%02d" % ( camera_name, nowtime.year, nowtime.month, nowtime.day, nowtime.hour, nowtime.minute, nowtime.second, ) self.remotePath = ("%04d" % (nowtime.year), "%02d" % (nowtime.month), "%02d/" % (nowtime.day)) # --- # Schedule YMI file generation (if not yet scheduled) if CamMotionDetector._frame_before_ymi_dump < 0: CamMotionDetector._frame_before_ymi_dump = 180 # --- filename = self._motionDetectedPrefixFilename + ".tiff" filepath = self._motionDebugPath + filename img = Image.frombuffer( "CMYK", (self._detectionImageWidth, self._detectionImageHeight), self._debugImageData, "raw", "CMYK", 0, 1, ) img.save(filepath) FtpUploader.upload_move(self.remotePath, filename, filepath) # --- if motionDetected: filename = self._motionDetectedPrefixFilename + ".txt" else: filename = self._motionDetectedPrefixFilename + "-debug.txt" filepath = self._motionDebugPath + filename time3 = time.time() - timeStart3 with open(filepath, "w") as file: file.write( "Cam Motion Detector: [%d,%d] noiseLevel=%d noiseLevelForHistory=%d sensitivity=%d\n" % ( self._detectionImageWidth, self._detectionImageHeight, CamMotionDetector._noiseLevel, CamMotionDetector._noiseLevelForHistory, CamMotionDetector._sensitivity, ) ) file.write( "Motion Detection: {:.0f} fps (capture {:.0f} ms | processing {:.0f} ms | dump {:.0f} ms)\n".format( CamMotionDetector._frame_processed_fps, 1000 * time1, 1000 * time2, 1000 * time3 ) ) file.write(motion_message()) FtpUploader.upload_move(self.remotePath, filename, filepath) # --- # --- time4 = time.time() - timeStart return motionDetected
def run(self): try: log.info("CamProcessorServer Started") camera_name = config.config['camera']['name'] with CamMotionDetector(self._storage_path) as camMotionDetector: # Take a shot at boot, them every hour on the hour log.info("Start After Boot Picture") # LEDProcessor.green(True) with picamera.PiCamera() as camera: nowtime = datetime.now() imageFilename = "%s-%04d%02d%02d-%02d%02d%02d-Boot.jpg" % ( camera_name, nowtime.year, nowtime.month, nowtime.day, nowtime.hour, nowtime.minute, nowtime.second) imageFilepath = self._periodic_path + imageFilename camera.resolution = (2592, 1944) # camera.hflip = True # camera.vflip = True #camera.exif_tags['EXIF.UserComment'] = b'Garden' camera.start_preview() # Camera warm-up time time.sleep(2) # LEDProcessor.green(False) camera.capture(imageFilepath) # LEDProcessor.green(True) remotePath = ("%04d" % (nowtime.year), "%02d" % (nowtime.month), "%02d" % (nowtime.day)) FtpUploader.upload_move(remotePath, imageFilename, imageFilepath) # LEDProcessor.green(False) # LEDProcessor.red(False) # LEDProcessor.blue(False) self.lastPictureTime = datetime.utcnow().hour while not self._terminate: log.info("Start Motion detection") with picamera.PiCamera() as camera: #camera.led = False # LEDProcessor.camera(False) camera.resolution = (1280, 720) # camera.hflip = True # camera.vflip = True camera.framerate = 6 #camera.video_stabilization = True stream = picamera.PiCameraCircularIO(camera, seconds=5) camera.start_recording(stream, format='h264') try: while not self._terminate: camera.wait_recording(0.2) if camMotionDetector.detect_motion( camera, True): self.process_motion( camera, stream, camMotionDetector) # 'datetime.utcnow().hour' take about 25 usec # 'time.gmtime()[3]' take about 26 usec utc_now_hour = datetime.utcnow().hour if (utc_now_hour != self.lastPictureTime): self.lastPictureTime = utc_now_hour break except Exception as e: log.exception("Motion detection") finally: camera.stop_recording() if (self._terminate): log.info("CamProcessorServer terminated %d" % (self._terminate)) break # Take a shot at boot, them every hour on the hour log.info("Start Periodic Picture") # LEDProcessor.green(True) with picamera.PiCamera() as camera: nowtime = datetime.now() log.info('Periodic Picture') imageFilename = "%s-%04d%02d%02d-%02d0000.jpg" % ( camera_name, nowtime.year, nowtime.month, nowtime.day, nowtime.hour) imageFilepath = self._periodic_path + imageFilename camera.resolution = (2592, 1944) # camera.hflip = True # camera.vflip = True #camera.exif_tags['EXIF.UserComment'] = b'Garden' camera.start_preview() # Camera warm-up time time.sleep(1) # LEDProcessor.green(False) camera.capture(imageFilepath) # LEDProcessor.green(True) remotePath = ('Periodic', "%04d" % (nowtime.year), "%02d" % (nowtime.month), "%02d" % (nowtime.day)) FtpUploader.upload_move(remotePath, imageFilename, imageFilepath) # LEDProcessor.green(False) except EnvironmentError as e: log.exception("CamProcessorServer Daemon failed: %d (%s)" % (e.errno, e.strerror)) except Exception as e: log.exception("CamProcessorServer Daemon failed (Exception)") finally: log.info("CamProcessorServer Daemon Exit.")
def run(self): try: log.info("CamProcessorServer Started") camera_name = config.config['camera']['name'] with CamMotionDetector(self._storage_path) as camMotionDetector: # Take a shot at boot, them every hour on the hour log.info("Start After Boot Picture") # LEDProcessor.green(True) with picamera.PiCamera() as camera: nowtime = datetime.now() imageFilename = "%s-%04d%02d%02d-%02d%02d%02d-Boot.jpg" % (camera_name, nowtime.year, nowtime.month, nowtime.day, nowtime.hour, nowtime.minute, nowtime.second) imageFilepath = self._periodic_path + imageFilename camera.resolution = (2592, 1944) # camera.hflip = True # camera.vflip = True #camera.exif_tags['EXIF.UserComment'] = b'Garden' camera.start_preview() # Camera warm-up time time.sleep(2) # LEDProcessor.green(False) camera.capture(imageFilepath) # LEDProcessor.green(True) remotePath = ("%04d" % (nowtime.year), "%02d" % (nowtime.month), "%02d" % (nowtime.day)) FtpUploader.upload_move(remotePath, imageFilename, imageFilepath) # LEDProcessor.green(False) # LEDProcessor.red(False) # LEDProcessor.blue(False) self.lastPictureTime = datetime.utcnow().hour; while not self._terminate: log.info("Start Motion detection") with picamera.PiCamera() as camera: #camera.led = False # LEDProcessor.camera(False) camera.resolution = (1280, 720) # camera.hflip = True # camera.vflip = True camera.framerate = 6 #camera.video_stabilization = True stream = picamera.PiCameraCircularIO(camera, seconds=5) camera.start_recording(stream, format='h264') try: while not self._terminate: camera.wait_recording(0.2) if camMotionDetector.detect_motion(camera, True): self.process_motion(camera, stream, camMotionDetector) # 'datetime.utcnow().hour' take about 25 usec # 'time.gmtime()[3]' take about 26 usec utc_now_hour = datetime.utcnow().hour; if (utc_now_hour != self.lastPictureTime): self.lastPictureTime = utc_now_hour break except Exception as e: log.exception("Motion detection") finally: camera.stop_recording() if (self._terminate): log.info("CamProcessorServer terminated %d" % (self._terminate)) break # Take a shot at boot, them every hour on the hour log.info("Start Periodic Picture") # LEDProcessor.green(True) with picamera.PiCamera() as camera: nowtime = datetime.now() log.info('Periodic Picture') imageFilename = "%s-%04d%02d%02d-%02d0000.jpg" % (camera_name, nowtime.year, nowtime.month, nowtime.day, nowtime.hour) imageFilepath = self._periodic_path + imageFilename camera.resolution = (2592, 1944) # camera.hflip = True # camera.vflip = True #camera.exif_tags['EXIF.UserComment'] = b'Garden' camera.start_preview() # Camera warm-up time time.sleep(1) # LEDProcessor.green(False) camera.capture(imageFilepath) # LEDProcessor.green(True) remotePath = ('Periodic', "%04d" % (nowtime.year), "%02d" % (nowtime.month), "%02d" % (nowtime.day)) FtpUploader.upload_move(remotePath, imageFilename, imageFilepath) # LEDProcessor.green(False) except EnvironmentError as e: log.exception("CamProcessorServer Daemon failed: %d (%s)" % (e.errno, e.strerror)) except Exception as e: log.exception("CamProcessorServer Daemon failed (Exception)") finally: log.info("CamProcessorServer Daemon Exit.")