import cv2 import numpy as np from collections import deque
# 전역 변수 설정 WIDTH = 640 HEIGHT = 480 is_paused = False
# 칼만 필터 초기화 kalman = cv2.KalmanFilter(4, 2) kalman.measurementMatrix = np.array([[1, 0, 0, 0], [0, 1, 0, 0]], np.float32) kalman.transitionMatrix = np.array([[1, 0, 1, 0], [0, 1, 0, 1], [0, 0, 1, 0], [0, 0, 0, 1]], np.float32) # 프로세스 노이즈를 낮춰서 예측이 더 멀리 진행되도록 설정 kalman.processNoiseCov = np.array([[1,0,0,0], [0,1,0,0], [0,0,1,0], [0,0,0,1]], np.float32) * 0.001 # 측정 노이즈를 낮춰서 측정값을 더 신뢰하도록 설정 kalman.measurementNoiseCov = np.array([[1,0], [0,1]], np.float32) * 0.1
# 궤적 저장용 큐 TRAIL_LENGTH = 50 measured_points = deque(maxlen=TRAIL_LENGTH) predicted_points = deque(maxlen=TRAIL_LENGTH)
# 윈도우 생성 cv2.namedWindow("Kalman Filter Tracking")
# 원형 운동 변수 t = 0 center_x, center_y = WIDTH//2, HEIGHT//2 radius = 100 angular_velocity = 0.05
# 이전 위치 저장 변수 (속도 계산용) last_x, last_y = None, None
while True: frame = np.zeros((HEIGHT, WIDTH, 3), dtype=np.uint8) # 원형 운동 위치 계산 if not is_paused: t += angular_velocity current_x = int(center_x + radius * np.cos(t)) current_y = int(center_y + radius * np.sin(t)) # 칼만 필터 예측 prediction = kalman.predict() pred_point = (int(prediction[0]), int(prediction[1])) # 측정값 업데이트 measurement = np.array([[np.float32(current_x)], [np.float32(current_y)]]) # 정지 상태일 때는 속도 성분을 유지 if not is_paused: kalman.correct(measurement) if last_x is not None and last_y is not None: # 현재 속도 계산 및 상태 벡터 업데이트 dx = current_x - last_x dy = current_y - last_y state = kalman.statePost state[2] = dx # x 방향 속도 state[3] = dy # y 방향 속도 kalman.statePost = state # 현재 위치 저장 last_x, last_y = current_x, current_y # 파란색 원 그리기 cv2.circle(frame, (current_x, current_y), 20, (255, 0, 0), -1) center = (current_x, current_y) # 궤적 저장 measured_points.append(center) predicted_points.append(pred_point) # 예측 궤적 그리기 (빨간색) points = list(predicted_points) for i in range(1, len(points)): if points[i-1] is not None and points[i] is not None: thickness = 2 if not is_paused else 3 cv2.line(frame, points[i-1], points[i], (0, 0, 255), thickness) # 측정 궤적 그리기 (파란색) points = list(measured_points) for i in range(1, len(points)): if points[i-1] is not None and points[i] is not None: cv2.line(frame, points[i-1], points[i], (255, 0, 0), 2) # 현재 예측 위치 표시 pred_radius = 5 if not is_paused else 8 cv2.circle(frame, pred_point, pred_radius, (0, 0, 255), -1) # 일시정지 상태 표시 if is_paused: cv2.putText(frame, "PAUSED", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2) cv2.imshow("Kalman Filter Tracking", frame) key = cv2.waitKey(30) & 0xFF if key == ord('q'): break elif key == ord(' '): is_paused = not is_paused
cv2.destroyAllWindows() |
Member discussion