Track a pixel between frames using speed (vector) outputs?

With a sequence of frames, I am looking to compute how each pixel moves between two frames (i.e., optical flows). For example, I wish to generate a "pixel movement map" that tells me, for example, pixel '(100, 100)' in frame 1 moves to '(102, 105)' in frame 2.

As this post suggests, I can

enable the desired render layer (ie "vector") and then save the render output as OpenEXR file. That format will save all the desired render layers (in this case, motion information in 4 channels) in a single file...

I now have the OpenEXR images of size '1080x720x3'. The values range from around '-200' to '100'. Given the relatively small motion between two frames in my case, I am sure these numbers are not in pixel unit (also, they are not even integers!).

What exactly are these numbers? How should I process these values to get movement (in both 'x' and 'y' directions; pixel unit) for each pixel?

P.S. -- As I write this question, I realize there will be pixels present in frame 1 but not in frame 2. Not sure how this speed output reflects that?

1 Answer

I've found a solution to my own problem after some research. We need to save all four channels, because

R: pixel displacement in X from current frame to previous frame

G: pixel displacement in Y from current frame to previous frame

B: pixel displacement in X from current frame to next frame

A: pixel displacement in Y from current frame to next frame

as discussed here.

Updates after hours of debugging (sigh...) -- The above statements are NOT 100% accurate. The first two are accurate, whereas the bottom two should instead be

B: pixel displacement in X from next frame to current frame

A: pixel displacement in Y from next frame to current frame

Caveat -- the y-axis seems to be pointing upwards. I need to flip its sign to display correctly on my image.

I used this MATLAB package to read all four channels of the OpenEXR images.