Skip to content

Rotation invariant representation for 2-D shapes #27

@Spacha

Description

@Spacha

My attempt to represent the shapes in a rotation invariant way is inspired by Local Binary Patterns (LBP).

LBP is used in machine vision to extract descriptors from an image. It is quite simple in principle (if you are not familiar with it, maybe read the article first!).

How does it work?

Say we have a shape like the one in the image (green blocks):

image

1. Add zero padding for calculation

We then add 2 levels of zero padding around the shape, which looks like this:

image

2. Calculate the cell values using modified LBP

Then we can start calculating the feature matrix. We start from the second cell of the second row (cell (1, 1), see the figure below) so that there are not edges next to it. The cell value for cell (1, 1) is calculated based on its 8-neighboring values as well as its own value. Each cell value is a 9-bit integer (0-512).

Here the cell (1, 1) is highlighted in orange:

image

  1. Start from the top-left neighbor. If there is a block (=green), set the first bit (MSB) of the cell value to 1, otherwise 0.
  2. Then proceed to the top-mid neighbor. Again, if there is a block, set the second bit of the cell value to 1.
  3. Repeat for the top-right neighbor and set bit position 3 accordingly.
  4. Repeat for the mid-right neighbor and set bit position 4 accordingly.
  5. Repeat for the bottom-right neighbor and set bit position 5 accordingly.
  6. Repeat for the bottom-mid neighbor and set bit position 6 accordingly.
  7. Repeat for the bottom-left neighbor and set bit position 7 accordingly.
  8. Repeat for the mid-left neighbor and set bit position 8 accordingly.
  9. Repeat for the middle cell (the cell itself!) and set bit position 9 (LSB) accordingly.

Now we have a 9-bit cell value for the first cell: 00001_0000, which is 16 in decimal. We can then move to the next cell. This is repeated for all cells except cells that are on the edge (so skipping the first and last columns as well as the first and last rows).

Here are all the cell values for the example shape:

image

Then, the feature vector of this shape is:

[[ 16  24  28  12   4   0]
 [ 32  33  51  27  14   4]
 [ 64 192 496 425 263   2]
 [  0   0 112 201 390 256]
 [  0   0  96 129 258   0]
 [  0   0  64 128 256   0]]

3. Calculate the sum of the matrix values

Finally, we sum all the cell values in the feature matrix to get the fingerprint of that shape. This fingerprint is the same for all rotations of the same shape.

Comparing the variants

Here are all the variants of the example shape, along with their feature matrices and their sums (the fingerprints).

image

Matrix:
[[ 16  24  28  12   4   0]
 [ 32  33  51  27  14   4]
 [ 64 192 496 425 263   2]
 [  0   0 112 201 390 256]
 [  0   0  96 129 258   0]
 [  0   0  64 128 256   0]]

Sum: 3577

image

Matrix:
[[  0  16   8   4   0   0]
 [ 16  56  29  30  12   4]
 [ 48 105 167 291   3   2]
 [112 201 454 448 384 256]
 [ 96 129 258   0   0   0]
 [ 64 128 256   0   0   0]]

Sum: 3577

image

Matrix:
[[  0  16   8   4   0   0]
 [  0  48   9   6   0   0]
 [ 16 120 141 262   0   0]
 [ 32 113 155 286  12   4]
 [ 64 224 417 291   3   2]
 [  0  64 192 448 384 256]]

Sum: 3577

image

Matrix:
[[  0   0   0  16   8   4]
 [  0   0   0  48   9   6]
 [ 16  24  28 124 141 262]
 [ 32  33  51 107 135 258]
 [ 64 192 480 449 386 256]
 [  0   0  64 128 256   0]]

Sum: 3577

As you see, all variants have the same fingerprint 3577!

Final words

I have tested this with maybe tens of various 2-D shapes. So far so good. Check my Notebook for all the tests.

  • This may not work in 3D at all, but pretty interesting nevertheless.
  • One fear I have is that the fingerprint is not unique. There might be some other shapes that have the same fingerprint. I will check this later as well.
  • It is possible that this is computationally more complex than the already found solutions.
  • I was quite tired (and sick) when I did this so it may well be overly complicated and I am just missing the obvious.

I have not yet proven nor disproven that this will work. However, I am planning to do that later.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions