동작 감지의 OpenCV 핵심 기술
OpenCV는 동작 추적을 위한 영상 처리 기능을 제공합니다. 프레임 차분, 배경 제거, 윤곽 검출 기법으로 움직이는 객체의 위치와 궤적을 식별합니다.
영상 전처리 단계
- 비디오 스트림에서 프레임 획득
- 계산 효율화를 위한 그레이스케일 변환
- 가우시안 블러로 노이즈 제거
import cv2
video_source = cv2.VideoCapture(0)
_, current_frame = video_source.read()
_, previous_frame = video_source.read()
gray_current = cv2.cvtColor(current_frame, cv2.COLOR_BGR2GRAY)
gray_current = cv2.GaussianBlur(gray_current, (15, 15), 0)
움직임 감지 기법 비교
| 방법 | 장점 | 적용 분야 |
| 프레임 차분 | 구현 간단, 빠른 응답 | 실시간 모니터링 |
| 배경 차감 | 정밀도 높음, 조명 변화 강건 | 고정 카메라 환경 |
graph LR
A[프레임 수집] --> B[그레이스케일]
B --> C[노이즈 필터링]
C --> D[프레임 비교]
D --> E[이진화]
E --> F[윤곽 탐지]
F --> G[바운딩 박스 그리기]
포즈 감지 환경 구성
OpenCV 기본 작업
import cv2
image_data = cv2.imread('sample.jpg')
cv2.imshow('Display', image_data)
cv2.waitKey(0)
cv2.destroyAllWindows()
의존성 관리
pip install -r requirements.txt
실시간 비디오 처리
capture = cv2.VideoCapture(0)
while capture.isOpened():
status, image_frame = capture.read()
if not status:
break
gray_frame = cv2.cvtColor(image_frame, cv2.COLOR_BGR2GRAY)
cv2.imshow('Processing', gray_frame)
if cv2.waitKey(20) & 0xFF == 27:
break
capture.release()
키포인트 감지 모델
| 모델 | 입력 크기 | 키포인트 |
| MoveNet | 192×192 | 17개 |
| OpenPose | 368×368 | 18개 |
MediaPipe 스켈레톤 렌더링
import mediapipe as mp
pose_estimator = mp.solutions.pose.Pose()
sketch_utils = mp.solutions.drawing_utils
video_stream = cv2.VideoCapture(0)
while video_stream.isOpened():
_, frame = video_stream.read()
rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
detected_pose = pose_estimator.process(rgb_frame)
if detected_pose.pose_landmarks:
sketch_utils.draw_landmarks(frame, detected_pose.pose_landmarks, mp.solutions.pose.POSE_CONNECTIONS)
cv2.imshow('Skeleton', frame)
if cv2.waitKey(5) == 27:
break
동작 분석 원리
키포인트 시퀀스 처리
import numpy as np
pose_sequence = np.random.rand(5, 17, 2) # 5프레임, 17개 관절
관절 각도 계산
import math
def get_joint_angle(point_a, point_b, point_c):
vector_ab = (point_a[0]-point_b[0], point_a[1]-point_b[1])
vector_cb = (point_c[0]-point_b[0], point_c[1]-point_b[1])
dot_product = vector_ab[0]*vector_cb[0] + vector_ab[1]*vector_cb[1]
magnitude_ab = math.hypot(vector_ab[0], vector_ab[1])
magnitude_cb = math.hypot(vector_cb[0], vector_cb[1])
cosine = dot_product / (magnitude_ab * magnitude_cb)
return math.degrees(math.acos(max(-1.0, min(1.0, cosine))))
실시간 시스템 구현
상태 머신 설계
| 현재 상태 | 트리거 | 다음 상태 |
| 대기 | 시작 명령 | 준비 |
| 준비 | 조건 충족 | 실행 |
데이터 출력 최적화
function formatOutput(data, formatType) {
if (formatType === 'csv') {
return data.map(item => Object.values(item).join(',')).join('\n');
} else {
return JSON.stringify(data, null, 2);
}
}
성능 튜닝
-Xms2g -Xmx2g -XX:+UseG1GC