OpenCV/OpenCV 강좌

YoLo를 사용하여 영상에 사람이 있었던 총시간을 측정하는 OpenCV Python 예제

webnautes 2025. 1. 28. 23:28
반응형

YoLo를 사용하여 영상내와 영상 바깥에 사람이 있었던 총시간을 각각 출력하는 OpenCV Python 예제입니다.

한사람만 보이는 경우를 가정하고 있습니다. 



최초작성 2025. 1. 28




https://youtu.be/4geryGplg24

 

 

 

import cv2
from ultralytics import YOLO
from datetime import datetime, timedelta


# 사용할 욜로 모델을 지정합니다.
model = YOLO('yolov8n.pt')

# 카메라를 지정합니다.
cap = cv2.VideoCapture(0)
start_time = None

# 변수를 초기화합니다.
total_sitting_time = timedelta()
total_standing_time = timedelta()
last_state = None  # 'sitting' or 'standing'
last_update_time = datetime.now()


while True:

    # 카메라로부터 이미지를 가져옵니다.
    ret, frame = cap.read()
    if not ret:
        break
       
    # 이미지를 입력으로 욜로 모델을 사용합니다.
    results = model(frame)

    # 디폴트 값은 사람이 감지 안된 상태입니다.
    person_detected = False
   
    # 욜로 모델에서 감지한 객체들을 하나씩 체크합니다.
    for r in results[0].boxes.data:
       
        # x1: 왼쪽 끝 x 좌표, y1: 위쪽 끝 y 좌표, x2: 오른쪽 끝 x 좌표, y2: 아래쪽 끝 y 좌표
        # conf : confidence score (신뢰도 점수). 모델이 얼마나 확신을 가지고 객체를 탐지했는지를 나타냄. 1에 가까울수록 더 확실한 탐지를 의미
        # cls: class index (클래스 인덱스). 감지된 객체의 종류를 나타내는 숫자
        x1, y1, x2, y2, conf, cls = r

        # 사람감지 체크
        if int(cls) == 0# 0번은 person class
            person_detected = True
            overlay = frame.copy()

            # 사람 영역에 붉은색 배경을 씌웁니다.
            cv2.rectangle(overlay, (int(x1), int(y1)), (int(x2), int(y2)), (0,0,255), -1)
            frame = cv2.addWeighted(overlay, 0.3, frame, 0.7, 0)
   

    current_time = datetime.now()
   
    # 사람이 감지된 경우 앉아있는 시간을 누적합니다.
    if person_detected:

        if last_state != 'sitting':
            if last_state is not None:
                total_standing_time += current_time - last_update_time
            last_state = 'sitting'
            last_update_time = current_time
           
        if start_time is None:
            start_time = current_time
        duration = current_time - start_time
        time_str = str(timedelta(seconds=int(duration.total_seconds())))
       
        current_sitting_duration = current_time - last_update_time
        temp_total_sitting = total_sitting_time + current_sitting_duration

    # 사람이 감지안된 경우 서있는 시간을 누적합니다.    
    else# person not detected (standing)
       
        if last_state != 'standing':
            if last_state is not None:
                total_sitting_time += current_time - last_update_time
            last_state = 'standing'
            last_update_time = current_time
           
        start_time = None
        current_standing_duration = current_time - last_update_time
        temp_total_standing = total_standing_time + current_standing_duration
   

    # 이미지에 정보를 출력합니다.
    sitting_str = str(temp_total_sitting if person_detected else total_sitting_time).split('.')[0]
    standing_str = str(temp_total_standing if not person_detected else total_standing_time).split('.')[0]
   
    cv2.putText(frame, f'Total Sitting Time: {sitting_str}', (10, 30),
                cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
    cv2.putText(frame, f'Total Standing Time: {standing_str}', (10, 60),
                cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 0, 0), 2)
   
    current_state = "Sitting" if person_detected else "Standing"
    cv2.putText(frame, f'Current State: {current_state}', (10, 90),
                cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
           

    # 이미지를 화면에 보옂줍니다.
    cv2.imshow('Person Detection', frame)
   

    #  ESC 키를 누르면 종료하도록 합니다.
    if cv2.waitKey(1) & 0xFF == 27
        break


# 최종 누적 시간을 계산합니다.
if last_state == 'sitting':
    total_sitting_time += datetime.now() - last_update_time
else:
    total_standing_time += datetime.now() - last_update_time

# 최종 누적 시간을 터미널에 출력합니다.
print(f"\nFinal Results:")
print(f"Total Sitting Time: {str(total_sitting_time).split('.')[0]}")
print(f"Total Standing Time: {str(total_standing_time).split('.')[0]}")


# 자원을 해제합니다.
cap.release()
cv2.destroyAllWindows()

 

반응형