Skip to content

Redesign of the ElemType register for OpenCV v4 #12584

@cv3d

Description

@cv3d

The current magic register is designed as:

FEDCBA987654321
---------------
            ddd 	depth
   nnnnnnnnn    	channels - 1
  r             	reserved (unset)
 c              	continuous flag
s               	submatrix flag

However, it is slightly space inefficient, so allow me to redesign it as:

FEDCBA987654321
---------------
          ddddd 	depth
      nnnn      	channels base - 1
   mmm          	channels exponent
  r             	reserved (unset)
 c              	continuous flag
s               	submatrix flag

Depth

32 different depth types are allowed, and the order can be recovered again (given that user code will not be broken - e.g. by choosing new names and mapping old ones). Furthermore, we allow some discontinuity for future extensions

Channels

By utilizing cn = (nnnn + 1) << mmm, we can have the following channels:
1-16, 18, 20, 22, 24, 26, 28, 30, 32, 36, 40, 44, 48, 52, 56, 60, 64, 72, 80, 88, 96, 104, 112, 120, 128, 144, 160, 176, 192, 208, 224, 240, 256, 288, 320, 352, 384, 416, 448, 480, 512, 576, 640, 704, 768, 832, 896, 960, 1024, 1152, 1280, 1408, 1536, 1664, 1792, 1920, 2048
which I believe is a reasonable way of division

There are some channels that can be formed in multi-ways, which are:

  • 2 ways: 2, 6, 10, 14, 20, 28, 40, 56, 80, 112, 160, 224, 320, 448, 640, 768, 896, 1024
  • 3 ways: 4, 12, 24, 48, 96, 192, 384, 512
  • 4 ways: 8, 256
  • 5 ways: 16, 32, 64, 128
    These are in some sense a waste of valuable encoding space, but since we want to have the first 1-16 all available channels, it cannot be helped!

As for computing the channel base and exponent from the number of channels (e.g. user input), it can be done efficiently using:

mmm = (0x45263107U >> ((((cn & -cn) * 0x17) >> 2) & 0x1C)) & 7
nnnn = (cn >> mmm) - 1

where channel is deemed invalid if mmm >= 8 || nnnn >= 16.
If user choose unsupported number of channels, the next acceptable cn can be easily obtained by iteratively right-shifting the invalid nnnn and incrementing the corresponding mmm until a valid nnnn appears, then suggested to the user.

Update: using the following is guaranteed to allocate at least cn channels without any need for iterations:

mmm = floor(log2((cn - 1) >> 3))
nnnn = ((cn - 1) >> mmm)

Backwards compatibility

Guaranteed via fail-over! If parser fails to interpret a sequence, it should try the legacy format before reporting an error.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions