0

I'm dealing with a predictive block-matching motion estimation algorithm. This means, the values of motion vectors are found using the previously found values and I am stuck with a really trivial thing.

I'm dealing with images divided into blocks, so I should have a motion vector for each block. I created a 2xN matrix motion_vectors, where N is the number of all blocks (blocks_in_the_first_row*blocks_in_the_first_column). The first row is the x coordinate and second row the y coordinate of the motion vector.

I have 2 predictors to help to estimate the motion vector of the current block. If my current block is at position (i,j) then the positions of the predictors are (i, j-1) (the block "on top)" and (i-1, j) (the block on the left).

My problem is, that I can't figure out a way how to adress the predictor blocks (in for loops) in motion_vectors since the dimensions are different (one is a 2xN matrix, the other blocks_in_row x blocks_in_column). I also wouldn't like to change the dimensions of motion_vectors, since then I would need a two-"layer" array. One for the x coordinates and one for y, but that doesn't fit to the further design.

I hope I made myself understandable, if not, please let me know.

Thanks for any clues!

  • Each block in the prediction gets assigned the same motion vector. Therefore, if you found that an 8 x 8 block has a motion vector of... say... `(2,2)`, then **all pixels** in this block move by `(2,2)`. In addition, can you show us what you've tried? It'll help me get a solution more quickly as I can integrate it into your existing code, rather than having to write one from scratch and making assumptions that are (probably) not correct. – rayryeng Aug 31 '15 at 20:06

1 Answers1

0

If you're accessing an element of motion_vectors, you're getting data about a corresponding block. That means that there's a system of translating between an index 1 through N, where N is blocks_in_row*blocks_in_column, and a specific block. If index 1 is the top-left block, index 2 is the block to its right, and you increment as reading a book (left-to-right and wrap to the next row), then you would translate as follows:

row_of_block = floor((index_in_motion_vector-1)/number_of_columns) + 1  
col_of_block = mod((index_in_motion_vector-1), number_of_columns) + 1

(This is called row-major ordering.)

If instead index 1 is the top-left block and index 2 is the block below it, and you wrap to the top of the next column when done with one, then the conversion would be

row_of_block = mod((index_in_motion_vector-1), number_of_rows) + 1
col_of_block = floor((index_in_motion_vector-1)/number_of_rows) + 1

(This is called column-major ordering, and is what MATLAB uses by default.)

So, if you're iterating 1 to N, you can just use those conversions. If you'd like to iterate 1 through number_of_rows, and 1 through number_of_columns you would do the opposite.

If you're using the book-like indexing of blocks (row-major ordering), the conversion to index of the motion vector would be

col_in_motion_vector = (row_of_block-1)*number_of_columns + column_of_block

If you're using the second, top-to-bottom-and-wrap method of indexing blocks (column-major ordering), the conversion would instead be

col_in_motion_vector = (column_of_block-1)*number_of_rows + row_of_block
Clarissa G
  • 341
  • 1
  • 8
  • Thank you!! Yes, I want to increment as reading a book. Am I missing something or could I also simply use in the case of columns `col_of_block = index_in_motion_vector % number_of_columns` (in MATLAB syntax `col_of_block = mod(index_in_motion_vector, number_of_columns)`) or is the subtraction and addition necessary in some cases? – bald_cactus Sep 01 '15 at 15:12
  • Thanks for mentioning mod vs. %; you don't want comments in your code! The subtraction and addition is necessary because MATLAB starts at index 1, rather than 0, and that can cause some cases to fail. For example: if you had 10 columns, and the index in the motion vector was 10, then just using mod without the -1 and subsequent +1 would give you `10%10 = 0` as your answer for `col_of_block`, which isn't a valid index in MATLAB. Instead, doing `((10-1)%10 + 1)` gives you the correct result: `10`. – Clarissa G Sep 02 '15 at 03:08