Python에서 OpenCV를 사용한 칼만 필터

Manav Narula 2023년1월30일
  1. Python에서 opencv를 사용하는 칼만 필터
  2. 결론
Python에서 OpenCV를 사용한 칼만 필터

Computer Vision은 인공 지능의 이미지 및 비디오 처리와 관련된 다양한 복잡한 작업을 처리합니다. 우리는 Python의 opencv 라이브러리를 사용하여 이러한 작업 중 일부를 처리합니다.

이 라이브러리는 이러한 문제 중 일부를 해결하기 위해 개체를 사용하여 다양한 알고리즘과 기술을 구현합니다.

그러한 작업 중 하나는 주어진 물체의 궤적을 예측하는 것입니다. 이를 위해 사용되는 가장 일반적인 알고리즘 중 하나는 칼만 필터입니다.

이 튜토리얼은 파이썬에서 opencv를 사용하여 칼만 필터를 보여줍니다.

Python에서 opencv를 사용하는 칼만 필터

칼만 필터는 객체의 이전 상태를 사용하여 다음 상태를 예측합니다. 이 알고리즘은 선형 확률적 차이 방정식을 사용하여 다음 상태를 결정합니다.

우리는 이 방정식과 관련된 몇 가지 행렬에 익숙해질 필요가 있습니다.

첫째, 상태 전이 행렬은 현재 상태를 이전 상태와 연결합니다. 선택적으로 제어 입력 행렬을 사용하여 입력을 제어할 수 있습니다.

변환 행렬을 사용하여 달성되는 일부 측정 영역으로 상태를 변환해야 합니다. 또한 공분산이 있는 프로세스 노이즈 벡터가 있어야 합니다.

Python에서는 opencv 라이브러리의 KalmanFilter 클래스를 사용하여 이 알고리즘을 구현하고 상태를 예측할 수 있습니다. 이 클래스에 대한 개체의 속성을 정의하고 필요한 행렬을 할당합니다.

measurementMatrix, transitionMatrixprocessNoiseCov 속성은 각각 이전에 논의된 측정 행렬, 전이 행렬 및 공분산이 있는 프로세스 잡음 행렬을 지정합니다. 그런 다음 객체를 사용하여 predict() 함수를 사용하여 몇 가지 예측을 할 수 있습니다.

예를 들어 이것을 더 잘 이해합시다.

import cv2
import numpy as np

measured = []
predicted = []
dr_frame = np.zeros((400, 400, 3), np.uint8)
mp = np.array((2, 1), np.float32)
tp = np.zeros((2, 1), np.float32)


def on_mouse(k, x, y, s, p):
    global mp, measured
    mp = np.array([[np.float32(x)], [np.float32(y)]])
    measured.append((x, y))


def paint_canvas():
    global dr_frame, measured, predicted
    for i in range(len(measured) - 1):
        cv2.line(dr_frame, measured[i], measured[i + 1], (0, 100, 0))
    for i in range(len(predicted) - 1):
        cv2.line(dr_frame, predicted[i], predicted[i + 1], (0, 0, 200))


def reset_canvas():
    global measured, predicted, dr_frame
    measured = []
    predicted = []
    dr_frame = np.zeros((400, 400, 3), np.uint8)


cv2.namedWindow("Sample")
cv2.setMouseCallback("Sample", on_mouse)
kalman_fil = cv2.KalmanFilter(4, 2)
kalman_fil.measurementMatrix = np.array([[1, 0, 0, 0], [0, 1, 0, 0]], np.float32)
kalman_fil.transitionMatrix = np.array(
    [[1, 0, 1, 0], [0, 1, 0, 1], [0, 0, 1, 0], [0, 0, 0, 1]], np.float32
)
kalman_fil.processNoiseCov = (
    np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]], np.float32)
    * 0.03
)

while True:
    kalman_fil.correct(mp)
    tp = kalman_fil.predict()
    predicted.append((int(tp[0]), int(tp[1])))
    paint_canvas()
    cv2.imshow("Output", dr_frame)
    k = cv2.waitKey(30) & 0xFF
    if k == 27:
        break
    if k == 32:
        reset_canvas()

출력:

Python에서 opencv를 사용하는 칼만 필터

위의 예에서 칼만 필터를 구현하고 이를 사용하여 마우스 움직임을 예측합니다. 우리는 캔버스를 만들고 이 캔버스(녹색)에 커서를 이동하고 동시에 칼만 필터는 커서 이동(빨간색)을 예측하려고 시도합니다.

코드에서 무슨 일이 일어나고 있는지 이해합시다.

커서 움직임을 그릴 수 있는 캔버스 프레임을 만드는 것으로 시작합니다. on_mouse() 함수는 커서 값을 추가하는 데 사용됩니다.

paint_canvas() 메서드는 이러한 값과 예측된 값을 가져와 캔버스에 그립니다. setMouseCallback() 함수도 커서가 이동할 때마다 호출됩니다.

kalman_fil 객체라는 KalmanFilter 클래스를 생성합니다. 필요한 매트릭스는 이전에 논의된 속성을 사용하여 할당되었습니다.

그런 다음 루프를 실행하여 캔버스에 그리고 예측을 수행합니다.

이 클래스의 correct() 메서드는 측정에서 예측된 상태를 업데이트합니다. predict() 함수는 예측을 수행합니다.

이러한 예측 값은 paint_canvas() 메서드에 제공됩니다.

루프에서 벗어나기 위해 break 문을 사용하며 사용자가 Esc 키(키보드의 키 번호 27)를 누를 때 호출됩니다. 스페이스바를 누르면 reset_canvas() 메서드를 호출하여 캔버스가 이전 측정에서 지워집니다.

결론

마무리하기 위해 이 튜토리얼에서 칼만 필터의 기본 사항에 대해 논의했습니다. 우리는 그 이면에 필요한 논리와 속성에 대해 논의했습니다.

opencv 라이브러리의 KalmanFilter 클래스를 사용하여 이 알고리즘을 구현했습니다. 이 클래스의 다른 매개변수와 멤버 함수가 시연되었습니다.

알고리즘을 사용하여 그리기 캔버스에서 커서의 움직임을 예측합니다.

작가: Manav Narula
Manav Narula avatar Manav Narula avatar

Manav is a IT Professional who has a lot of experience as a core developer in many live projects. He is an avid learner who enjoys learning new things and sharing his findings whenever possible.

LinkedIn