Attention please

[OpenCV] OpenCV를 이용한 얼굴 감지 CCTV 만들기 본문

프로젝트

[OpenCV] OpenCV를 이용한 얼굴 감지 CCTV 만들기

Seongmin.C 2023. 1. 10. 17:11

이번에 소개할 프로젝트는 opencv를 활용한 얼굴 감지 CCTV이다.

 

얼굴을 감지하여 원이 같이 따라간다.

 

위 동영상처럼 얼굴을 감지하기 위해 mediapipe 라이브러리를 사용하였다. mediapipe는 얼굴 감지 뿐만 아닌 Object Detection, KNIFT 등등 다양한 기능들이 존재한다.

https://google.github.io/mediapipe/

 

Home

Cross-platform, customizable ML solutions for live and streaming media.

google.github.io

 

이번에 필요한 기능은 face detection이기 때문에 관련 코드를 먼저 가져왔다.

 

import cv2
import mediapipe as mp
mp_face_detection = mp.solutions.face_detection
mp_drawing = mp.solutions.drawing_utils

# For static images:
IMAGE_FILES = []
with mp_face_detection.FaceDetection(
    model_selection=1, min_detection_confidence=0.5) as face_detection:
  for idx, file in enumerate(IMAGE_FILES):
    image = cv2.imread(file)
    # Convert the BGR image to RGB and process it with MediaPipe Face Detection.
    results = face_detection.process(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))

    # Draw face detections of each face.
    if not results.detections:
      continue
    annotated_image = image.copy()
    for detection in results.detections:
      print('Nose tip:')
      print(mp_face_detection.get_key_point(
          detection, mp_face_detection.FaceKeyPoint.NOSE_TIP))
      mp_drawing.draw_detection(annotated_image, detection)
    cv2.imwrite('/tmp/annotated_image' + str(idx) + '.png', annotated_image)

# For webcam input:
cap = cv2.VideoCapture(0)
with mp_face_detection.FaceDetection(
    model_selection=0, min_detection_confidence=0.5) as face_detection:
  while cap.isOpened():
    success, image = cap.read()
    if not success:
      print("Ignoring empty camera frame.")
      # If loading a video, use 'break' instead of 'continue'.
      continue

    # To improve performance, optionally mark the image as not writeable to
    # pass by reference.
    image.flags.writeable = False
    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    results = face_detection.process(image)

    # Draw the face detection annotations on the image.
    image.flags.writeable = True
    image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
    if results.detections:
      for detection in results.detections:
        mp_drawing.draw_detection(image, detection)
    # Flip the image horizontally for a selfie-view display.
    cv2.imshow('MediaPipe Face Detection', cv2.flip(image, 1))
    if cv2.waitKey(5) & 0xFF == 27:
      break
cap.release()

 

이 중에서 webcam만을 사용하기 때문에 관련 코드만 가져와 약간의 수정을 해주었다.

 

        if results.detections:
            for detection in results.detections:
                keypoints = detection.location_data.relative_keypoints
                nose = keypoints[2]

                h, w, _ = image.shape
                nose = (int(nose.x * w), int(nose.y * h))

                cv2.circle(image, nose, 100, (0, 255, 0), cv2.FILLED, cv2.LINE_AA)

 

이 코드에서 제공되는 face bounding box대신 cv2.circle함수를 사용하여 얼굴 중심에 원을 그려주었다. 이를 위해 코에 해당되는 좌표를 가져와 원을 그려주었다.

 

여기까지 하면 이미 얼굴을 감지하는 webcam은 완성되었다. 하지만 이번에 만들 것은 몰래 나의 컴퓨터를 만지는 사람을 감지하고 증거물을 남겨야 하기 때문에 얼굴이 감지되는 동안의 영상을 저장해주어야 한다. 

 

영상을 저장하기 위해 다음 코드를 추가로 수정해주었다.

 

# codec
fourcc = cv2.VideoWriter_fourcc(*'DIVX')

# FPS
width = round(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) 
height = round(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = cap.get(cv2.CAP_PROP_FPS)  

out = cv2.VideoWriter('warning.avi', fourcc, fps, (width, height))

 

다음과 같이 코덱과 FPS를 설정해준 후 비디오를 저장해주는 객체 하나를 out이라는 변수에 저장한다.

 

        if results.detections:
            print('warning')
            out.write(image)

            warning = True

    

out.release()
cap.release()
cv2.destroyAllWindows()

 

다음 코드를 추가하여 사람이 감지되는 순간 'warning' 문구를 출력함과 동시에 해당 frame을 저장한다. 이제 해당 경로를 확인해보면 warning.avi 파일이 생성되어 있을 것이다.

 

현재 경로에 동영상 파일이 생성되었다.

 

 

 

 

Comments