Files
SceneSense/camera-client/camera_monitor.py
Muhamad H. Asadi 0cf729e90e added detection delay feature for preventing bulk record generation
added headers and API Key parts
Changes to be committed:
	modified:   camera-client/camera_monitor.py
2023-09-21 23:02:01 +03:30

136 lines
4.4 KiB
Python

import cv2
import time
import requests
import numpy as np
from datetime import datetime
import os
import json
import logging as lg
import argparse
class CameraMonitor:
def __init__(self, config, logger):
self.config = config
self.logger = logger
self.last_detection = 0
def initialize_camera(self):
"""
Initialize the camera and return the VideoCapture object.
"""
cap = cv2.VideoCapture(self.config['camera_address'])
if not cap.isOpened():
raise Exception(f"Failed to open camera at {self.config['camera_address']}")
return cap
def log_scene_change(self):
"""
Log a scene change notification to the Scenesense server.
"""
current_time = int(time.time())
human_readable_time = datetime.utcfromtimestamp(
current_time
).strftime('%Y-%m-%d %H:%M:%S')
description = f'Scene change detected at {human_readable_time}'
payload = {
'timestamp': current_time,
'description': description
}
headers = {
'Authorization': self.config['api_key']
}
if (
current_time - self.last_detection >= self.config['detection_delay']
):
try:
response = requests.post(
self.config['api_url'],
json=payload,
headers=headers
)
response.raise_for_status()
self.logger.info(f'Scene change logged: {description}')
except requests.exceptions.RequestException as e:
self.logger.error(f'Error connecting to Scenesense server: {e}')
except requests.exceptions.HTTPError as e:
self.logger.error(f'HTTP error: {e}')
def detect_scene_change(self, previous_frame, current_frame):
"""
Detect scene change based on frame differences.
"""
frame_diff = cv2.absdiff(previous_frame, current_frame)
mean_diff = np.mean(frame_diff)
return mean_diff > self.config['sensitivity_threshold']
def run(self):
try:
with self.initialize_camera() as cap:
previous_frame = None
while True:
ret, current_frame = cap.read()
if not ret:
raise Exception("Failed to read frame")
if previous_frame is not None:
if self.detect_scene_change(previous_frame, current_frame):
self.log_scene_change()
previous_frame = current_frame
except KeyboardInterrupt:
self.logger.info("Camera monitoring stopped by user.")
except Exception as e:
self.logger.error(f"An error occurred: {e}")
def parse_command_line_args():
parser = argparse.ArgumentParser(description='Camera Monitor for Scenesense')
parser.add_argument('--config', type=str, default='config.json', help='Path to configuration file')
return parser.parse_args()
def load_config(config_path):
try:
with open(config_path, 'r') as config_file:
return json.load(config_file)
except FileNotFoundError:
raise Exception(f"Config file not found: {config_path}")
except json.JSONDecodeError:
raise Exception(f"Invalid JSON format in config file: {config_path}")
def setup_logging(log_file='logs/camera_monitor.log'):
# logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
# return logging.getLogger('CameraMonitor')
# Configure the logger
logger = lg.getLogger('CameraMonitor')
logger.setLevel(lg.INFO)
# Create a TimedRotatingFileHandler for log rotation
file_handler = lg.handlers.TimedRotatingFileHandler(
log_file, when='midnight', backupCount=7
) # Keeps logs for 7 days
file_handler.suffix = '%Y-%m-%d' # Append date to log file names
# Define the log message format
formatter = lg.Formatter(
'%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
file_handler.setFormatter(formatter)
# Add the file handler to the logger
logger.addHandler(file_handler)
return logger
def main():
args = parse_command_line_args()
config = load_config(args.config)
logger = setup_logging()
monitor = CameraMonitor(config, logger)
monitor.run()
if __name__ == "__main__":
main()