Door Camera - Code

From RoboWiki
Jump to: navigation, search

Return back to project page: Door camera - Jakub Vojtek

Python code for the Door Camera project:

 
import cv2
from buildhat import DistanceSensor
from datetime import datetime
import threading
import sqlite3
import os
import time

distance_sensor = DistanceSensor('A')

video_capture = cv2.VideoCapture(0)
frame_width = 480
frame_height = 360
video_capture.set(cv2.CAP_PROP_FRAME_WIDTH, frame_width)
video_capture.set(cv2.CAP_PROP_FRAME_HEIGHT, frame_height)

# face detector
face_classifier = cv2.CascadeClassifier(cv2.data.haarcascades + "haarcascade_frontalface_default.xml")

current_frame = None
lock = threading.Lock()

# create camera_pictures directory if it doesn't exist
if not os.path.exists("camera_pictures"):
    os.makedirs("camera_pictures")

db_directory = "database"
if not os.path.exists(db_directory):
    os.makedirs(db_directory)

db_filename = os.path.join(db_directory, "face_images.db")

conn = sqlite3.connect(db_filename)
c = conn.cursor()

c.execute('''
    CREATE TABLE IF NOT EXISTS images (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        timestamp TEXT NOT NULL,
        detected_faces INTEGER NOT NULL
    )
''')
conn.commit()

def camera_thread():
    global current_frame
    while True:
        result, frame = video_capture.read()
        if result:
            with lock:
                current_frame = frame

def take_and_save_picture():
    with lock:
        if current_frame is not None:
            video_frame = current_frame.copy()
            gframe = cv2.cvtColor(video_frame, cv2.COLOR_BGR2GRAY)

            faces = face_classifier.detectMultiScale(gframe, 1.1, 5, minSize=(40, 40))

            detected_faces = len(faces)
            if detected_faces > 0:
                faces = sorted(faces, key=lambda x: x[2] * x[3], reverse=True)
                x, y, width, height = faces[0]
                cv2.rectangle(video_frame, (x, y), (x + width, y + height), (0, 255, 0), 4)
            else:
                cv2.putText(video_frame, "Face couldn't be detected", (video_frame.shape[1] - 250, video_frame.shape[0] - 10),
                            cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1, cv2.LINE_AA)

            timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            cv2.putText(video_frame, timestamp, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2, cv2.LINE_AA)

            filename = f"camera_pictures/face_detected_{datetime.now().strftime('%Y%m%d_%H%M%S')}.jpg"
            cv2.imwrite(filename, video_frame)
            print(f"Saved image: {filename}")

            # save time and amount of detected faces to database
            c.execute('''
                INSERT INTO images (timestamp, detected_faces)
                VALUES (?, ?)
            ''', (timestamp, detected_faces))
            conn.commit()

            time.sleep(1)


if __name__ == '__main__':
    threading.Thread(target=camera_thread, daemon=True).start()

    try:
        while True:
            distance = distance_sensor.get_distance()
            if distance < 300:
                take_and_save_picture()
    finally:
        video_capture.release()
        cv2.destroyAllWindows()
        conn.close()