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