Search code examples
matlabimage-processingindexingmotion-detection

Indexing issue in MATLAB (image processing)


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!


Solution

  • 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