我有一组图像,我想递归地预测下一张图像中一堆像素的位置。我正在使用 Python、OpenCV,并且相信卡尔曼滤波可能是前进的方向,但我正在努力实现。为简单起见,下面的代码打开图像并仅提取一个颜色 channel ,在本例中为红色 channel 。
到目前为止,我使用光流来确定每个像素在 X 和 Y 方向的图像之间的运动。每次迭代后,我想使用最后 N 次迭代,并通过使用每次找到的 X/Y 运动,计算像素的速度,并预测它将在下一帧中结束的位置。我将查看和预测的像素组未指定,但与示例无关。它只是 (x,y) 值的 Numpy 数组。
如有任何帮助,我们将不胜感激。下面是简化的代码片段:
import numpy as np
import cv2
from PIL import Image
imageNames = ["image1.jpg", "image2.jpg", "image3.jpg", "image4.jpg", "image5.jpg"]
for i in range(len(imageNames)):
# Load images and extract just one colour channel (e.g., red)
image1 = Image.open(imageNames[i])
image2 = Image.open(imageNames[i+1])
image1R = np.asarray(image1[:,:,0]).astype(np.uint8)
image2R = np.asarray(image2[:,:,0]).astype(np.uint8)
# Get optical flow
flow = cv2.calcOpticalFlowFarneback(image1R, image2R, 0.5, 1, 5, 15, 10, 5, 1)
change_in_x = flow[:,:,0]
change_in_y = flow[:,:,1]
# Use previous flows to obtain velocity in x and y
# For a subset of the image, predict where points will be in the next image
# Use Kalman filtering?
# Repeat recursively
最佳答案
我不确定我是否可以在这里解释一下;但我会试一试。卡尔曼滤波器只不过是一个基于预测测量(校正)的循环。
在两张图像之后你有你的初始状态(位置和速度):
X0 = [x0 v0]
where v0 is the flow between image1 and image2.
and x0 is the position at image2.
做一个假设(比如恒速模型)。在恒速假设下,您将预测该物体将移动到 X1 = A* X0,其中 A 是从恒速模型方程中找到的:
x1 = x0 + v0*T
v1 = v0
=> X1 = [x1 v1]
= [1 T ; 0 1] * [x0 v0]
= [1 T ; 0 1] * X0
T 是您的采样时间(如果与相机一起使用,通常被视为帧速率)。您需要在此处了解图像的时差。
稍后,您将通过下一个测量(在此处加载 image3 并从 image2 和 image3 的流中获取 v1'。同时从中获取 x1'图 3).
X1' = [x1' y1']
对于更简单版本的KF,求平均点作为估计,即
~X1 = (X1 + X1')/2.
如果你想使用精确的过滤器,并使用卡尔曼增益和 coveriance 计算,我会说你需要查看 algorithm ,第 4 页。如果您的图像足够准确(这是传感器噪声),请将 R 调小。
您会发现 ~X1 会将您带到起点。将初始状态替换为 ~X1 并执行相同的过程。
如果您检查 opencv doc ,该算法可能已经存在供您使用。
如果您不打算使用相机和 opencv 方法;我建议您使用 MATLAB,因为它更容易操作矩阵。
关于python - 使用 Python、OpenCV 和卡尔曼滤波进行二维运动估计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17520711/