Skip to content

Commit

Permalink
Object detection model (#89)
Browse files Browse the repository at this point in the history
* Update repo structure

* added the whole frontend

* Update repo structure

* Adding object detection model

* added object detection model

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
  • Loading branch information
devxMani and github-actions[bot] authored Nov 4, 2024
1 parent 3265ecf commit a1ac39e
Show file tree
Hide file tree
Showing 6 changed files with 1,266 additions and 37 deletions.
123 changes: 123 additions & 0 deletions Backend/proctor_core.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# Backend/proctor_core.py
# adding to a new branch
import cv2
import mediapipe as mp
import numpy as np
from typing import Dict, List, Tuple
import logging
import os

# Local imports
from .detection import run_detection
from .head_pose import pose
from .object_detection import detect_objects
from .audio import process_audio
from .screen_recorder import capture_screen

class ProctorCore:
def __init__(self):
self.mp_face_detection = mp.solutions.face_detection
self.mp_pose = mp.solutions.pose
self.face_detection = self.mp_face_detection.FaceDetection(min_detection_confidence=0.7)
self.pose_detection = self.mp_pose.Pose(min_detection_confidence=0.7)
self.logger = self._setup_logger()

def _setup_logger(self) -> logging.Logger:
"""Configure logging for the proctoring system"""
logger = logging.getLogger('ProctorCore')
logger.setLevel(logging.INFO)
handler = logging.StreamHandler()
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
return logger

def start_monitoring(self):
"""Initialize and start all monitoring components"""
try:
# Start detection systems
detection_result = run_detection()
pose_result = pose()
screen_capture = capture_screen()

# Process and combine results
combined_results = self._process_results(
detection_result,
pose_result,
screen_capture
)

return combined_results

except Exception as e:
self.logger.error(f"Error in monitoring: {str(e)}")
raise

def _process_results(self, detection_data, pose_data, screen_data) -> Dict:
"""Process and combine results from different detection systems"""
results = {
'timestamp': np.datetime64('now'),
'detection': detection_data,
'pose': pose_data,
'screen': screen_data,
'suspicious_level': 0.0
}

# Calculate suspicious level based on combined factors
suspicious_factors = [
detection_data.get('suspicious_score', 0),
pose_data.get('deviation_score', 0),
screen_data.get('activity_score', 0)
]

results['suspicious_level'] = np.mean([x for x in suspicious_factors if x is not None])

return results

def save_results(self, results: Dict, output_path: str = None):
"""Save monitoring results to specified location"""
if output_path is None:
output_path = os.path.join(
os.path.dirname(__file__),
'Dataset',
f'proctor_results_{np.datetime64("now")}.json'
)

try:
import json
with open(output_path, 'w') as f:
json.dump(results, f, indent=4, default=str)
self.logger.info(f"Results saved to {output_path}")
except Exception as e:
self.logger.error(f"Error saving results: {str(e)}")

def analyze_behavior(self, results: Dict) -> Dict:
"""Analyze monitored behavior and generate insights"""
analysis = {
'timestamp': np.datetime64('now'),
'overall_score': results.get('suspicious_level', 0),
'warnings': [],
'recommendations': []
}

# Generate warnings based on thresholds
if results.get('pose', {}).get('deviation_score', 0) > 0.7:
analysis['warnings'].append('Significant head movement detected')

if results.get('detection', {}).get('suspicious_score', 0) > 0.7:
analysis['warnings'].append('Suspicious objects detected')

if results.get('screen', {}).get('activity_score', 0) > 0.7:
analysis['warnings'].append('Unusual screen activity detected')

return analysis

def cleanup(self):
"""Cleanup resources and close connections"""
try:
cv2.destroyAllWindows()
self.logger.info("Cleanup completed successfully")
except Exception as e:
self.logger.error(f"Error during cleanup: {str(e)}")


126 changes: 105 additions & 21 deletions Backend/run.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,112 @@
import head_pose
import detection
# Backend/run.py
# adding to a new branch
import threading as th
import logging
import os
from typing import Dict, List
import queue
from .proctor_core import ProctorCore

def run_threads():
try:
# Create threads for each target function
head_pose_thread = th.Thread(target=head_pose.pose)
# audio_thread = th.Thread(target=audio.sound) # Uncomment if audio module is needed
detection_thread = th.Thread(target=detection.run_detection)

# Start the threads
head_pose_thread.start()
# audio_thread.start() # Uncomment to start audio thread
detection_thread.start()

# Wait for the threads to complete
head_pose_thread.join()
# audio_thread.join() # Uncomment to wait for audio thread
detection_thread.join()
class ProctorManager:
def __init__(self):
self.result_queue = queue.Queue()
self.proctor = ProctorCore()
self.is_running = False
self.threads: List[th.Thread] = []
self.logger = self._setup_logger()

def _setup_logger(self):
logger = logging.getLogger('ProctorManager')
logger.setLevel(logging.INFO)
handler = logging.StreamHandler()
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
return logger

def _monitoring_worker(self):
"""Worker function for continuous monitoring"""
while self.is_running:
try:
results = self.proctor.start_monitoring()
self.result_queue.put(results)
except Exception as e:
self.logger.error(f"Error in monitoring worker: {str(e)}")
break

def _analysis_worker(self):
"""Worker function for analyzing results"""
while self.is_running:
try:
results = self.result_queue.get(timeout=1)
if results:
analysis = self.proctor.analyze_behavior(results)
self.proctor.save_results(analysis)
except queue.Empty:
continue
except Exception as e:
self.logger.error(f"Error in analysis worker: {str(e)}")
break

def start(self):
"""Start the proctoring system"""
try:
self.is_running = True

# Create worker threads
monitoring_thread = th.Thread(target=self._monitoring_worker)
analysis_thread = th.Thread(target=self._analysis_worker)

# Start threads
self.threads = [monitoring_thread, analysis_thread]
for thread in self.threads:
thread.start()

self.logger.info("Proctoring system started successfully")

except Exception as e:
self.logger.error(f"Error starting proctoring system: {str(e)}")
self.stop()

def stop(self):
"""Stop the proctoring system"""
self.is_running = False

# Wait for threads to complete
for thread in self.threads:
thread.join()

# Cleanup resources
self.proctor.cleanup()
self.logger.info("Proctoring system stopped")

def main():
# Setup logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)

try:
# Initialize and start the proctoring system
manager = ProctorManager()
manager.start()

# Keep running until interrupted
while True:
pass

except KeyboardInterrupt:
logger.info("Received shutdown signal")
except Exception as e:
print(f"An error occurred: {e}")
logger.error(f"Unexpected error: {str(e)}")
finally:
print("All threads have been joined.")
if 'manager' in locals():
manager.stop()
logger.info("Application shutdown complete")

if __name__ == "__main__":
run_threads()
main()


11 changes: 9 additions & 2 deletions PROJECT_STRUCTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -225,19 +225,24 @@
│ ├── SQLFILE.sql
│ ├── __pycache__/
│ │ ├── audio.cpython-311.pyc
│ │ ├── audio.cpython-312.pyc
│ │ ├── detection.cpython-311.pyc
│ │ └── head_pose.cpython-311.pyc
│ │ ├── head_pose.cpython-311.pyc
│ │ └── head_pose.cpython-312.pyc
│ ├── audio.py
│ ├── detection.py
│ ├── face-rec.py
│ ├── graph.py
│ ├── head_pose.py
│ ├── logic.xlsx
│ ├── object_detection.py
│ ├── peer_comparison_tool.py
│ ├── processes.py
│ ├── pyaudio_test.py
│ ├── run.py
│ └── screen_recorder.py
│ ├── screen_recorder.py
│ ├── test-image.jpg
│ └── test-image2.jpg
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── GSSoC-Ext.png
Expand All @@ -260,6 +265,8 @@
│ ├── contributor.css
│ ├── contributor.html
│ └── contributor.js
├── frontend/
│ └── index.html
├── heatmap_combined_20241009_144503.png
├── login.py
├── modle.png
Expand Down
Loading

0 comments on commit a1ac39e

Please sign in to comment.