简体   繁体   English

使用Python,OpenCV和卡尔曼滤波进行2D运动估计

[英]2D motion estimation using Python, OpenCV & Kalman filtering

I have a set of images, and would like to recursively predict where a bunch of pixels will be in the next image. 我有一组图像,并且想递归地预测下一个图像中的像素点。 I am using Python, OpenCV, and believe Kalman filtering may be the way forward, but am struggling on the implementation. 我使用的是Python,OpenCV,并相信卡尔曼过滤可能是前进的方向,但在实现上却步履维艰。 For simplicity, the code below opens and image and extracts just one colour channel, in this case the red one. 为简单起见,下面的代码将打开并显示图像,并仅提取一种颜色通道,在这种情况下为红色。

So far, I am using optical flow to determine the motion between images in X and Y for each pixel. 到目前为止,我正在使用光流确定每个像素在X和Y图像之间的运动。 After each iteration, I would like to use the last N iterations, and by using the X/Y motions found each time, calculate the velocity of the pixel, and predict where it will end up in the next frame. 每次迭代之后,我想使用最近的N次迭代,并使用每次找到的X / Y运动来计算像素的速度,并预测像素在下一帧的结束位置。 The group of pixels I will look at and predict is not specified, but is not relevant for the example. 我将查看和预测的像素组未指定,但与示例无关。 It would just be a Numpy array of (x,y) values. 它只是一个(x,y)值的Numpy数组。

Any help would be greatly appreciated. 任何帮助将不胜感激。 Simplified code snippet below: 以下是简化的代码段:

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

I am not sure if I can explain this here; 我不确定是否可以在这里解释。 but I will have a shot. 但我会试一试。 Kalman filter is nothing but a prediction-measurement (correction) based loop. 卡尔曼滤波器不过是基于预测测量(校正)的循环。

You have your initial state (position and velocity) after two images: 在两幅图像之后,您便拥有了初始状态(位置和速度):

X0 = [x0 v0] 

where v0 is the flow between image1 and image2. 其中v0是image1和image2之间的流。

and x0 is the position at image2. x0是image2的位置。

Make an assumption (like constant velocity model). 做一个假设(如恒速模型)。 Under constant velocity assumption, you will predict this object will move to X1 = A* X0 where A is found from constant velocity model equations: 在恒定速度假设下,您将预测该对象将移动到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 is your sampling time (generally taken as the frame rate if used with cameras). T是您的采样时间(如果与相机一起使用,则通常作为帧速率)。 You need to know the time difference of your images here. 您需要在此处了解图像的时差。

Later, you are going to correct this assumption with the next measurement (load image3 here and obtain v1' from flow of image2 and image3. Also take x1' from image3). 稍后,您将通过下一个测量来纠正此假设(在此处加载image3并从image2和image3的流中获取v1'。还要从image3中获取x1')。

X1' = [x1' y1'] 

For a simpler version of KF, find the average point as the estimation, ie 对于更简单的KF版本,找到平均点作为估计值,即

~X1 = (X1 + X1')/2. 

If you want to use the exact filter, and use kalman gain and coveriance calculations, I'd say you need to check out the algorithm , page 4. Take R small if your images are accurate enough (it is the sensor noise). 如果要使用精确的滤波器,并使用卡尔曼增益和覆盖率计算,我想说的是,您需要检查算法 ,第4页。如果图像足够准确,则将R减小(这是传感器噪声)。

The ~X1 you will find takes you to the start. 您会发现〜X1,使您开始。 Replace initial state with ~X1 and go over same procedure. 将初始状态替换为〜X1并执行相同的步骤。

If you check the opencv doc , the algorithm might already be there for you to use. 如果您检查opencv doc ,则该算法可能已经存在供您使用。

If you are not going to use a camera and opencv methods; 如果您不打算使用相机和opencv方法; I would suggest you to use MATLAB, just because it is easier to manipulate matrices there. 我建议您使用MATLAB,只是因为在那里更容易操作矩阵。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM