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
7e358388
Commit
7e358388
authored
Sep 17, 2012
by
Andrey Kamaev
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Minor refactoring of NL-means denoising
parent
3c491755
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
201 additions
and
200 deletions
+201
-200
arrays.hpp
modules/photo/src/arrays.hpp
+23
-23
denoising.cpp
modules/photo/src/denoising.cpp
+37
-37
fast_nlmeans_denoising_invoker.hpp
modules/photo/src/fast_nlmeans_denoising_invoker.hpp
+77
-76
fast_nlmeans_denoising_invoker_commons.hpp
modules/photo/src/fast_nlmeans_denoising_invoker_commons.hpp
+2
-2
fast_nlmeans_multi_denoising_invoker.hpp
modules/photo/src/fast_nlmeans_multi_denoising_invoker.hpp
+62
-62
No files found.
modules/photo/src/arrays.hpp
View file @
7e358388
...
...
@@ -47,20 +47,20 @@ template <class T> struct Array2d {
int
n1
,
n2
;
bool
needToDeallocArray
;
Array2d
(
const
Array2d
&
array2d
)
:
a
(
array2d
.
a
),
n1
(
array2d
.
n1
),
n2
(
array2d
.
n2
),
needToDeallocArray
(
false
)
Array2d
(
const
Array2d
&
array2d
)
:
a
(
array2d
.
a
),
n1
(
array2d
.
n1
),
n2
(
array2d
.
n2
),
needToDeallocArray
(
false
)
{
if
(
array2d
.
needToDeallocArray
)
{
// copy constructor for self allocating arrays not supported
throw
new
exception
();
}
}
Array2d
(
T
*
_a
,
int
_n1
,
int
_n2
)
:
Array2d
(
T
*
_a
,
int
_n1
,
int
_n2
)
:
a
(
_a
),
n1
(
_n1
),
n2
(
_n2
),
needToDeallocArray
(
false
)
{}
Array2d
(
int
_n1
,
int
_n2
)
:
n1
(
_n1
),
n2
(
_n2
),
needToDeallocArray
(
true
)
Array2d
(
int
_n1
,
int
_n2
)
:
n1
(
_n1
),
n2
(
_n2
),
needToDeallocArray
(
true
)
{
a
=
new
T
[
n1
*
n2
];
}
...
...
@@ -74,7 +74,7 @@ template <class T> struct Array2d {
T
*
operator
[]
(
int
i
)
{
return
a
+
i
*
n2
;
}
inline
T
*
row_ptr
(
int
i
)
{
return
(
*
this
)[
i
];
}
...
...
@@ -84,12 +84,12 @@ template <class T> struct Array3d {
T
*
a
;
int
n1
,
n2
,
n3
;
bool
needToDeallocArray
;
Array3d
(
T
*
_a
,
int
_n1
,
int
_n2
,
int
_n3
)
:
Array3d
(
T
*
_a
,
int
_n1
,
int
_n2
,
int
_n3
)
:
a
(
_a
),
n1
(
_n1
),
n2
(
_n2
),
n3
(
_n3
),
needToDeallocArray
(
false
)
{}
Array3d
(
int
_n1
,
int
_n2
,
int
_n3
)
:
n1
(
_n1
),
n2
(
_n2
),
n3
(
_n3
),
needToDeallocArray
(
true
)
Array3d
(
int
_n1
,
int
_n2
,
int
_n3
)
:
n1
(
_n1
),
n2
(
_n2
),
n3
(
_n3
),
needToDeallocArray
(
true
)
{
a
=
new
T
[
n1
*
n2
*
n3
];
}
...
...
@@ -115,25 +115,25 @@ template <class T> struct Array4d {
int
n1
,
n2
,
n3
,
n4
;
bool
needToDeallocArray
;
int
steps
[
4
];
void
init_steps
()
{
steps
[
0
]
=
n2
*
n3
*
n4
;
steps
[
1
]
=
n3
*
n4
;
steps
[
2
]
=
n4
;
steps
[
3
]
=
1
;
steps
[
0
]
=
n2
*
n3
*
n4
;
steps
[
1
]
=
n3
*
n4
;
steps
[
2
]
=
n4
;
steps
[
3
]
=
1
;
}
Array4d
(
T
*
_a
,
int
_n1
,
int
_n2
,
int
_n3
,
int
_n4
)
:
a
(
_a
),
n1
(
_n1
),
n2
(
_n2
),
n3
(
_n3
),
n4
(
_n4
),
needToDeallocArray
(
false
)
Array4d
(
T
*
_a
,
int
_n1
,
int
_n2
,
int
_n3
,
int
_n4
)
:
a
(
_a
),
n1
(
_n1
),
n2
(
_n2
),
n3
(
_n3
),
n4
(
_n4
),
needToDeallocArray
(
false
)
{
init_steps
();
init_steps
();
}
Array4d
(
int
_n1
,
int
_n2
,
int
_n3
,
int
_n4
)
:
n1
(
_n1
),
n2
(
_n2
),
n3
(
_n3
),
n4
(
_n4
),
needToDeallocArray
(
true
)
Array4d
(
int
_n1
,
int
_n2
,
int
_n3
,
int
_n4
)
:
n1
(
_n1
),
n2
(
_n2
),
n3
(
_n3
),
n4
(
_n4
),
needToDeallocArray
(
true
)
{
a
=
new
T
[
n1
*
n2
*
n3
*
n4
];
init_steps
();
a
=
new
T
[
n1
*
n2
*
n3
*
n4
];
init_steps
();
}
~
Array4d
()
{
...
...
modules/photo/src/denoising.cpp
View file @
7e358388
...
...
@@ -51,37 +51,37 @@ void cv::fastNlMeansDenoising( InputArray _src, OutputArray _dst,
Mat
src
=
_src
.
getMat
();
_dst
.
create
(
src
.
size
(),
src
.
type
());
Mat
dst
=
_dst
.
getMat
();
switch
(
src
.
type
())
{
case
CV_8U
:
parallel_for
(
cv
::
BlockedRange
(
0
,
src
.
rows
),
parallel_for
(
cv
::
BlockedRange
(
0
,
src
.
rows
),
FastNlMeansDenoisingInvoker
<
uchar
>
(
src
,
dst
,
templateWindowSize
,
searchWindowSize
,
h
));
break
;
case
CV_8UC2
:
parallel_for
(
cv
::
BlockedRange
(
0
,
src
.
rows
),
parallel_for
(
cv
::
BlockedRange
(
0
,
src
.
rows
),
FastNlMeansDenoisingInvoker
<
cv
::
Vec2b
>
(
src
,
dst
,
templateWindowSize
,
searchWindowSize
,
h
));
break
;
case
CV_8UC3
:
parallel_for
(
cv
::
BlockedRange
(
0
,
src
.
rows
),
parallel_for
(
cv
::
BlockedRange
(
0
,
src
.
rows
),
FastNlMeansDenoisingInvoker
<
cv
::
Vec3b
>
(
src
,
dst
,
templateWindowSize
,
searchWindowSize
,
h
));
break
;
default
:
CV_Error
(
CV_StsBadArg
,
"Unsupported
matrix format! Only uchar, Vec2b, Vec3b
are supported"
);
CV_Error
(
CV_StsBadArg
,
"Unsupported
image format! Only CV_8UC1, CV_8UC2 and CV_8UC3
are supported"
);
}
}
void
cv
::
fastNlMeansDenoisingColored
(
InputArray
_src
,
OutputArray
_dst
,
int
templateWindowSize
,
int
searchWindowSize
,
int
templateWindowSize
,
int
searchWindowSize
,
int
h
,
int
hForColorComponents
)
{
Mat
src
=
_src
.
getMat
();
_dst
.
create
(
src
.
size
(),
src
.
type
());
Mat
dst
=
_dst
.
getMat
();
if
(
src
.
type
()
!=
CV_8UC3
)
{
CV_Error
(
CV_StsBadArg
,
"Type of input image should be CV_8UC3!"
);
return
;
...
...
@@ -89,13 +89,13 @@ void cv::fastNlMeansDenoisingColored( InputArray _src, OutputArray _dst,
Mat
src_lab
;
cvtColor
(
src
,
src_lab
,
CV_LBGR2Lab
);
Mat
l
(
src
.
size
(),
CV_8U
);
Mat
ab
(
src
.
size
(),
CV_8UC2
);
Mat
l_ab
[]
=
{
l
,
ab
};
int
from_to
[]
=
{
0
,
0
,
1
,
1
,
2
,
2
};
mixChannels
(
&
src_lab
,
1
,
l_ab
,
2
,
from_to
,
3
);
fastNlMeansDenoising
(
l
,
l
,
templateWindowSize
,
searchWindowSize
,
h
);
fastNlMeansDenoising
(
ab
,
ab
,
templateWindowSize
,
searchWindowSize
,
hForColorComponents
);
...
...
@@ -106,10 +106,10 @@ void cv::fastNlMeansDenoisingColored( InputArray _src, OutputArray _dst,
cvtColor
(
dst_lab
,
dst
,
CV_Lab2LBGR
);
}
static
void
fastNlMeansDenoisingMultiCheckPreconditions
(
const
std
::
vector
<
Mat
>&
srcImgs
,
static
void
fastNlMeansDenoisingMultiCheckPreconditions
(
const
std
::
vector
<
Mat
>&
srcImgs
,
int
imgToDenoiseIndex
,
int
temporalWindowSize
,
int
templateWindowSize
,
int
searchWindowSize
)
int
templateWindowSize
,
int
searchWindowSize
)
{
int
src_imgs_size
=
(
int
)
srcImgs
.
size
();
if
(
src_imgs_size
==
0
)
{
...
...
@@ -123,10 +123,10 @@ static void fastNlMeansDenoisingMultiCheckPreconditions(
}
int
temporalWindowHalfSize
=
temporalWindowSize
/
2
;
if
(
imgToDenoiseIndex
-
temporalWindowHalfSize
<
0
||
imgToDenoiseIndex
+
temporalWindowHalfSize
>=
src_imgs_size
)
{
CV_Error
(
CV_StsBadArg
,
if
(
imgToDenoiseIndex
-
temporalWindowHalfSize
<
0
||
imgToDenoiseIndex
+
temporalWindowHalfSize
>=
src_imgs_size
)
{
CV_Error
(
CV_StsBadArg
,
"imgToDenoiseIndex and temporalWindowSize "
"should be choosen corresponding srcImgs size!"
);
}
...
...
@@ -138,16 +138,16 @@ static void fastNlMeansDenoisingMultiCheckPreconditions(
}
}
void
cv
::
fastNlMeansDenoisingMulti
(
InputArrayOfArrays
_srcImgs
,
void
cv
::
fastNlMeansDenoisingMulti
(
InputArrayOfArrays
_srcImgs
,
int
imgToDenoiseIndex
,
int
temporalWindowSize
,
OutputArray
_dst
,
int
templateWindowSize
,
int
searchWindowSize
,
int
h
)
{
vector
<
Mat
>
srcImgs
;
_srcImgs
.
getMatVector
(
srcImgs
);
fastNlMeansDenoisingMultiCheckPreconditions
(
srcImgs
,
imgToDenoiseIndex
,
srcImgs
,
imgToDenoiseIndex
,
temporalWindowSize
,
templateWindowSize
,
searchWindowSize
);
_dst
.
create
(
srcImgs
[
0
].
size
(),
srcImgs
[
0
].
type
());
...
...
@@ -155,43 +155,43 @@ void cv::fastNlMeansDenoisingMulti( InputArrayOfArrays _srcImgs,
switch
(
srcImgs
[
0
].
type
())
{
case
CV_8U
:
parallel_for
(
cv
::
BlockedRange
(
0
,
srcImgs
[
0
].
rows
),
parallel_for
(
cv
::
BlockedRange
(
0
,
srcImgs
[
0
].
rows
),
FastNlMeansMultiDenoisingInvoker
<
uchar
>
(
srcImgs
,
imgToDenoiseIndex
,
temporalWindowSize
,
srcImgs
,
imgToDenoiseIndex
,
temporalWindowSize
,
dst
,
templateWindowSize
,
searchWindowSize
,
h
));
break
;
case
CV_8UC2
:
parallel_for
(
cv
::
BlockedRange
(
0
,
srcImgs
[
0
].
rows
),
parallel_for
(
cv
::
BlockedRange
(
0
,
srcImgs
[
0
].
rows
),
FastNlMeansMultiDenoisingInvoker
<
cv
::
Vec2b
>
(
srcImgs
,
imgToDenoiseIndex
,
temporalWindowSize
,
srcImgs
,
imgToDenoiseIndex
,
temporalWindowSize
,
dst
,
templateWindowSize
,
searchWindowSize
,
h
));
break
;
case
CV_8UC3
:
parallel_for
(
cv
::
BlockedRange
(
0
,
srcImgs
[
0
].
rows
),
parallel_for
(
cv
::
BlockedRange
(
0
,
srcImgs
[
0
].
rows
),
FastNlMeansMultiDenoisingInvoker
<
cv
::
Vec3b
>
(
srcImgs
,
imgToDenoiseIndex
,
temporalWindowSize
,
srcImgs
,
imgToDenoiseIndex
,
temporalWindowSize
,
dst
,
templateWindowSize
,
searchWindowSize
,
h
));
break
;
default
:
CV_Error
(
CV_StsBadArg
,
CV_Error
(
CV_StsBadArg
,
"Unsupported matrix format! Only uchar, Vec2b, Vec3b are supported"
);
}
}
void
cv
::
fastNlMeansDenoisingColoredMulti
(
InputArrayOfArrays
_srcImgs
,
void
cv
::
fastNlMeansDenoisingColoredMulti
(
InputArrayOfArrays
_srcImgs
,
int
imgToDenoiseIndex
,
int
temporalWindowSize
,
OutputArray
_dst
,
int
templateWindowSize
,
int
searchWindowSize
,
int
templateWindowSize
,
int
searchWindowSize
,
int
h
,
int
hForColorComponents
)
{
vector
<
Mat
>
srcImgs
;
_srcImgs
.
getMatVector
(
srcImgs
);
fastNlMeansDenoisingMultiCheckPreconditions
(
srcImgs
,
imgToDenoiseIndex
,
srcImgs
,
imgToDenoiseIndex
,
temporalWindowSize
,
templateWindowSize
,
searchWindowSize
);
_dst
.
create
(
srcImgs
[
0
].
size
(),
srcImgs
[
0
].
type
());
Mat
dst
=
_dst
.
getMat
();
...
...
@@ -207,26 +207,26 @@ void cv::fastNlMeansDenoisingColoredMulti( InputArrayOfArrays _srcImgs,
// TODO convert only required images
vector
<
Mat
>
src_lab
(
src_imgs_size
);
vector
<
Mat
>
l
(
src_imgs_size
);
vector
<
Mat
>
ab
(
src_imgs_size
);
vector
<
Mat
>
ab
(
src_imgs_size
);
for
(
int
i
=
0
;
i
<
src_imgs_size
;
i
++
)
{
src_lab
[
i
]
=
Mat
::
zeros
(
srcImgs
[
0
].
size
(),
CV_8UC3
);
l
[
i
]
=
Mat
::
zeros
(
srcImgs
[
0
].
size
(),
CV_8UC1
);
ab
[
i
]
=
Mat
::
zeros
(
srcImgs
[
0
].
size
(),
CV_8UC2
);
cvtColor
(
srcImgs
[
i
],
src_lab
[
i
],
CV_LBGR2Lab
);
Mat
l_ab
[]
=
{
l
[
i
],
ab
[
i
]
};
mixChannels
(
&
src_lab
[
i
],
1
,
l_ab
,
2
,
from_to
,
3
);
}
Mat
dst_l
;
Mat
dst_ab
;
fastNlMeansDenoisingMulti
(
l
,
imgToDenoiseIndex
,
temporalWindowSize
,
l
,
imgToDenoiseIndex
,
temporalWindowSize
,
dst_l
,
templateWindowSize
,
searchWindowSize
,
h
);
fastNlMeansDenoisingMulti
(
ab
,
imgToDenoiseIndex
,
temporalWindowSize
,
ab
,
imgToDenoiseIndex
,
temporalWindowSize
,
dst_ab
,
templateWindowSize
,
searchWindowSize
,
hForColorComponents
);
Mat
l_ab_denoised
[]
=
{
dst_l
,
dst_ab
};
...
...
modules/photo/src/fast_nlmeans_denoising_invoker.hpp
View file @
7e358388
...
...
@@ -56,17 +56,15 @@ using namespace cv;
template
<
typename
T
>
struct
FastNlMeansDenoisingInvoker
{
public
:
FastNlMeansDenoisingInvoker
(
const
Mat
&
src
,
Mat
&
dst
,
public
:
FastNlMeansDenoisingInvoker
(
const
Mat
&
src
,
Mat
&
dst
,
int
template_window_size
,
int
search_window_size
,
const
double
h
);
void
operator
()
(
const
BlockedRange
&
range
)
const
;
void
operator
=
(
const
FastNlMeansDenoisingInvoker
&
)
{
CV_Error
(
CV_StsNotImplemented
,
"Assigment operator is not implemented"
);
}
private
:
void
operator
=
(
const
FastNlMeansDenoisingInvoker
&
);
const
Mat
&
src_
;
Mat
&
dst_
;
...
...
@@ -80,41 +78,48 @@ struct FastNlMeansDenoisingInvoker {
int
search_window_half_size_
;
int
fixed_point_mult_
;
int
almost_template_window_size_sq_bin_shift
;
vector
<
int
>
almost_dist2weight
;
int
almost_template_window_size_sq_bin_shift
_
;
vector
<
int
>
almost_dist2weight
_
;
void
calcDistSumsForFirstElementInRow
(
int
i
,
Array2d
<
int
>&
dist_sums
,
Array3d
<
int
>&
col_dist_sums
,
Array3d
<
int
>&
up_col_dist_sums
)
const
;
int
i
,
Array2d
<
int
>&
dist_sums
,
Array3d
<
int
>&
col_dist_sums
,
Array3d
<
int
>&
up_col_dist_sums
)
const
;
void
calcDistSumsForElementInFirstRow
(
int
i
,
int
j
,
int
j
,
int
first_col_num
,
Array2d
<
int
>&
dist_sums
,
Array3d
<
int
>&
col_dist_sums
,
Array3d
<
int
>&
up_col_dist_sums
)
const
;
Array2d
<
int
>&
dist_sums
,
Array3d
<
int
>&
col_dist_sums
,
Array3d
<
int
>&
up_col_dist_sums
)
const
;
};
inline
int
getNearestPowerOf2
(
int
value
)
{
int
p
=
0
;
while
(
1
<<
p
<
value
)
++
p
;
return
p
;
}
template
<
class
T
>
FastNlMeansDenoisingInvoker
<
T
>::
FastNlMeansDenoisingInvoker
(
const
cv
::
Mat
&
src
,
cv
::
Mat
&
dst
,
int
template_window_size
,
int
search_window_size
,
const
cv
::
Mat
&
src
,
cv
::
Mat
&
dst
,
int
template_window_size
,
int
search_window_size
,
const
double
h
)
:
src_
(
src
),
dst_
(
dst
)
{
CV_Assert
(
src
.
channels
()
<=
3
);
CV_Assert
(
src
.
channels
()
==
sizeof
(
T
));
//T is Vec1b or Vec2b or Vec3b
template_window_half_size_
=
template_window_size
/
2
;
search_window_half_size_
=
search_window_size
/
2
;
template_window_size_
=
template_window_half_size_
*
2
+
1
;
search_window_size_
=
search_window_half_size_
*
2
+
1
;
search_window_half_size_
=
search_window_size
/
2
;
template_window_size_
=
template_window_half_size_
*
2
+
1
;
search_window_size_
=
search_window_half_size_
*
2
+
1
;
border_size_
=
search_window_half_size_
+
template_window_half_size_
;
copyMakeBorder
(
src_
,
extended_src_
,
copyMakeBorder
(
src_
,
extended_src_
,
border_size_
,
border_size_
,
border_size_
,
border_size_
,
cv
::
BORDER_DEFAULT
);
const
int
max_estimate_sum_value
=
search_window_size_
*
search_window_size_
*
255
;
...
...
@@ -122,19 +127,15 @@ FastNlMeansDenoisingInvoker<T>::FastNlMeansDenoisingInvoker(
// precalc weight for every possible l2 dist between blocks
// additional optimization of precalced weights to replace division(averaging) by binary shift
CV_Assert
(
template_window_size_
<=
46340
);
// sqrt(INT_MAX)
int
template_window_size_sq
=
template_window_size_
*
template_window_size_
;
almost_template_window_size_sq_bin_shift
=
0
;
while
(
1
<<
almost_template_window_size_sq_bin_shift
<
template_window_size_sq
)
{
almost_template_window_size_sq_bin_shift
++
;
}
int
almost_template_window_size_sq
=
1
<<
almost_template_window_size_sq_bin_shift
;
double
almost_dist2actual_dist_multiplier
=
((
double
)
almost_template_window_size_sq
)
/
template_window_size_sq
;
almost_template_window_size_sq_bin_shift_
=
getNearestPowerOf2
(
template_window_size_sq
);
double
almost_dist2actual_dist_multiplier
=
((
double
)(
1
<<
almost_template_window_size_sq_bin_shift_
))
/
template_window_size_sq
;
int
max_dist
=
256
*
256
*
src_
.
channels
();
int
almost_max_dist
=
(
int
)
(
max_dist
/
almost_dist2actual_dist_multiplier
+
1
);
almost_dist2weight
.
resize
(
almost_max_dist
);
almost_dist2weight
_
.
resize
(
almost_max_dist
);
const
double
WEIGHT_THRESHOLD
=
0.001
;
for
(
int
almost_dist
=
0
;
almost_dist
<
almost_max_dist
;
almost_dist
++
)
{
...
...
@@ -145,7 +146,7 @@ FastNlMeansDenoisingInvoker<T>::FastNlMeansDenoisingInvoker(
weight
=
0
;
}
almost_dist2weight
[
almost_dist
]
=
weight
;
almost_dist2weight
_
[
almost_dist
]
=
weight
;
}
// additional optimization init end
...
...
@@ -160,10 +161,10 @@ void FastNlMeansDenoisingInvoker<T>::operator() (const BlockedRange& range) cons
int
row_to
=
range
.
end
()
-
1
;
Array2d
<
int
>
dist_sums
(
search_window_size_
,
search_window_size_
);
// for lazy calc optimization
Array3d
<
int
>
col_dist_sums
(
template_window_size_
,
search_window_size_
,
search_window_size_
);
int
first_col_num
=
-
1
;
Array3d
<
int
>
up_col_dist_sums
(
src_
.
cols
,
search_window_size_
,
search_window_size_
);
...
...
@@ -179,17 +180,17 @@ void FastNlMeansDenoisingInvoker<T>::operator() (const BlockedRange& range) cons
}
else
{
// calc cur dist_sums using previous dist_sums
if
(
i
==
row_from
)
{
calcDistSumsForElementInFirstRow
(
i
,
j
,
first_col_num
,
dist_sums
,
col_dist_sums
,
up_col_dist_sums
);
calcDistSumsForElementInFirstRow
(
i
,
j
,
first_col_num
,
dist_sums
,
col_dist_sums
,
up_col_dist_sums
);
}
else
{
int
ay
=
border_size_
+
i
;
int
ay
=
border_size_
+
i
;
int
ax
=
border_size_
+
j
+
template_window_half_size_
;
int
start_by
=
int
start_by
=
border_size_
+
i
-
search_window_half_size_
;
int
start_bx
=
int
start_bx
=
border_size_
+
j
-
search_window_half_size_
+
template_window_half_size_
;
T
a_up
=
extended_src_
.
at
<
T
>
(
ay
-
template_window_half_size_
-
1
,
ax
);
...
...
@@ -200,64 +201,64 @@ void FastNlMeansDenoisingInvoker<T>::operator() (const BlockedRange& range) cons
for
(
int
y
=
0
;
y
<
search_window_size
;
y
++
)
{
int
*
dist_sums_row
=
dist_sums
.
row_ptr
(
y
);
int
*
col_dist_sums_row
=
col_dist_sums
.
row_ptr
(
first_col_num
,
y
);
int
*
up_col_dist_sums_row
=
up_col_dist_sums
.
row_ptr
(
j
,
y
);
const
T
*
b_up_ptr
=
const
T
*
b_up_ptr
=
extended_src_
.
ptr
<
T
>
(
start_by
-
template_window_half_size_
-
1
+
y
);
const
T
*
b_down_ptr
=
const
T
*
b_down_ptr
=
extended_src_
.
ptr
<
T
>
(
start_by
+
template_window_half_size_
+
y
);
for
(
int
x
=
0
;
x
<
search_window_size
;
x
++
)
{
dist_sums_row
[
x
]
-=
col_dist_sums_row
[
x
];
col_dist_sums_row
[
x
]
=
up_col_dist_sums_row
[
x
]
+
col_dist_sums_row
[
x
]
=
up_col_dist_sums_row
[
x
]
+
calcUpDownDist
(
a_up
,
a_down
,
a_up
,
a_down
,
b_up_ptr
[
start_bx
+
x
],
b_down_ptr
[
start_bx
+
x
]
);
dist_sums_row
[
x
]
+=
col_dist_sums_row
[
x
];
up_col_dist_sums_row
[
x
]
=
col_dist_sums_row
[
x
];
}
}
}
first_col_num
=
(
first_col_num
+
1
)
%
template_window_size_
;
}
// calc weights
int
weights_sum
=
0
;
int
estimation
[
3
];
int
estimation
[
3
];
for
(
int
channel_num
=
0
;
channel_num
<
src_
.
channels
();
channel_num
++
)
{
estimation
[
channel_num
]
=
0
;
}
for
(
int
y
=
0
;
y
<
search_window_size_
;
y
++
)
{
const
T
*
cur_row_ptr
=
extended_src_
.
ptr
<
T
>
(
border_size_
+
search_window_y
+
y
);
int
*
dist_sums_row
=
dist_sums
.
row_ptr
(
y
);
for
(
int
x
=
0
;
x
<
search_window_size_
;
x
++
)
{
int
almostAvgDist
=
dist_sums_row
[
x
]
>>
almost_template_window_size_sq_bin_shift
;
int
almostAvgDist
=
dist_sums_row
[
x
]
>>
almost_template_window_size_sq_bin_shift
_
;
int
weight
=
almost_dist2weight
[
almostAvgDist
];
int
weight
=
almost_dist2weight
_
[
almostAvgDist
];
weights_sum
+=
weight
;
T
p
=
cur_row_ptr
[
border_size_
+
search_window_x
+
x
];
incWithWeight
(
estimation
,
weight
,
p
);
}
}
if
(
weights_sum
>
0
)
{
for
(
int
channel_num
=
0
;
channel_num
<
src_
.
channels
();
channel_num
++
)
{
estimation
[
channel_num
]
=
estimation
[
channel_num
]
=
cvRound
(((
double
)
estimation
[
channel_num
])
/
weights_sum
);
}
...
...
@@ -272,9 +273,9 @@ void FastNlMeansDenoisingInvoker<T>::operator() (const BlockedRange& range) cons
template
<
class
T
>
inline
void
FastNlMeansDenoisingInvoker
<
T
>::
calcDistSumsForFirstElementInRow
(
int
i
,
Array2d
<
int
>&
dist_sums
,
Array3d
<
int
>&
col_dist_sums
,
int
i
,
Array2d
<
int
>&
dist_sums
,
Array3d
<
int
>&
col_dist_sums
,
Array3d
<
int
>&
up_col_dist_sums
)
const
{
int
j
=
0
;
...
...
@@ -291,7 +292,7 @@ inline void FastNlMeansDenoisingInvoker<T>::calcDistSumsForFirstElementInRow(
for
(
int
ty
=
-
template_window_half_size_
;
ty
<=
template_window_half_size_
;
ty
++
)
{
for
(
int
tx
=
-
template_window_half_size_
;
tx
<=
template_window_half_size_
;
tx
++
)
{
int
dist
=
calcDist
<
T
>
(
extended_src_
,
int
dist
=
calcDist
<
T
>
(
extended_src_
,
border_size_
+
i
+
ty
,
border_size_
+
j
+
tx
,
border_size_
+
start_y
+
ty
,
border_size_
+
start_x
+
tx
);
...
...
@@ -310,29 +311,29 @@ inline void FastNlMeansDenoisingInvoker<T>::calcDistSumsForElementInFirstRow(
int
i
,
int
j
,
int
first_col_num
,
Array2d
<
int
>&
dist_sums
,
Array3d
<
int
>&
col_dist_sums
,
Array2d
<
int
>&
dist_sums
,
Array3d
<
int
>&
col_dist_sums
,
Array3d
<
int
>&
up_col_dist_sums
)
const
{
int
ay
=
border_size_
+
i
;
int
ay
=
border_size_
+
i
;
int
ax
=
border_size_
+
j
+
template_window_half_size_
;
int
start_by
=
border_size_
+
i
-
search_window_half_size_
;
int
start_bx
=
border_size_
+
j
-
search_window_half_size_
+
template_window_half_size_
;
int
new_last_col_num
=
first_col_num
;
for
(
int
y
=
0
;
y
<
search_window_size_
;
y
++
)
{
for
(
int
x
=
0
;
x
<
search_window_size_
;
x
++
)
{
dist_sums
[
y
][
x
]
-=
col_dist_sums
[
first_col_num
][
y
][
x
];
col_dist_sums
[
new_last_col_num
][
y
][
x
]
=
0
;
int
by
=
start_by
+
y
;
col_dist_sums
[
new_last_col_num
][
y
][
x
]
=
0
;
int
by
=
start_by
+
y
;
int
bx
=
start_bx
+
x
;
for
(
int
ty
=
-
template_window_half_size_
;
ty
<=
template_window_half_size_
;
ty
++
)
{
col_dist_sums
[
new_last_col_num
][
y
][
x
]
+=
col_dist_sums
[
new_last_col_num
][
y
][
x
]
+=
calcDist
<
T
>
(
extended_src_
,
ay
+
ty
,
ax
,
by
+
ty
,
bx
);
}
}
dist_sums
[
y
][
x
]
+=
col_dist_sums
[
new_last_col_num
][
y
][
x
];
...
...
modules/photo/src/fast_nlmeans_denoising_invoker_commons.hpp
View file @
7e358388
...
...
@@ -65,7 +65,7 @@ template <> inline int calcDist(const Vec3b a, const Vec3b b) {
template
<
typename
T
>
static
inline
int
calcDist
(
const
Mat
&
m
,
int
i1
,
int
j1
,
int
i2
,
int
j2
)
{
const
T
a
=
m
.
at
<
T
>
(
i1
,
j1
);
const
T
b
=
m
.
at
<
T
>
(
i2
,
j2
);
const
T
b
=
m
.
at
<
T
>
(
i2
,
j2
);
return
calcDist
<
T
>
(
a
,
b
);
}
...
...
@@ -108,7 +108,7 @@ template <> inline Vec2b saturateCastFromArray(int* estimation) {
res
[
1
]
=
saturate_cast
<
uchar
>
(
estimation
[
1
]);
return
res
;
}
template
<>
inline
Vec3b
saturateCastFromArray
(
int
*
estimation
)
{
Vec3b
res
;
res
[
0
]
=
saturate_cast
<
uchar
>
(
estimation
[
0
]);
...
...
modules/photo/src/fast_nlmeans_multi_denoising_invoker.hpp
View file @
7e358388
...
...
@@ -56,16 +56,16 @@ using namespace cv;
template
<
typename
T
>
struct
FastNlMeansMultiDenoisingInvoker
{
public
:
public
:
FastNlMeansMultiDenoisingInvoker
(
const
std
::
vector
<
Mat
>&
srcImgs
,
int
imgToDenoiseIndex
,
int
temporalWindowSize
,
const
std
::
vector
<
Mat
>&
srcImgs
,
int
imgToDenoiseIndex
,
int
temporalWindowSize
,
Mat
&
dst
,
int
template_window_size
,
int
search_window_size
,
const
double
h
);
void
operator
()
(
const
BlockedRange
&
range
)
const
;
void
operator
=
(
const
FastNlMeansMultiDenoisingInvoker
&
)
{
CV_Error
(
CV_StsNotImplemented
,
"Assigment operator is not implemented"
);
}
void
operator
=
(
const
FastNlMeansMultiDenoisingInvoker
&
)
{
CV_Error
(
CV_StsNotImplemented
,
"Assigment operator is not implemented"
);
}
private
:
int
rows_
;
...
...
@@ -91,28 +91,28 @@ struct FastNlMeansMultiDenoisingInvoker {
vector
<
int
>
almost_dist2weight
;
void
calcDistSumsForFirstElementInRow
(
int
i
,
Array3d
<
int
>&
dist_sums
,
Array4d
<
int
>&
col_dist_sums
,
Array4d
<
int
>&
up_col_dist_sums
)
const
;
int
i
,
Array3d
<
int
>&
dist_sums
,
Array4d
<
int
>&
col_dist_sums
,
Array4d
<
int
>&
up_col_dist_sums
)
const
;
void
calcDistSumsForElementInFirstRow
(
int
i
,
int
j
,
int
j
,
int
first_col_num
,
Array3d
<
int
>&
dist_sums
,
Array4d
<
int
>&
col_dist_sums
,
Array4d
<
int
>&
up_col_dist_sums
)
const
;
Array3d
<
int
>&
dist_sums
,
Array4d
<
int
>&
col_dist_sums
,
Array4d
<
int
>&
up_col_dist_sums
)
const
;
};
template
<
class
T
>
FastNlMeansMultiDenoisingInvoker
<
T
>::
FastNlMeansMultiDenoisingInvoker
(
const
vector
<
Mat
>&
srcImgs
,
int
imgToDenoiseIndex
,
int
temporalWindowSize
,
cv
::
Mat
&
dst
,
int
template_window_size
,
int
search_window_size
,
const
vector
<
Mat
>&
srcImgs
,
int
imgToDenoiseIndex
,
int
temporalWindowSize
,
cv
::
Mat
&
dst
,
int
template_window_size
,
int
search_window_size
,
const
double
h
)
:
dst_
(
dst
),
extended_srcs_
(
srcImgs
.
size
())
{
CV_Assert
(
srcImgs
.
size
()
>
0
);
...
...
@@ -131,14 +131,14 @@ FastNlMeansMultiDenoisingInvoker<T>::FastNlMeansMultiDenoisingInvoker(
temporal_window_size_
=
temporal_window_half_size_
*
2
+
1
;
border_size_
=
search_window_half_size_
+
template_window_half_size_
;
for
(
int
i
=
0
;
i
<
temporal_window_size_
;
i
++
)
{
for
(
int
i
=
0
;
i
<
temporal_window_size_
;
i
++
)
{
copyMakeBorder
(
srcImgs
[
imgToDenoiseIndex
-
temporal_window_half_size_
+
i
],
extended_srcs_
[
i
],
srcImgs
[
imgToDenoiseIndex
-
temporal_window_half_size_
+
i
],
extended_srcs_
[
i
],
border_size_
,
border_size_
,
border_size_
,
border_size_
,
cv
::
BORDER_DEFAULT
);
}
main_extended_src_
=
extended_srcs_
[
temporal_window_half_size_
];
const
int
max_estimate_sum_value
=
const
int
max_estimate_sum_value
=
temporal_window_size_
*
search_window_size_
*
search_window_size_
*
255
;
fixed_point_mult_
=
numeric_limits
<
int
>::
max
()
/
max_estimate_sum_value
;
...
...
@@ -150,9 +150,9 @@ FastNlMeansMultiDenoisingInvoker<T>::FastNlMeansMultiDenoisingInvoker(
while
(
1
<<
almost_template_window_size_sq_bin_shift
<
template_window_size_sq
)
{
almost_template_window_size_sq_bin_shift
++
;
}
int
almost_template_window_size_sq
=
1
<<
almost_template_window_size_sq_bin_shift
;
double
almost_dist2actual_dist_multiplier
=
double
almost_dist2actual_dist_multiplier
=
((
double
)
almost_template_window_size_sq
)
/
template_window_size_sq
;
int
max_dist
=
256
*
256
*
channels_count_
;
...
...
@@ -183,16 +183,16 @@ void FastNlMeansMultiDenoisingInvoker<T>::operator() (const BlockedRange& range)
int
row_to
=
range
.
end
()
-
1
;
Array3d
<
int
>
dist_sums
(
temporal_window_size_
,
search_window_size_
,
search_window_size_
);
// for lazy calc optimization
Array4d
<
int
>
col_dist_sums
(
template_window_size_
,
temporal_window_size_
,
search_window_size_
,
search_window_size_
);
template_window_size_
,
temporal_window_size_
,
search_window_size_
,
search_window_size_
);
int
first_col_num
=
-
1
;
Array4d
<
int
>
up_col_dist_sums
(
cols_
,
temporal_window_size_
,
search_window_size_
,
search_window_size_
);
for
(
int
i
=
row_from
;
i
<=
row_to
;
i
++
)
{
for
(
int
j
=
0
;
j
<
cols_
;
j
++
)
{
int
search_window_y
=
i
-
search_window_half_size_
;
...
...
@@ -205,17 +205,17 @@ void FastNlMeansMultiDenoisingInvoker<T>::operator() (const BlockedRange& range)
}
else
{
// calc cur dist_sums using previous dist_sums
if
(
i
==
row_from
)
{
calcDistSumsForElementInFirstRow
(
i
,
j
,
first_col_num
,
dist_sums
,
col_dist_sums
,
up_col_dist_sums
);
calcDistSumsForElementInFirstRow
(
i
,
j
,
first_col_num
,
dist_sums
,
col_dist_sums
,
up_col_dist_sums
);
}
else
{
int
ay
=
border_size_
+
i
;
int
ay
=
border_size_
+
i
;
int
ax
=
border_size_
+
j
+
template_window_half_size_
;
int
start_by
=
int
start_by
=
border_size_
+
i
-
search_window_half_size_
;
int
start_bx
=
int
start_bx
=
border_size_
+
j
-
search_window_half_size_
+
template_window_half_size_
;
T
a_up
=
main_extended_src_
.
at
<
T
>
(
ay
-
template_window_half_size_
-
1
,
ax
);
...
...
@@ -231,41 +231,41 @@ void FastNlMeansMultiDenoisingInvoker<T>::operator() (const BlockedRange& range)
Array2d
<
int
>
cur_up_col_dist_sums
=
up_col_dist_sums
[
j
][
d
];
for
(
int
y
=
0
;
y
<
search_window_size
;
y
++
)
{
int
*
dist_sums_row
=
cur_dist_sums
.
row_ptr
(
y
);
int
*
col_dist_sums_row
=
cur_col_dist_sums
.
row_ptr
(
y
);
int
*
up_col_dist_sums_row
=
cur_up_col_dist_sums
.
row_ptr
(
y
);
const
T
*
b_up_ptr
=
const
T
*
b_up_ptr
=
cur_extended_src
.
ptr
<
T
>
(
start_by
-
template_window_half_size_
-
1
+
y
);
const
T
*
b_down_ptr
=
const
T
*
b_down_ptr
=
cur_extended_src
.
ptr
<
T
>
(
start_by
+
template_window_half_size_
+
y
);
for
(
int
x
=
0
;
x
<
search_window_size
;
x
++
)
{
dist_sums_row
[
x
]
-=
col_dist_sums_row
[
x
];
col_dist_sums_row
[
x
]
=
up_col_dist_sums_row
[
x
]
+
col_dist_sums_row
[
x
]
=
up_col_dist_sums_row
[
x
]
+
calcUpDownDist
(
a_up
,
a_down
,
a_up
,
a_down
,
b_up_ptr
[
start_bx
+
x
],
b_down_ptr
[
start_bx
+
x
]
);
dist_sums_row
[
x
]
+=
col_dist_sums_row
[
x
];
up_col_dist_sums_row
[
x
]
=
col_dist_sums_row
[
x
];
}
}
}
}
first_col_num
=
(
first_col_num
+
1
)
%
template_window_size_
;
}
// calc weights
int
weights_sum
=
0
;
int
estimation
[
3
];
int
estimation
[
3
];
for
(
int
channel_num
=
0
;
channel_num
<
channels_count_
;
channel_num
++
)
{
estimation
[
channel_num
]
=
0
;
}
...
...
@@ -277,12 +277,12 @@ void FastNlMeansMultiDenoisingInvoker<T>::operator() (const BlockedRange& range)
int
*
dist_sums_row
=
dist_sums
.
row_ptr
(
d
,
y
);
for
(
int
x
=
0
;
x
<
search_window_size_
;
x
++
)
{
int
almostAvgDist
=
int
almostAvgDist
=
dist_sums_row
[
x
]
>>
almost_template_window_size_sq_bin_shift
;
int
weight
=
almost_dist2weight
[
almostAvgDist
];
weights_sum
+=
weight
;
T
p
=
cur_row_ptr
[
border_size_
+
search_window_x
+
x
];
incWithWeight
(
estimation
,
weight
,
p
);
}
...
...
@@ -291,7 +291,7 @@ void FastNlMeansMultiDenoisingInvoker<T>::operator() (const BlockedRange& range)
if
(
weights_sum
>
0
)
{
for
(
int
channel_num
=
0
;
channel_num
<
channels_count_
;
channel_num
++
)
{
estimation
[
channel_num
]
=
estimation
[
channel_num
]
=
cvRound
(((
double
)
estimation
[
channel_num
])
/
weights_sum
);
}
...
...
@@ -307,9 +307,9 @@ void FastNlMeansMultiDenoisingInvoker<T>::operator() (const BlockedRange& range)
template
<
class
T
>
inline
void
FastNlMeansMultiDenoisingInvoker
<
T
>::
calcDistSumsForFirstElementInRow
(
int
i
,
Array3d
<
int
>&
dist_sums
,
Array4d
<
int
>&
col_dist_sums
,
int
i
,
Array3d
<
int
>&
dist_sums
,
Array4d
<
int
>&
col_dist_sums
,
Array4d
<
int
>&
up_col_dist_sums
)
const
{
int
j
=
0
;
...
...
@@ -328,7 +328,7 @@ inline void FastNlMeansMultiDenoisingInvoker<T>::calcDistSumsForFirstElementInRo
int
*
dist_sums_ptr
=
&
dist_sums
[
d
][
y
][
x
];
int
*
col_dist_sums_ptr
=
&
col_dist_sums
[
0
][
d
][
y
][
x
];
int
col_dist_sums_step
=
col_dist_sums
.
step_size
(
0
);
int
col_dist_sums_step
=
col_dist_sums
.
step_size
(
0
);
for
(
int
tx
=
-
template_window_half_size_
;
tx
<=
template_window_half_size_
;
tx
++
)
{
for
(
int
ty
=
-
template_window_half_size_
;
ty
<=
template_window_half_size_
;
ty
++
)
{
int
dist
=
calcDist
<
T
>
(
...
...
@@ -355,16 +355,16 @@ inline void FastNlMeansMultiDenoisingInvoker<T>::calcDistSumsForElementInFirstRo
int
i
,
int
j
,
int
first_col_num
,
Array3d
<
int
>&
dist_sums
,
Array4d
<
int
>&
col_dist_sums
,
Array3d
<
int
>&
dist_sums
,
Array4d
<
int
>&
col_dist_sums
,
Array4d
<
int
>&
up_col_dist_sums
)
const
{
int
ay
=
border_size_
+
i
;
int
ay
=
border_size_
+
i
;
int
ax
=
border_size_
+
j
+
template_window_half_size_
;
int
start_by
=
border_size_
+
i
-
search_window_half_size_
;
int
start_bx
=
border_size_
+
j
-
search_window_half_size_
+
template_window_half_size_
;
int
new_last_col_num
=
first_col_num
;
for
(
int
d
=
0
;
d
<
temporal_window_size_
;
d
++
)
{
...
...
@@ -372,19 +372,19 @@ inline void FastNlMeansMultiDenoisingInvoker<T>::calcDistSumsForElementInFirstRo
for
(
int
y
=
0
;
y
<
search_window_size_
;
y
++
)
{
for
(
int
x
=
0
;
x
<
search_window_size_
;
x
++
)
{
dist_sums
[
d
][
y
][
x
]
-=
col_dist_sums
[
first_col_num
][
d
][
y
][
x
];
col_dist_sums
[
new_last_col_num
][
d
][
y
][
x
]
=
0
;
int
by
=
start_by
+
y
;
col_dist_sums
[
new_last_col_num
][
d
][
y
][
x
]
=
0
;
int
by
=
start_by
+
y
;
int
bx
=
start_bx
+
x
;
int
*
col_dist_sums_ptr
=
&
col_dist_sums
[
new_last_col_num
][
d
][
y
][
x
];
for
(
int
ty
=
-
template_window_half_size_
;
ty
<=
template_window_half_size_
;
ty
++
)
{
*
col_dist_sums_ptr
+=
calcDist
<
T
>
(
main_extended_src_
.
at
<
T
>
(
ay
+
ty
,
ax
),
main_extended_src_
.
at
<
T
>
(
ay
+
ty
,
ax
),
cur_extended_src
.
at
<
T
>
(
by
+
ty
,
bx
)
);
}
}
dist_sums
[
d
][
y
][
x
]
+=
col_dist_sums
[
new_last_col_num
][
d
][
y
][
x
];
...
...
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