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
7d94236c
Commit
7d94236c
authored
Oct 06, 2012
by
Daniil-Osokin
Committed by
Daniil Osokin
Dec 17, 2012
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
TBB version of calcHist
parent
09be997e
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
579 additions
and
1 deletion
+579
-1
histogram.cpp
modules/imgproc/src/histogram.cpp
+579
-1
No files found.
modules/imgproc/src/histogram.cpp
View file @
7d94236c
...
...
@@ -165,11 +165,13 @@ static void histPrepareImages( const Mat* images, int nimages, const int* channe
deltas
[
dims
*
2
+
1
]
=
(
int
)(
mask
.
step
/
mask
.
elemSize1
());
}
#ifndef HAVE_TBB
if
(
isContinuous
)
{
imsize
.
width
*=
imsize
.
height
;
imsize
.
height
=
1
;
}
#endif
if
(
!
ranges
)
{
...
...
@@ -207,6 +209,538 @@ static void histPrepareImages( const Mat* images, int nimages, const int* channe
////////////////////////////////// C A L C U L A T E H I S T O G R A M ////////////////////////////////////
#ifdef HAVE_TBB
enum
{
one
=
1
,
two
,
three
};
// array elements number
template
<
typename
T
>
class
calcHist1D_Invoker
{
public
:
calcHist1D_Invoker
(
const
vector
<
uchar
*>&
_ptrs
,
const
vector
<
int
>&
_deltas
,
Mat
&
hist
,
const
double
*
_uniranges
,
int
sz
,
int
dims
,
Size
&
imageSize
)
:
mask_
(
_ptrs
[
dims
]),
mstep_
(
_deltas
[
dims
*
2
+
1
]),
imageWidth_
(
imageSize
.
width
),
histogramSize_
(
hist
.
size
()),
histogramType_
(
hist
.
type
()),
globalHistogram_
((
tbb
::
atomic
<
int
>*
)
hist
.
data
)
{
p_
[
0
]
=
((
T
**
)
&
_ptrs
[
0
])[
0
];
step_
[
0
]
=
(
&
_deltas
[
0
])[
1
];
d_
[
0
]
=
(
&
_deltas
[
0
])[
0
];
a_
[
0
]
=
(
&
_uniranges
[
0
])[
0
];
b_
[
0
]
=
(
&
_uniranges
[
0
])[
1
];
size_
[
0
]
=
sz
;
}
void
operator
()(
const
BlockedRange
&
range
)
const
{
T
*
p0
=
p_
[
0
]
+
range
.
begin
()
*
(
step_
[
0
]
+
imageWidth_
*
d_
[
0
]);
uchar
*
mask
=
mask_
+
range
.
begin
()
*
mstep_
;
for
(
int
row
=
range
.
begin
();
row
<
range
.
end
();
row
++
,
p0
+=
step_
[
0
]
)
{
if
(
!
mask_
)
{
for
(
int
x
=
0
;
x
<
imageWidth_
;
x
++
,
p0
+=
d_
[
0
]
)
{
int
idx
=
cvFloor
(
*
p0
*
a_
[
0
]
+
b_
[
0
]);
if
(
(
unsigned
)
idx
<
(
unsigned
)
size_
[
0
]
)
{
globalHistogram_
[
idx
].
fetch_and_add
(
1
);
}
}
}
else
{
for
(
int
x
=
0
;
x
<
imageWidth_
;
x
++
,
p0
+=
d_
[
0
]
)
{
if
(
mask
[
x
]
)
{
int
idx
=
cvFloor
(
*
p0
*
a_
[
0
]
+
b_
[
0
]);
if
(
(
unsigned
)
idx
<
(
unsigned
)
size_
[
0
]
)
{
globalHistogram_
[
idx
].
fetch_and_add
(
1
);
}
}
}
mask
+=
mstep_
;
}
}
}
private
:
T
*
p_
[
one
];
uchar
*
mask_
;
int
step_
[
one
];
int
d_
[
one
];
int
mstep_
;
double
a_
[
one
];
double
b_
[
one
];
int
size_
[
one
];
int
imageWidth_
;
Size
histogramSize_
;
int
histogramType_
;
tbb
::
atomic
<
int
>*
globalHistogram_
;
};
template
<
typename
T
>
class
calcHist2D_Invoker
{
public
:
calcHist2D_Invoker
(
const
vector
<
uchar
*>&
_ptrs
,
const
vector
<
int
>&
_deltas
,
Mat
&
hist
,
const
double
*
_uniranges
,
const
int
*
size
,
int
dims
,
Size
&
imageSize
,
size_t
*
hstep
)
:
mask_
(
_ptrs
[
dims
]),
mstep_
(
_deltas
[
dims
*
2
+
1
]),
imageWidth_
(
imageSize
.
width
),
histogramSize_
(
hist
.
size
()),
histogramType_
(
hist
.
type
()),
globalHistogram_
(
hist
.
data
)
{
p_
[
0
]
=
((
T
**
)
&
_ptrs
[
0
])[
0
];
p_
[
1
]
=
((
T
**
)
&
_ptrs
[
0
])[
1
];
step_
[
0
]
=
(
&
_deltas
[
0
])[
1
];
step_
[
1
]
=
(
&
_deltas
[
0
])[
3
];
d_
[
0
]
=
(
&
_deltas
[
0
])[
0
];
d_
[
1
]
=
(
&
_deltas
[
0
])[
2
];
a_
[
0
]
=
(
&
_uniranges
[
0
])[
0
];
a_
[
1
]
=
(
&
_uniranges
[
0
])[
2
];
b_
[
0
]
=
(
&
_uniranges
[
0
])[
1
];
b_
[
1
]
=
(
&
_uniranges
[
0
])[
3
];
size_
[
0
]
=
size
[
0
];
size_
[
1
]
=
size
[
1
];
hstep_
[
0
]
=
hstep
[
0
];
}
void
operator
()(
const
BlockedRange
&
range
)
const
{
T
*
p0
=
p_
[
0
]
+
range
.
begin
()
*
(
step_
[
0
]
+
imageWidth_
*
d_
[
0
]);
T
*
p1
=
p_
[
1
]
+
range
.
begin
()
*
(
step_
[
1
]
+
imageWidth_
*
d_
[
1
]);
uchar
*
mask
=
mask_
+
range
.
begin
()
*
mstep_
;
for
(
int
row
=
range
.
begin
();
row
<
range
.
end
();
row
++
,
p0
+=
step_
[
0
],
p1
+=
step_
[
1
]
)
{
if
(
!
mask_
)
{
for
(
int
x
=
0
;
x
<
imageWidth_
;
x
++
,
p0
+=
d_
[
0
],
p1
+=
d_
[
1
]
)
{
int
idx0
=
cvFloor
(
*
p0
*
a_
[
0
]
+
b_
[
0
]);
int
idx1
=
cvFloor
(
*
p1
*
a_
[
1
]
+
b_
[
1
]);
if
(
(
unsigned
)
idx0
<
(
unsigned
)
size_
[
0
]
&&
(
unsigned
)
idx1
<
(
unsigned
)
size_
[
1
]
)
(
(
tbb
::
atomic
<
int
>*
)(
globalHistogram_
+
hstep_
[
0
]
*
idx0
)
)[
idx1
].
fetch_and_add
(
1
);
}
}
else
{
for
(
int
x
=
0
;
x
<
imageWidth_
;
x
++
,
p0
+=
d_
[
0
],
p1
+=
d_
[
1
]
)
{
if
(
mask
[
x
]
)
{
int
idx0
=
cvFloor
(
*
p0
*
a_
[
0
]
+
b_
[
0
]);
int
idx1
=
cvFloor
(
*
p1
*
a_
[
1
]
+
b_
[
1
]);
if
(
(
unsigned
)
idx0
<
(
unsigned
)
size_
[
0
]
&&
(
unsigned
)
idx1
<
(
unsigned
)
size_
[
1
]
)
((
tbb
::
atomic
<
int
>*
)(
globalHistogram_
+
hstep_
[
0
]
*
idx0
))[
idx1
].
fetch_and_add
(
1
);
}
}
mask
+=
mstep_
;
}
}
}
private
:
T
*
p_
[
two
];
uchar
*
mask_
;
int
step_
[
two
];
int
d_
[
two
];
int
mstep_
;
double
a_
[
two
];
double
b_
[
two
];
int
size_
[
two
];
const
int
imageWidth_
;
size_t
hstep_
[
one
];
Size
histogramSize_
;
int
histogramType_
;
uchar
*
globalHistogram_
;
};
template
<
typename
T
>
class
calcHist3D_Invoker
{
public
:
calcHist3D_Invoker
(
const
vector
<
uchar
*>&
_ptrs
,
const
vector
<
int
>&
_deltas
,
Size
imsize
,
Mat
&
hist
,
const
double
*
uniranges
,
int
_dims
,
size_t
*
hstep
,
int
*
size
)
:
mask_
(
_ptrs
[
_dims
]),
mstep_
(
_deltas
[
_dims
*
2
+
1
]),
imageWidth_
(
imsize
.
width
),
globalHistogram_
(
hist
.
data
)
{
p_
[
0
]
=
((
T
**
)
&
_ptrs
[
0
])[
0
];
p_
[
1
]
=
((
T
**
)
&
_ptrs
[
0
])[
1
];
p_
[
2
]
=
((
T
**
)
&
_ptrs
[
0
])[
2
];
step_
[
0
]
=
(
&
_deltas
[
0
])[
1
];
step_
[
1
]
=
(
&
_deltas
[
0
])[
3
];
step_
[
2
]
=
(
&
_deltas
[
0
])[
5
];
d_
[
0
]
=
(
&
_deltas
[
0
])[
0
];
d_
[
1
]
=
(
&
_deltas
[
0
])[
2
];
d_
[
2
]
=
(
&
_deltas
[
0
])[
4
];
a_
[
0
]
=
uniranges
[
0
];
a_
[
1
]
=
uniranges
[
2
];
a_
[
2
]
=
uniranges
[
4
];
b_
[
0
]
=
uniranges
[
1
];
b_
[
1
]
=
uniranges
[
3
];
b_
[
2
]
=
uniranges
[
5
];
size_
[
0
]
=
size
[
0
];
size_
[
1
]
=
size
[
1
];
size_
[
2
]
=
size
[
2
];
hstep_
[
0
]
=
hstep
[
0
];
hstep_
[
1
]
=
hstep
[
1
];
}
void
operator
()(
const
BlockedRange
&
range
)
const
{
T
*
p0
=
p_
[
0
]
+
range
.
begin
()
*
(
imageWidth_
*
d_
[
0
]
+
step_
[
0
]);
T
*
p1
=
p_
[
1
]
+
range
.
begin
()
*
(
imageWidth_
*
d_
[
1
]
+
step_
[
1
]);
T
*
p2
=
p_
[
2
]
+
range
.
begin
()
*
(
imageWidth_
*
d_
[
2
]
+
step_
[
2
]);
uchar
*
mask
=
mask_
+
range
.
begin
()
*
mstep_
;
for
(
int
i
=
range
.
begin
();
i
<
range
.
end
();
i
++
,
p0
+=
step_
[
0
],
p1
+=
step_
[
1
],
p2
+=
step_
[
2
]
)
{
if
(
!
mask_
)
{
for
(
int
x
=
0
;
x
<
imageWidth_
;
x
++
,
p0
+=
d_
[
0
],
p1
+=
d_
[
1
],
p2
+=
d_
[
2
]
)
{
int
idx0
=
cvFloor
(
*
p0
*
a_
[
0
]
+
b_
[
0
]);
int
idx1
=
cvFloor
(
*
p1
*
a_
[
1
]
+
b_
[
1
]);
int
idx2
=
cvFloor
(
*
p2
*
a_
[
2
]
+
b_
[
2
]);
if
(
(
unsigned
)
idx0
<
(
unsigned
)
size_
[
0
]
&&
(
unsigned
)
idx1
<
(
unsigned
)
size_
[
1
]
&&
(
unsigned
)
idx2
<
(
unsigned
)
size_
[
2
]
)
{
(
(
tbb
::
atomic
<
int
>*
)(
globalHistogram_
+
hstep_
[
0
]
*
idx0
+
hstep_
[
1
]
*
idx1
)
)[
idx2
].
fetch_and_add
(
1
);
}
}
}
else
{
for
(
int
x
=
0
;
x
<
imageWidth_
;
x
++
,
p0
+=
d_
[
0
],
p1
+=
d_
[
1
],
p2
+=
d_
[
2
]
)
{
if
(
mask
[
x
]
)
{
int
idx0
=
cvFloor
(
*
p0
*
a_
[
0
]
+
b_
[
0
]);
int
idx1
=
cvFloor
(
*
p1
*
a_
[
1
]
+
b_
[
1
]);
int
idx2
=
cvFloor
(
*
p2
*
a_
[
2
]
+
b_
[
2
]);
if
(
(
unsigned
)
idx0
<
(
unsigned
)
size_
[
0
]
&&
(
unsigned
)
idx1
<
(
unsigned
)
size_
[
1
]
&&
(
unsigned
)
idx2
<
(
unsigned
)
size_
[
2
]
)
{
(
(
tbb
::
atomic
<
int
>*
)(
globalHistogram_
+
hstep_
[
0
]
*
idx0
+
hstep_
[
1
]
*
idx1
)
)[
idx2
].
fetch_and_add
(
1
);
}
}
}
mask
+=
mstep_
;
}
}
}
static
bool
isFit
(
const
Mat
&
histogram
,
const
Size
imageSize
)
{
return
(
imageSize
.
width
*
imageSize
.
height
>=
320
*
240
&&
histogram
.
total
()
>=
8
*
8
*
8
);
}
private
:
T
*
p_
[
three
];
uchar
*
mask_
;
int
step_
[
three
];
int
d_
[
three
];
const
int
mstep_
;
double
a_
[
three
];
double
b_
[
three
];
int
size_
[
three
];
int
imageWidth_
;
size_t
hstep_
[
two
];
uchar
*
globalHistogram_
;
};
class
CalcHist1D_8uInvoker
{
public
:
CalcHist1D_8uInvoker
(
const
vector
<
uchar
*>&
ptrs
,
const
vector
<
int
>&
deltas
,
Size
imsize
,
Mat
&
hist
,
int
dims
,
const
vector
<
size_t
>&
tab
,
tbb
::
mutex
*
lock
)
:
mask_
(
ptrs
[
dims
]),
mstep_
(
deltas
[
dims
*
2
+
1
]),
imageWidth_
(
imsize
.
width
),
imageSize_
(
imsize
),
histSize_
(
hist
.
size
()),
histType_
(
hist
.
type
()),
tab_
((
size_t
*
)
&
tab
[
0
]),
histogramWriteLock_
(
lock
),
globalHistogram_
(
hist
.
data
)
{
p_
[
0
]
=
(
&
ptrs
[
0
])[
0
];
step_
[
0
]
=
(
&
deltas
[
0
])[
1
];
d_
[
0
]
=
(
&
deltas
[
0
])[
0
];
}
void
operator
()(
const
BlockedRange
&
range
)
const
{
int
localHistogram
[
256
]
=
{
0
,
};
uchar
*
mask
=
mask_
;
uchar
*
p0
=
p_
[
0
];
int
x
;
tbb
::
mutex
::
scoped_lock
lock
;
if
(
!
mask_
)
{
int
n
=
(
imageWidth_
-
4
)
/
4
+
1
;
int
tail
=
imageWidth_
-
n
*
4
;
int
xN
=
4
*
n
;
p0
+=
(
xN
*
d_
[
0
]
+
tail
*
d_
[
0
]
+
step_
[
0
])
*
range
.
begin
();
}
else
{
p0
+=
(
imageWidth_
*
d_
[
0
]
+
step_
[
0
])
*
range
.
begin
();
mask
+=
mstep_
*
range
.
begin
();
}
for
(
int
i
=
range
.
begin
();
i
<
range
.
end
();
i
++
,
p0
+=
step_
[
0
]
)
{
if
(
!
mask_
)
{
if
(
d_
[
0
]
==
1
)
{
for
(
x
=
0
;
x
<=
imageWidth_
-
4
;
x
+=
4
)
{
int
t0
=
p0
[
x
],
t1
=
p0
[
x
+
1
];
localHistogram
[
t0
]
++
;
localHistogram
[
t1
]
++
;
t0
=
p0
[
x
+
2
];
t1
=
p0
[
x
+
3
];
localHistogram
[
t0
]
++
;
localHistogram
[
t1
]
++
;
}
p0
+=
x
;
}
else
{
for
(
x
=
0
;
x
<=
imageWidth_
-
4
;
x
+=
4
)
{
int
t0
=
p0
[
0
],
t1
=
p0
[
d_
[
0
]];
localHistogram
[
t0
]
++
;
localHistogram
[
t1
]
++
;
p0
+=
d_
[
0
]
*
2
;
t0
=
p0
[
0
];
t1
=
p0
[
d_
[
0
]];
localHistogram
[
t0
]
++
;
localHistogram
[
t1
]
++
;
p0
+=
d_
[
0
]
*
2
;
}
}
for
(
;
x
<
imageWidth_
;
x
++
,
p0
+=
d_
[
0
]
)
{
localHistogram
[
*
p0
]
++
;
}
}
else
{
for
(
x
=
0
;
x
<
imageWidth_
;
x
++
,
p0
+=
d_
[
0
]
)
{
if
(
mask
[
x
]
)
{
localHistogram
[
*
p0
]
++
;
}
}
mask
+=
mstep_
;
}
}
lock
.
acquire
(
*
histogramWriteLock_
);
for
(
int
i
=
0
;
i
<
256
;
i
++
)
{
size_t
hidx
=
tab_
[
i
];
if
(
hidx
<
OUT_OF_RANGE
)
{
*
(
int
*
)((
globalHistogram_
+
hidx
))
+=
localHistogram
[
i
];
}
}
lock
.
release
();
}
static
bool
isFit
(
const
Mat
&
histogram
,
const
Size
imageSize
)
{
return
(
histogram
.
total
()
>=
8
&&
imageSize
.
width
*
imageSize
.
height
>=
160
*
120
);
}
private
:
uchar
*
p_
[
one
];
uchar
*
mask_
;
int
mstep_
;
int
step_
[
one
];
int
d_
[
one
];
int
imageWidth_
;
Size
imageSize_
;
Size
histSize_
;
int
histType_
;
size_t
*
tab_
;
tbb
::
mutex
*
histogramWriteLock_
;
uchar
*
globalHistogram_
;
};
class
CalcHist2D_8uInvoker
{
public
:
CalcHist2D_8uInvoker
(
const
vector
<
uchar
*>&
_ptrs
,
const
vector
<
int
>&
_deltas
,
Size
imsize
,
Mat
&
hist
,
int
dims
,
const
vector
<
size_t
>&
_tab
,
tbb
::
mutex
*
lock
)
:
mask_
(
_ptrs
[
dims
]),
mstep_
(
_deltas
[
dims
*
2
+
1
]),
imageWidth_
(
imsize
.
width
),
histSize_
(
hist
.
size
()),
histType_
(
hist
.
type
()),
tab_
((
size_t
*
)
&
_tab
[
0
]),
histogramWriteLock_
(
lock
),
globalHistogram_
(
hist
.
data
)
{
p_
[
0
]
=
(
uchar
*
)(
&
_ptrs
[
0
])[
0
];
p_
[
1
]
=
(
uchar
*
)(
&
_ptrs
[
0
])[
1
];
step_
[
0
]
=
(
&
_deltas
[
0
])[
1
];
step_
[
1
]
=
(
&
_deltas
[
0
])[
3
];
d_
[
0
]
=
(
&
_deltas
[
0
])[
0
];
d_
[
1
]
=
(
&
_deltas
[
0
])[
2
];
}
void
operator
()(
const
BlockedRange
&
range
)
const
{
uchar
*
p0
=
p_
[
0
]
+
range
.
begin
()
*
(
step_
[
0
]
+
imageWidth_
*
d_
[
0
]);
uchar
*
p1
=
p_
[
1
]
+
range
.
begin
()
*
(
step_
[
1
]
+
imageWidth_
*
d_
[
1
]);
uchar
*
mask
=
mask_
+
range
.
begin
()
*
mstep_
;
Mat
localHist
=
Mat
::
zeros
(
histSize_
,
histType_
);
uchar
*
localHistData
=
localHist
.
data
;
tbb
::
mutex
::
scoped_lock
lock
;
for
(
int
i
=
range
.
begin
();
i
<
range
.
end
();
i
++
,
p0
+=
step_
[
0
],
p1
+=
step_
[
1
])
{
if
(
!
mask_
)
{
for
(
int
x
=
0
;
x
<
imageWidth_
;
x
++
,
p0
+=
d_
[
0
],
p1
+=
d_
[
1
]
)
{
size_t
idx
=
tab_
[
*
p0
]
+
tab_
[
*
p1
+
256
];
if
(
idx
<
OUT_OF_RANGE
)
{
++*
(
int
*
)(
localHistData
+
idx
);
}
}
}
else
{
for
(
int
x
=
0
;
x
<
imageWidth_
;
x
++
,
p0
+=
d_
[
0
],
p1
+=
d_
[
1
]
)
{
size_t
idx
;
if
(
mask
[
x
]
&&
(
idx
=
tab_
[
*
p0
]
+
tab_
[
*
p1
+
256
])
<
OUT_OF_RANGE
)
{
++*
(
int
*
)(
localHistData
+
idx
);
}
}
mask
+=
mstep_
;
}
}
lock
.
acquire
(
*
histogramWriteLock_
);
for
(
int
i
=
0
;
i
<
histSize_
.
width
*
histSize_
.
height
;
i
++
)
{
((
int
*
)
globalHistogram_
)[
i
]
+=
((
int
*
)
localHistData
)[
i
];
}
lock
.
release
();
}
static
bool
isFit
(
const
Mat
&
histogram
,
const
Size
imageSize
)
{
return
(
(
histogram
.
total
()
>
4
*
4
&&
histogram
.
total
()
<=
116
*
116
&&
imageSize
.
width
*
imageSize
.
height
>=
320
*
240
)
||
(
histogram
.
total
()
>
116
*
116
&&
imageSize
.
width
*
imageSize
.
height
>=
1280
*
720
)
);
}
private
:
uchar
*
p_
[
two
];
uchar
*
mask_
;
int
step_
[
two
];
int
d_
[
two
];
int
mstep_
;
int
imageWidth_
;
Size
histSize_
;
int
histType_
;
size_t
*
tab_
;
tbb
::
mutex
*
histogramWriteLock_
;
uchar
*
globalHistogram_
;
};
class
CalcHist3D_8uInvoker
{
public
:
CalcHist3D_8uInvoker
(
const
vector
<
uchar
*>&
_ptrs
,
const
vector
<
int
>&
_deltas
,
Size
imsize
,
Mat
&
hist
,
int
dims
,
const
vector
<
size_t
>&
tab
)
:
mask_
(
_ptrs
[
dims
]),
mstep_
(
_deltas
[
dims
*
2
+
1
]),
histogramSize_
(
hist
.
size
.
p
),
histogramType_
(
hist
.
type
()),
imageWidth_
(
imsize
.
width
),
tab_
((
size_t
*
)
&
tab
[
0
]),
globalHistogram_
(
hist
.
data
)
{
p_
[
0
]
=
(
uchar
*
)(
&
_ptrs
[
0
])[
0
];
p_
[
1
]
=
(
uchar
*
)(
&
_ptrs
[
0
])[
1
];
p_
[
2
]
=
(
uchar
*
)(
&
_ptrs
[
0
])[
2
];
step_
[
0
]
=
(
&
_deltas
[
0
])[
1
];
step_
[
1
]
=
(
&
_deltas
[
0
])[
3
];
step_
[
2
]
=
(
&
_deltas
[
0
])[
5
];
d_
[
0
]
=
(
&
_deltas
[
0
])[
0
];
d_
[
1
]
=
(
&
_deltas
[
0
])[
2
];
d_
[
2
]
=
(
&
_deltas
[
0
])[
4
];
}
void
operator
()(
const
BlockedRange
&
range
)
const
{
uchar
*
p0
=
p_
[
0
]
+
range
.
begin
()
*
(
step_
[
0
]
+
imageWidth_
*
d_
[
0
]);
uchar
*
p1
=
p_
[
1
]
+
range
.
begin
()
*
(
step_
[
1
]
+
imageWidth_
*
d_
[
1
]);
uchar
*
p2
=
p_
[
2
]
+
range
.
begin
()
*
(
step_
[
2
]
+
imageWidth_
*
d_
[
2
]);
uchar
*
mask
=
mask_
+
range
.
begin
()
*
mstep_
;
for
(
int
i
=
range
.
begin
();
i
<
range
.
end
();
i
++
,
p0
+=
step_
[
0
],
p1
+=
step_
[
1
],
p2
+=
step_
[
2
]
)
{
if
(
!
mask_
)
{
for
(
int
x
=
0
;
x
<
imageWidth_
;
x
++
,
p0
+=
d_
[
0
],
p1
+=
d_
[
1
],
p2
+=
d_
[
2
]
)
{
size_t
idx
=
tab_
[
*
p0
]
+
tab_
[
*
p1
+
256
]
+
tab_
[
*
p2
+
512
];
if
(
idx
<
OUT_OF_RANGE
)
{
(
*
(
tbb
::
atomic
<
int
>*
)(
globalHistogram_
+
idx
)
).
fetch_and_add
(
1
);
}
}
}
else
{
for
(
int
x
=
0
;
x
<
imageWidth_
;
x
++
,
p0
+=
d_
[
0
],
p1
+=
d_
[
1
],
p2
+=
d_
[
2
]
)
{
size_t
idx
;
if
(
mask
[
x
]
&&
(
idx
=
tab_
[
*
p0
]
+
tab_
[
*
p1
+
256
]
+
tab_
[
*
p2
+
512
])
<
OUT_OF_RANGE
)
{
(
*
(
tbb
::
atomic
<
int
>*
)(
globalHistogram_
+
idx
)).
fetch_and_add
(
1
);
}
}
mask
+=
mstep_
;
}
}
}
static
bool
isFit
(
const
Mat
&
histogram
,
const
Size
imageSize
)
{
return
(
histogram
.
total
()
>=
128
*
128
*
128
&&
imageSize
.
width
*
imageSize
.
width
>=
320
*
240
);
}
private
:
uchar
*
p_
[
three
];
uchar
*
mask_
;
int
mstep_
;
int
step_
[
three
];
int
d_
[
three
];
int
*
histogramSize_
;
int
histogramType_
;
int
imageWidth_
;
size_t
*
tab_
;
uchar
*
globalHistogram_
;
};
static
void
callCalcHist2D_8u
(
vector
<
uchar
*>&
_ptrs
,
const
vector
<
int
>&
_deltas
,
Size
imsize
,
Mat
&
hist
,
int
dims
,
vector
<
size_t
>&
_tab
)
{
int
grainSize
=
imsize
.
height
/
tbb
::
task_scheduler_init
::
default_num_threads
();
tbb
::
mutex
histogramWriteLock
;
CalcHist2D_8uInvoker
body
(
_ptrs
,
_deltas
,
imsize
,
hist
,
dims
,
_tab
,
&
histogramWriteLock
);
parallel_for
(
BlockedRange
(
0
,
imsize
.
height
,
grainSize
),
body
);
}
static
void
callCalcHist3D_8u
(
vector
<
uchar
*>&
_ptrs
,
const
vector
<
int
>&
_deltas
,
Size
imsize
,
Mat
&
hist
,
int
dims
,
vector
<
size_t
>&
_tab
)
{
CalcHist3D_8uInvoker
body
(
_ptrs
,
_deltas
,
imsize
,
hist
,
dims
,
_tab
);
parallel_for
(
BlockedRange
(
0
,
imsize
.
height
),
body
);
}
#endif
template
<
typename
T
>
static
void
calcHist_
(
vector
<
uchar
*>&
_ptrs
,
const
vector
<
int
>&
_deltas
,
...
...
@@ -234,6 +768,11 @@ calcHist_( vector<uchar*>& _ptrs, const vector<int>& _deltas,
if
(
dims
==
1
)
{
#ifdef HAVE_TBB
calcHist1D_Invoker
<
T
>
body
(
_ptrs
,
_deltas
,
hist
,
_uniranges
,
size
[
0
],
dims
,
imsize
);
parallel_for
(
BlockedRange
(
0
,
imsize
.
height
),
body
);
return
;
#endif
double
a
=
uniranges
[
0
],
b
=
uniranges
[
1
];
int
sz
=
size
[
0
],
d0
=
deltas
[
0
],
step0
=
deltas
[
1
];
const
T
*
p0
=
(
const
T
*
)
ptrs
[
0
];
...
...
@@ -259,6 +798,11 @@ calcHist_( vector<uchar*>& _ptrs, const vector<int>& _deltas,
}
else
if
(
dims
==
2
)
{
#ifdef HAVE_TBB
calcHist2D_Invoker
<
T
>
body
(
_ptrs
,
_deltas
,
hist
,
_uniranges
,
size
,
dims
,
imsize
,
hstep
);
parallel_for
(
BlockedRange
(
0
,
imsize
.
height
),
body
);
return
;
#endif
double
a0
=
uniranges
[
0
],
b0
=
uniranges
[
1
],
a1
=
uniranges
[
2
],
b1
=
uniranges
[
3
];
int
sz0
=
size
[
0
],
sz1
=
size
[
1
];
int
d0
=
deltas
[
0
],
step0
=
deltas
[
1
],
...
...
@@ -290,6 +834,14 @@ calcHist_( vector<uchar*>& _ptrs, const vector<int>& _deltas,
}
else
if
(
dims
==
3
)
{
#ifdef HAVE_TBB
if
(
calcHist3D_Invoker
<
T
>::
isFit
(
hist
,
imsize
)
)
{
calcHist3D_Invoker
<
T
>
body
(
_ptrs
,
_deltas
,
imsize
,
hist
,
uniranges
,
dims
,
hstep
,
size
);
parallel_for
(
BlockedRange
(
0
,
imsize
.
height
),
body
);
return
;
}
#endif
double
a0
=
uniranges
[
0
],
b0
=
uniranges
[
1
],
a1
=
uniranges
[
2
],
b1
=
uniranges
[
3
],
a2
=
uniranges
[
4
],
b2
=
uniranges
[
5
];
...
...
@@ -441,8 +993,20 @@ calcHist_8u( vector<uchar*>& _ptrs, const vector<int>& _deltas,
if
(
dims
==
1
)
{
#ifdef HAVE_TBB
if
(
CalcHist1D_8uInvoker
::
isFit
(
hist
,
imsize
)
)
{
int
treadsNumber
=
tbb
::
task_scheduler_init
::
default_num_threads
();
int
grainSize
=
imsize
.
height
/
treadsNumber
;
tbb
::
mutex
histogramWriteLock
;
CalcHist1D_8uInvoker
body
(
_ptrs
,
_deltas
,
imsize
,
hist
,
dims
,
_tab
,
&
histogramWriteLock
);
parallel_for
(
BlockedRange
(
0
,
imsize
.
height
,
grainSize
),
body
);
return
;
}
#endif
int
d0
=
deltas
[
0
],
step0
=
deltas
[
1
];
int
matH
[
256
]
=
{
0
};
int
matH
[
256
]
=
{
0
,
};
const
uchar
*
p0
=
(
const
uchar
*
)
ptrs
[
0
];
for
(
;
imsize
.
height
--
;
p0
+=
step0
,
mask
+=
mstep
)
...
...
@@ -489,6 +1053,13 @@ calcHist_8u( vector<uchar*>& _ptrs, const vector<int>& _deltas,
}
else
if
(
dims
==
2
)
{
#ifdef HAVE_TBB
if
(
CalcHist2D_8uInvoker
::
isFit
(
hist
,
imsize
)
)
{
callCalcHist2D_8u
(
_ptrs
,
_deltas
,
imsize
,
hist
,
dims
,
_tab
);
return
;
}
#endif
int
d0
=
deltas
[
0
],
step0
=
deltas
[
1
],
d1
=
deltas
[
2
],
step1
=
deltas
[
3
];
const
uchar
*
p0
=
(
const
uchar
*
)
ptrs
[
0
];
...
...
@@ -514,6 +1085,13 @@ calcHist_8u( vector<uchar*>& _ptrs, const vector<int>& _deltas,
}
else
if
(
dims
==
3
)
{
#ifdef HAVE_TBB
if
(
CalcHist3D_8uInvoker
::
isFit
(
hist
,
imsize
)
)
{
callCalcHist3D_8u
(
_ptrs
,
_deltas
,
imsize
,
hist
,
dims
,
_tab
);
return
;
}
#endif
int
d0
=
deltas
[
0
],
step0
=
deltas
[
1
],
d1
=
deltas
[
2
],
step1
=
deltas
[
3
],
d2
=
deltas
[
4
],
step2
=
deltas
[
5
];
...
...
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