I added some filtering to macroblock vector output, including only those with individual SAD values less than half the overall SAD average for that frame. I then took the rig for a walk around a 3m square (measured fairly accurately), held approximately 1m above the ground. The graph goes anti-clockwise horizontally from 0,0. The height probably descended a little towards the end hence the overrun from >1000 to <0 vertically.

3m square walk

This is probably pretty perfect and more than good enough to work out the scale from macroblock vectors to meters:

1000 (vectors) = 3 (meters) @ 1m height or

meters = (**0.003** * height) vectors

Previously, I’d tried to calculate the macroblock vector to meter scale as the following where macroblock per frame are lengths in pixels:

meters = (2 * height * tan(lens angle / 2) / macroblocks per frame) vectors
meters = (2 * height * tan(48.4 / 2) / (400 / 16) vectors
meters = (**0.036** * height) vectors

Clearly my mathematical guess was wrong by a factor of roughly 12. The measurement errors for the test run were < 3% horizontally, and perhaps 5% vertically so they don’t explain the discrepancy.

I needed to investigate further how the vector values scale per frame size. So I upped the video frame from 400 x 400 pixels to 600 x 600 pixels:

(3m @ 600 pixels)²

The 1000 x 1000 vector square has now turned nicely into a 1500 x 1500 vector square corresponding to the 400 x 400 to 600 x 600 frame size change. So again,

1500 (vectors) = 3 (meters) @ 1m height or

meters = (**0.002** * height) vectors

So unsurprizingly, the macroblock vectors are inversely proportional to the frame size:

meters = (scale * height / frame width) * vectors
meters = (1.2 * height / frame width) * vectors

But what’s this 1.2 represent? I’ve done some thinking, but to no avail directly, but I think I’ve found away that I don’t need to know. That’ll be my next post.