Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv_contrib
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
opencv_contrib
Commits
d783cbef
Commit
d783cbef
authored
Sep 21, 2015
by
Alexander Alekhin
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #384 from paroj:markercoding
parents
dc4e52cd
35b935c9
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
30 additions
and
63 deletions
+30
-63
dictionary.cpp
modules/aruco/src/dictionary.cpp
+30
-63
No files found.
modules/aruco/src/dictionary.cpp
View file @
d783cbef
...
...
@@ -48,24 +48,6 @@ namespace aruco {
using
namespace
std
;
/**
* Hamming weight look up table from 0 to 255
*/
const
unsigned
char
hammingWeightLUT
[]
=
{
0
,
1
,
1
,
2
,
1
,
2
,
2
,
3
,
1
,
2
,
2
,
3
,
2
,
3
,
3
,
4
,
1
,
2
,
2
,
3
,
2
,
3
,
3
,
4
,
2
,
3
,
3
,
4
,
3
,
4
,
4
,
5
,
1
,
2
,
2
,
3
,
2
,
3
,
3
,
4
,
2
,
3
,
3
,
4
,
3
,
4
,
4
,
5
,
2
,
3
,
3
,
4
,
3
,
4
,
4
,
5
,
3
,
4
,
4
,
5
,
4
,
5
,
5
,
6
,
1
,
2
,
2
,
3
,
2
,
3
,
3
,
4
,
2
,
3
,
3
,
4
,
3
,
4
,
4
,
5
,
2
,
3
,
3
,
4
,
3
,
4
,
4
,
5
,
3
,
4
,
4
,
5
,
4
,
5
,
5
,
6
,
2
,
3
,
3
,
4
,
3
,
4
,
4
,
5
,
3
,
4
,
4
,
5
,
4
,
5
,
5
,
6
,
3
,
4
,
4
,
5
,
4
,
5
,
5
,
6
,
4
,
5
,
5
,
6
,
5
,
6
,
6
,
7
,
1
,
2
,
2
,
3
,
2
,
3
,
3
,
4
,
2
,
3
,
3
,
4
,
3
,
4
,
4
,
5
,
2
,
3
,
3
,
4
,
3
,
4
,
4
,
5
,
3
,
4
,
4
,
5
,
4
,
5
,
5
,
6
,
2
,
3
,
3
,
4
,
3
,
4
,
4
,
5
,
3
,
4
,
4
,
5
,
4
,
5
,
5
,
6
,
3
,
4
,
4
,
5
,
4
,
5
,
5
,
6
,
4
,
5
,
5
,
6
,
5
,
6
,
6
,
7
,
2
,
3
,
3
,
4
,
3
,
4
,
4
,
5
,
3
,
4
,
4
,
5
,
4
,
5
,
5
,
6
,
3
,
4
,
4
,
5
,
4
,
5
,
5
,
6
,
4
,
5
,
5
,
6
,
5
,
6
,
6
,
7
,
3
,
4
,
4
,
5
,
4
,
5
,
5
,
6
,
4
,
5
,
5
,
6
,
5
,
6
,
6
,
7
,
4
,
5
,
5
,
6
,
5
,
6
,
6
,
7
,
5
,
6
,
6
,
7
,
6
,
7
,
7
,
8
};
/**
*/
Dictionary
::
Dictionary
(
const
unsigned
char
*
bytes
,
int
_markerSize
,
int
dictsize
,
int
_maxcorr
)
{
...
...
@@ -75,14 +57,9 @@ Dictionary::Dictionary(const unsigned char *bytes, int _markerSize, int dictsize
if
((
markerSize
*
markerSize
)
%
8
!=
0
)
nbytes
++
;
// save bytes in internal format
// bytesList.
at<Vec4b>(i, j)[k
] is j-th byte of i-th marker, in its k-th rotation
// bytesList.
ptr(i)[k*nbytes + j
] is j-th byte of i-th marker, in its k-th rotation
bytesList
=
Mat
(
dictsize
,
nbytes
,
CV_8UC4
);
for
(
int
i
=
0
;
i
<
dictsize
;
i
++
)
{
for
(
int
j
=
0
;
j
<
nbytes
;
j
++
)
{
for
(
int
k
=
0
;
k
<
4
;
k
++
)
bytesList
.
at
<
Vec4b
>
(
i
,
j
)[
k
]
=
bytes
[
i
*
(
4
*
nbytes
)
+
k
*
nbytes
+
j
];
}
}
memcpy
(
bytesList
.
data
,
bytes
,
dictsize
*
nbytes
*
4
);
}
...
...
@@ -106,13 +83,10 @@ bool Dictionary::identify(const Mat &onlyBits, int &idx, int &rotation,
int
currentMinDistance
=
markerSize
*
markerSize
+
1
;
int
currentRotation
=
-
1
;
for
(
unsigned
int
r
=
0
;
r
<
4
;
r
++
)
{
int
currentHamming
=
0
;
// for each byte, calculate XOR result and then sum the Hamming weight from the LUT
for
(
unsigned
int
b
=
0
;
b
<
candidateBytes
.
total
();
b
++
)
{
unsigned
char
xorRes
=
bytesList
.
ptr
<
Vec4b
>
(
m
)[
b
][
r
]
^
candidateBytes
.
ptr
<
Vec4b
>
(
0
)[
b
][
0
];
currentHamming
+=
hammingWeightLUT
[
xorRes
];
}
int
currentHamming
=
hal
::
normHamming
(
bytesList
.
ptr
(
m
)
+
r
*
candidateBytes
.
cols
,
candidateBytes
.
ptr
(),
candidateBytes
.
cols
);
if
(
currentHamming
<
currentMinDistance
)
{
currentMinDistance
=
currentHamming
;
...
...
@@ -147,12 +121,10 @@ int Dictionary::getDistanceToId(InputArray bits, int id, bool allRotations) cons
Mat
candidateBytes
=
getByteListFromBits
(
bits
.
getMat
());
int
currentMinDistance
=
int
(
bits
.
total
()
*
bits
.
total
());
for
(
unsigned
int
r
=
0
;
r
<
nRotations
;
r
++
)
{
int
currentHamming
=
0
;
for
(
unsigned
int
b
=
0
;
b
<
candidateBytes
.
total
();
b
++
)
{
unsigned
char
xorRes
=
bytesList
.
ptr
<
Vec4b
>
(
id
)[
b
][
r
]
^
candidateBytes
.
ptr
<
Vec4b
>
(
0
)[
b
][
0
];
currentHamming
+=
hammingWeightLUT
[
xorRes
];
}
int
currentHamming
=
hal
::
normHamming
(
bytesList
.
ptr
(
id
)
+
r
*
candidateBytes
.
cols
,
candidateBytes
.
ptr
(),
candidateBytes
.
cols
);
if
(
currentHamming
<
currentMinDistance
)
{
currentMinDistance
=
currentHamming
;
...
...
@@ -202,26 +174,25 @@ Mat Dictionary::getByteListFromBits(const Mat &bits) {
Mat
candidateByteList
(
1
,
nbytes
,
CV_8UC4
,
Scalar
::
all
(
0
));
unsigned
char
currentBit
=
0
;
int
currentByte
=
0
;
// the 4 rotations
uchar
*
rot0
=
candidateByteList
.
ptr
();
uchar
*
rot1
=
candidateByteList
.
ptr
()
+
1
*
nbytes
;
uchar
*
rot2
=
candidateByteList
.
ptr
()
+
2
*
nbytes
;
uchar
*
rot3
=
candidateByteList
.
ptr
()
+
3
*
nbytes
;
for
(
int
row
=
0
;
row
<
bits
.
rows
;
row
++
)
{
for
(
int
col
=
0
;
col
<
bits
.
cols
;
col
++
)
{
// circular shift
candidateByteList
.
ptr
<
Vec4b
>
(
0
)[
currentByte
][
0
]
=
candidateByteList
.
ptr
<
Vec4b
>
(
0
)[
currentByte
][
0
]
<<
1
;
candidateByteList
.
ptr
<
Vec4b
>
(
0
)[
currentByte
][
1
]
=
candidateByteList
.
ptr
<
Vec4b
>
(
0
)[
currentByte
][
1
]
<<
1
;
candidateByteList
.
ptr
<
Vec4b
>
(
0
)[
currentByte
][
2
]
=
candidateByteList
.
ptr
<
Vec4b
>
(
0
)[
currentByte
][
2
]
<<
1
;
candidateByteList
.
ptr
<
Vec4b
>
(
0
)[
currentByte
][
3
]
=
candidateByteList
.
ptr
<
Vec4b
>
(
0
)[
currentByte
][
3
]
<<
1
;
// increment if bit is 1
if
(
bits
.
at
<
unsigned
char
>
(
row
,
col
))
candidateByteList
.
ptr
<
Vec4b
>
(
0
)[
currentByte
][
0
]
++
;
if
(
bits
.
at
<
unsigned
char
>
(
col
,
bits
.
cols
-
1
-
row
))
candidateByteList
.
ptr
<
Vec4b
>
(
0
)[
currentByte
][
1
]
++
;
if
(
bits
.
at
<
unsigned
char
>
(
bits
.
rows
-
1
-
row
,
bits
.
cols
-
1
-
col
))
candidateByteList
.
ptr
<
Vec4b
>
(
0
)[
currentByte
][
2
]
++
;
if
(
bits
.
at
<
unsigned
char
>
(
bits
.
rows
-
1
-
col
,
row
))
candidateByteList
.
ptr
<
Vec4b
>
(
0
)[
currentByte
][
3
]
++
;
rot0
[
currentByte
]
<<=
1
;
rot1
[
currentByte
]
<<=
1
;
rot2
[
currentByte
]
<<=
1
;
rot3
[
currentByte
]
<<=
1
;
// set bit
rot0
[
currentByte
]
|=
bits
.
at
<
uchar
>
(
row
,
col
);
rot1
[
currentByte
]
|=
bits
.
at
<
uchar
>
(
col
,
bits
.
cols
-
1
-
row
);
rot2
[
currentByte
]
|=
bits
.
at
<
uchar
>
(
bits
.
rows
-
1
-
row
,
bits
.
cols
-
1
-
col
);
rot3
[
currentByte
]
|=
bits
.
at
<
uchar
>
(
bits
.
rows
-
1
-
col
,
row
);
currentBit
++
;
if
(
currentBit
==
8
)
{
// next byte
...
...
@@ -247,7 +218,7 @@ Mat Dictionary::getBitsFromByteList(const Mat &byteList, int markerSize) {
unsigned
char
base2List
[]
=
{
128
,
64
,
32
,
16
,
8
,
4
,
2
,
1
};
int
currentByteIdx
=
0
;
// we only need the bytes in normal rotation
unsigned
char
currentByte
=
byteList
.
ptr
<
Vec4b
>
(
0
)[
0
]
[
0
];
unsigned
char
currentByte
=
byteList
.
ptr
()
[
0
];
int
currentBit
=
0
;
for
(
int
row
=
0
;
row
<
bits
.
rows
;
row
++
)
{
for
(
int
col
=
0
;
col
<
bits
.
cols
;
col
++
)
{
...
...
@@ -258,7 +229,7 @@ Mat Dictionary::getBitsFromByteList(const Mat &byteList, int markerSize) {
currentBit
++
;
if
(
currentBit
==
8
)
{
currentByteIdx
++
;
currentByte
=
byteList
.
ptr
<
Vec4b
>
(
0
)[
currentByteIdx
][
0
];
currentByte
=
byteList
.
ptr
()[
currentByteIdx
];
// if not enough bits for one more byte, we are in the end
// update bit position accordingly
if
(
8
*
(
currentByteIdx
+
1
)
>
(
int
)
bits
.
total
())
...
...
@@ -369,12 +340,8 @@ static Mat _generateRandomMarker(int markerSize) {
static
int
_getSelfDistance
(
const
Mat
&
marker
)
{
Mat
bytes
=
Dictionary
::
getByteListFromBits
(
marker
);
int
minHamming
=
(
int
)
marker
.
total
()
+
1
;
for
(
int
i
=
1
;
i
<
4
;
i
++
)
{
int
currentHamming
=
0
;
for
(
int
j
=
0
;
j
<
bytes
.
cols
;
j
++
)
{
unsigned
char
xorRes
=
bytes
.
ptr
<
Vec4b
>
()[
j
][
0
]
^
bytes
.
ptr
<
Vec4b
>
()[
j
][
i
];
currentHamming
+=
hammingWeightLUT
[
xorRes
];
}
for
(
int
r
=
1
;
r
<
4
;
r
++
)
{
int
currentHamming
=
hal
::
normHamming
(
bytes
.
ptr
(),
bytes
.
ptr
()
+
bytes
.
cols
*
r
,
bytes
.
cols
);
if
(
currentHamming
<
minHamming
)
minHamming
=
currentHamming
;
}
return
minHamming
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment