-
-
Notifications
You must be signed in to change notification settings - Fork 56.5k
Redesign of the ElemType register for OpenCV v4 #12584
Description
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.