Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv
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
Commits
40f2c716
Commit
40f2c716
authored
Apr 23, 2012
by
Vadim Pisarevsky
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
added NORM_HAMMING* support to cv::norm (ticket #1840)
parent
8dae3431
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
225 additions
and
40 deletions
+225
-40
stat.cpp
modules/core/src/stat.cpp
+151
-38
test_arithm.cpp
modules/core/test/test_arithm.cpp
+8
-2
ts_func.cpp
modules/ts/src/ts_func.cpp
+66
-0
No files found.
modules/core/src/stat.cpp
View file @
40f2c716
...
...
@@ -965,6 +965,34 @@ static const uchar popCountTable4[] =
1
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
1
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
};
int
normHamming
(
const
uchar
*
a
,
int
n
)
{
int
i
=
0
,
result
=
0
;
#if CV_NEON
if
(
CPU_HAS_NEON_FEATURE
)
{
uint32x4_t
bits
=
vmovq_n_u32
(
0
);
for
(;
i
<=
n
-
16
;
i
+=
16
)
{
uint8x16_t
A_vec
=
vld1q_u8
(
a
+
i
);
uint8x16_t
bitsSet
=
vcntq_u8
(
A_vec
);
uint16x8_t
bitSet8
=
vpaddlq_u8
(
bitsSet
);
uint32x4_t
bitSet4
=
vpaddlq_u16
(
bitSet8
);
bits
=
vaddq_u32
(
bits
,
bitSet4
);
}
uint64x2_t
bitSet2
=
vpaddlq_u32
(
bits
);
result
=
vgetq_lane_s32
(
vreinterpretq_s32_u64
(
bitSet2
),
0
);
result
+=
vgetq_lane_s32
(
vreinterpretq_s32_u64
(
bitSet2
),
2
);
}
else
#endif
for
(
;
i
<=
n
-
4
;
i
+=
4
)
result
+=
popCountTable
[
a
[
i
]]
+
popCountTable
[
a
[
i
+
1
]]
+
popCountTable
[
a
[
i
+
2
]]
+
popCountTable
[
a
[
i
+
3
]];
for
(
;
i
<
n
;
i
++
)
result
+=
popCountTable
[
a
[
i
]];
return
result
;
}
int
normHamming
(
const
uchar
*
a
,
const
uchar
*
b
,
int
n
)
{
int
i
=
0
,
result
=
0
;
...
...
@@ -995,6 +1023,27 @@ int normHamming(const uchar* a, const uchar* b, int n)
return
result
;
}
int
normHamming
(
const
uchar
*
a
,
int
n
,
int
cellSize
)
{
if
(
cellSize
==
1
)
return
normHamming
(
a
,
n
);
const
uchar
*
tab
=
0
;
if
(
cellSize
==
2
)
tab
=
popCountTable2
;
else
if
(
cellSize
==
4
)
tab
=
popCountTable4
;
else
CV_Error
(
CV_StsBadSize
,
"bad cell size (not 1, 2 or 4) in normHamming"
);
int
i
=
0
,
result
=
0
;
#if CV_ENABLE_UNROLLED
for
(
;
i
<=
n
-
4
;
i
+=
4
)
result
+=
tab
[
a
[
i
]]
+
tab
[
a
[
i
+
1
]]
+
tab
[
a
[
i
+
2
]]
+
tab
[
a
[
i
+
3
]];
#endif
for
(
;
i
<
n
;
i
++
)
result
+=
tab
[
a
[
i
]];
return
result
;
}
int
normHamming
(
const
uchar
*
a
,
const
uchar
*
b
,
int
n
,
int
cellSize
)
{
if
(
cellSize
==
1
)
...
...
@@ -1221,38 +1270,74 @@ double cv::norm( InputArray _src, int normType, InputArray _mask )
int
depth
=
src
.
depth
(),
cn
=
src
.
channels
();
normType
&=
7
;
CV_Assert
(
normType
==
NORM_INF
||
normType
==
NORM_L1
||
normType
==
NORM_L2
);
CV_Assert
(
normType
==
NORM_INF
||
normType
==
NORM_L1
||
normType
==
NORM_L2
||
((
normType
==
NORM_HAMMING
||
normType
==
NORM_HAMMING2
)
&&
src
.
type
()
==
CV_8U
)
);
if
(
depth
==
CV_32F
&&
src
.
isContinuous
()
&&
mask
.
empty
()
)
if
(
src
.
isContinuous
()
&&
mask
.
empty
()
)
{
size_t
len
=
src
.
total
()
*
cn
;
if
(
len
==
(
size_t
)(
int
)
len
)
{
const
float
*
data
=
src
.
ptr
<
float
>
();
if
(
normType
==
NORM_L2
)
if
(
depth
==
CV_32F
)
{
double
result
=
0
;
GET_OPTIMIZED
(
normL2_32f
)(
data
,
0
,
&
result
,
(
int
)
len
,
1
);
return
std
::
sqrt
(
result
);
}
if
(
normType
==
NORM_L1
)
{
double
result
=
0
;
GET_OPTIMIZED
(
normL1_32f
)(
data
,
0
,
&
result
,
(
int
)
len
,
1
);
return
result
;
const
float
*
data
=
src
.
ptr
<
float
>
();
if
(
normType
==
NORM_L2
)
{
double
result
=
0
;
GET_OPTIMIZED
(
normL2_32f
)(
data
,
0
,
&
result
,
(
int
)
len
,
1
);
return
std
::
sqrt
(
result
);
}
if
(
normType
==
NORM_L1
)
{
double
result
=
0
;
GET_OPTIMIZED
(
normL1_32f
)(
data
,
0
,
&
result
,
(
int
)
len
,
1
);
return
result
;
}
if
(
normType
==
NORM_INF
)
{
float
result
=
0
;
GET_OPTIMIZED
(
normInf_32f
)(
data
,
0
,
&
result
,
(
int
)
len
,
1
);
return
result
;
}
}
if
(
depth
==
CV_8U
)
{
float
result
=
0
;
GET_OPTIMIZED
(
normInf_32f
)(
data
,
0
,
&
result
,
(
int
)
len
,
1
);
return
result
;
const
uchar
*
data
=
src
.
ptr
<
uchar
>
();
if
(
normType
==
NORM_HAMMING
)
return
normHamming
(
data
,
(
int
)
len
);
if
(
normType
==
NORM_HAMMING2
)
return
normHamming
(
data
,
(
int
)
len
,
2
);
}
}
}
CV_Assert
(
mask
.
empty
()
||
mask
.
type
()
==
CV_8U
);
if
(
normType
==
NORM_HAMMING
||
normType
==
NORM_HAMMING2
)
{
if
(
!
mask
.
empty
()
)
{
Mat
temp
;
bitwise_and
(
src
,
mask
,
temp
);
return
norm
(
temp
,
normType
);
}
int
cellSize
=
normType
==
NORM_HAMMING
?
1
:
2
;
const
Mat
*
arrays
[]
=
{
&
src
,
0
};
uchar
*
ptrs
[
1
];
NAryMatIterator
it
(
arrays
,
ptrs
);
int
total
=
(
int
)
it
.
size
;
int
result
=
0
;
for
(
size_t
i
=
0
;
i
<
it
.
nplanes
;
i
++
,
++
it
)
result
+=
normHamming
(
ptrs
[
0
],
total
,
cellSize
);
return
result
;
}
NormFunc
func
=
normTab
[
normType
>>
1
][
depth
];
CV_Assert
(
func
!=
0
);
...
...
@@ -1328,38 +1413,66 @@ double cv::norm( InputArray _src1, InputArray _src2, int normType, InputArray _m
CV_Assert
(
src1
.
size
==
src2
.
size
&&
src1
.
type
()
==
src2
.
type
()
);
normType
&=
7
;
CV_Assert
(
normType
==
NORM_INF
||
normType
==
NORM_L1
||
normType
==
NORM_L2
);
CV_Assert
(
normType
==
NORM_INF
||
normType
==
NORM_L1
||
normType
==
NORM_L2
||
((
normType
==
NORM_HAMMING
||
normType
==
NORM_HAMMING2
)
&&
src1
.
type
()
==
CV_8U
)
);
if
(
src1
.
depth
()
==
CV_32F
&&
src1
.
isContinuous
()
&&
src2
.
isContinuous
()
&&
mask
.
empty
()
)
if
(
src1
.
isContinuous
()
&&
src2
.
isContinuous
()
&&
mask
.
empty
()
)
{
size_t
len
=
src1
.
total
()
*
src1
.
channels
();
if
(
len
==
(
size_t
)(
int
)
len
)
{
const
float
*
data1
=
src1
.
ptr
<
float
>
();
const
float
*
data2
=
src2
.
ptr
<
float
>
();
if
(
normType
==
NORM_L2
)
{
double
result
=
0
;
GET_OPTIMIZED
(
normDiffL2_32f
)(
data1
,
data2
,
0
,
&
result
,
(
int
)
len
,
1
);
return
std
::
sqrt
(
result
);
}
if
(
normType
==
NORM_L1
)
{
double
result
=
0
;
GET_OPTIMIZED
(
normDiffL1_32f
)(
data1
,
data2
,
0
,
&
result
,
(
int
)
len
,
1
);
return
result
;
}
if
(
src1
.
depth
()
==
CV_32F
)
{
float
result
=
0
;
GET_OPTIMIZED
(
normDiffInf_32f
)(
data1
,
data2
,
0
,
&
result
,
(
int
)
len
,
1
);
return
result
;
const
float
*
data1
=
src1
.
ptr
<
float
>
();
const
float
*
data2
=
src2
.
ptr
<
float
>
();
if
(
normType
==
NORM_L2
)
{
double
result
=
0
;
GET_OPTIMIZED
(
normDiffL2_32f
)(
data1
,
data2
,
0
,
&
result
,
(
int
)
len
,
1
);
return
std
::
sqrt
(
result
);
}
if
(
normType
==
NORM_L1
)
{
double
result
=
0
;
GET_OPTIMIZED
(
normDiffL1_32f
)(
data1
,
data2
,
0
,
&
result
,
(
int
)
len
,
1
);
return
result
;
}
if
(
normType
==
NORM_INF
)
{
float
result
=
0
;
GET_OPTIMIZED
(
normDiffInf_32f
)(
data1
,
data2
,
0
,
&
result
,
(
int
)
len
,
1
);
return
result
;
}
}
}
}
CV_Assert
(
mask
.
empty
()
||
mask
.
type
()
==
CV_8U
);
if
(
normType
==
NORM_HAMMING
||
normType
==
NORM_HAMMING2
)
{
if
(
!
mask
.
empty
()
)
{
Mat
temp
;
bitwise_xor
(
src1
,
src2
,
temp
);
bitwise_and
(
temp
,
mask
,
temp
);
return
norm
(
temp
,
normType
);
}
int
cellSize
=
normType
==
NORM_HAMMING
?
1
:
2
;
const
Mat
*
arrays
[]
=
{
&
src1
,
&
src2
,
0
};
uchar
*
ptrs
[
2
];
NAryMatIterator
it
(
arrays
,
ptrs
);
int
total
=
(
int
)
it
.
size
;
int
result
=
0
;
for
(
size_t
i
=
0
;
i
<
it
.
nplanes
;
i
++
,
++
it
)
result
+=
normHamming
(
ptrs
[
0
],
ptrs
[
1
],
total
,
cellSize
);
return
result
;
}
NormDiffFunc
func
=
normDiffTab
[
normType
>>
1
][
depth
];
CV_Assert
(
func
!=
0
);
...
...
modules/core/test/test_arithm.cpp
View file @
40f2c716
...
...
@@ -1226,7 +1226,14 @@ struct NormOp : public BaseElemWiseOp
};
int
getRandomType
(
RNG
&
rng
)
{
return
cvtest
::
randomType
(
rng
,
DEPTH_MASK_ALL_BUT_8S
,
1
,
4
);
int
type
=
cvtest
::
randomType
(
rng
,
DEPTH_MASK_ALL_BUT_8S
,
1
,
4
);
normType
=
1
<<
rng
.
uniform
(
0
,
3
);
if
(
CV_MAT_DEPTH
(
type
)
==
CV_8U
&&
(
rng
.
next
()
&
8
)
!=
0
)
{
normType
=
cv
::
NORM_HAMMING
+
rng
.
uniform
(
0
,
2
);
type
=
CV_MAT_DEPTH
(
type
);
}
return
type
;
}
void
op
(
const
vector
<
Mat
>&
src
,
Mat
&
dst
,
const
Mat
&
mask
)
{
...
...
@@ -1242,7 +1249,6 @@ struct NormOp : public BaseElemWiseOp
}
void
generateScalars
(
int
,
RNG
&
rng
)
{
normType
=
1
<<
rng
.
uniform
(
0
,
3
);
}
double
getMaxErr
(
int
)
{
...
...
modules/ts/src/ts_func.cpp
View file @
40f2c716
...
...
@@ -1100,6 +1100,23 @@ void minMaxLoc(const Mat& src, double* _minval, double* _maxval,
}
static
int
normHamming
(
const
uchar
*
src
,
size_t
total
,
int
cellSize
)
{
int
result
=
0
;
int
mask
=
cellSize
==
1
?
1
:
cellSize
==
2
?
3
:
cellSize
==
4
?
15
:
-
1
;
CV_Assert
(
mask
>=
0
);
for
(
size_t
i
=
0
;
i
<
total
;
i
++
)
{
unsigned
a
=
src
[
i
];
for
(
;
a
!=
0
;
a
>>=
cellSize
)
result
+=
(
a
&
mask
)
!=
0
;
}
return
result
;
}
template
<
typename
_Tp
>
static
double
norm_
(
const
_Tp
*
src
,
size_t
total
,
int
cn
,
int
normType
,
double
startval
,
const
uchar
*
mask
)
{
...
...
@@ -1216,8 +1233,34 @@ norm_(const _Tp* src1, const _Tp* src2, size_t total, int cn, int normType, doub
double
norm
(
const
Mat
&
src
,
int
normType
,
const
Mat
&
mask
)
{
if
(
normType
==
NORM_HAMMING
||
normType
==
NORM_HAMMING2
)
{
if
(
!
mask
.
empty
()
)
{
Mat
temp
;
bitwise_and
(
src
,
mask
,
temp
);
return
norm
(
temp
,
normType
,
Mat
());
}
CV_Assert
(
src
.
depth
()
==
CV_8U
);
const
Mat
*
arrays
[]
=
{
&
src
,
0
};
Mat
planes
[
1
];
NAryMatIterator
it
(
arrays
,
planes
);
size_t
total
=
planes
[
0
].
total
();
size_t
i
,
nplanes
=
it
.
nplanes
;
double
result
=
0
;
int
cellSize
=
normType
==
NORM_HAMMING
?
1
:
2
;
for
(
i
=
0
;
i
<
nplanes
;
i
++
,
++
it
)
result
+=
normHamming
(
planes
[
0
].
data
,
total
,
cellSize
);
return
result
;
}
CV_Assert
(
mask
.
empty
()
||
(
src
.
size
==
mask
.
size
&&
mask
.
type
()
==
CV_8U
)
);
CV_Assert
(
normType
==
NORM_INF
||
normType
==
NORM_L1
||
normType
==
NORM_L2
);
const
Mat
*
arrays
[]
=
{
&
src
,
&
mask
,
0
};
Mat
planes
[
2
];
...
...
@@ -1267,6 +1310,29 @@ double norm(const Mat& src, int normType, const Mat& mask)
double
norm
(
const
Mat
&
src1
,
const
Mat
&
src2
,
int
normType
,
const
Mat
&
mask
)
{
if
(
normType
==
NORM_HAMMING
||
normType
==
NORM_HAMMING2
)
{
Mat
temp
;
bitwise_xor
(
src1
,
src2
,
temp
);
if
(
!
mask
.
empty
()
)
bitwise_and
(
temp
,
mask
,
temp
);
CV_Assert
(
temp
.
depth
()
==
CV_8U
);
const
Mat
*
arrays
[]
=
{
&
temp
,
0
};
Mat
planes
[
1
];
NAryMatIterator
it
(
arrays
,
planes
);
size_t
total
=
planes
[
0
].
total
();
size_t
i
,
nplanes
=
it
.
nplanes
;
double
result
=
0
;
int
cellSize
=
normType
==
NORM_HAMMING
?
1
:
2
;
for
(
i
=
0
;
i
<
nplanes
;
i
++
,
++
it
)
result
+=
normHamming
(
planes
[
0
].
data
,
total
,
cellSize
);
return
result
;
}
CV_Assert
(
src1
.
type
()
==
src2
.
type
()
&&
src1
.
size
==
src2
.
size
);
CV_Assert
(
mask
.
empty
()
||
(
src1
.
size
==
mask
.
size
&&
mask
.
type
()
==
CV_8U
)
);
CV_Assert
(
normType
==
NORM_INF
||
normType
==
NORM_L1
||
normType
==
NORM_L2
);
...
...
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