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
f2afe645
Commit
f2afe645
authored
Jun 17, 2013
by
Alex Leontiev
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Starting implement simplex algorithm.
parent
47ce461d
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
47 additions
and
2151 deletions
+47
-2151
CMakeLists.txt
modules/optim/CMakeLists.txt
+2
-2
arrays.hpp
modules/optim/src/arrays.hpp
+0
-161
denoising.cpp
modules/optim/src/denoising.cpp
+0
-242
fast_nlmeans_denoising_invoker.hpp
modules/optim/src/fast_nlmeans_denoising_invoker.hpp
+0
-334
fast_nlmeans_denoising_invoker_commons.hpp
modules/optim/src/fast_nlmeans_denoising_invoker_commons.hpp
+0
-115
fast_nlmeans_multi_denoising_invoker.hpp
modules/optim/src/fast_nlmeans_multi_denoising_invoker.hpp
+0
-383
inpaint.cpp
modules/optim/src/inpaint.cpp
+0
-817
lpsolver.cpp
modules/optim/src/lpsolver.cpp
+45
-0
precomp.cpp
modules/optim/src/precomp.cpp
+0
-44
precomp.hpp
modules/optim/src/precomp.hpp
+0
-53
No files found.
modules/optim/CMakeLists.txt
View file @
f2afe645
set
(
the_description
"
Computational Photography
"
)
ocv_define_module
(
photo opencv_imgproc
)
set
(
the_description
"
Generic optimization
"
)
ocv_define_module
(
optim
)
modules/optim/src/arrays.hpp
deleted
100644 → 0
View file @
47ce461d
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective icvers.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef __OPENCV_DENOISING_ARRAYS_HPP__
#define __OPENCV_DENOISING_ARRAYS_HPP__
template
<
class
T
>
struct
Array2d
{
T
*
a
;
int
n1
,
n2
;
bool
needToDeallocArray
;
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
std
::
exception
();
}
}
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
)
{
a
=
new
T
[
n1
*
n2
];
}
~
Array2d
()
{
if
(
needToDeallocArray
)
{
delete
[]
a
;
}
}
T
*
operator
[]
(
int
i
)
{
return
a
+
i
*
n2
;
}
inline
T
*
row_ptr
(
int
i
)
{
return
(
*
this
)[
i
];
}
};
template
<
class
T
>
struct
Array3d
{
T
*
a
;
int
n1
,
n2
,
n3
;
bool
needToDeallocArray
;
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
)
{
a
=
new
T
[
n1
*
n2
*
n3
];
}
~
Array3d
()
{
if
(
needToDeallocArray
)
{
delete
[]
a
;
}
}
Array2d
<
T
>
operator
[]
(
int
i
)
{
Array2d
<
T
>
array2d
(
a
+
i
*
n2
*
n3
,
n2
,
n3
);
return
array2d
;
}
inline
T
*
row_ptr
(
int
i1
,
int
i2
)
{
return
a
+
i1
*
n2
*
n3
+
i2
*
n3
;
}
};
template
<
class
T
>
struct
Array4d
{
T
*
a
;
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
;
}
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
();
}
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
();
}
~
Array4d
()
{
if
(
needToDeallocArray
)
{
delete
[]
a
;
}
}
Array3d
<
T
>
operator
[]
(
int
i
)
{
Array3d
<
T
>
array3d
(
a
+
i
*
n2
*
n3
*
n4
,
n2
,
n3
,
n4
);
return
array3d
;
}
inline
T
*
row_ptr
(
int
i1
,
int
i2
,
int
i3
)
{
return
a
+
i1
*
n2
*
n3
*
n4
+
i2
*
n3
*
n4
+
i3
*
n4
;
}
inline
int
step_size
(
int
dimension
)
{
return
steps
[
dimension
];
}
};
#endif
modules/optim/src/denoising.cpp
deleted
100644 → 0
View file @
47ce461d
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective icvers.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "precomp.hpp"
#include "opencv2/photo.hpp"
#include "opencv2/imgproc.hpp"
#include "fast_nlmeans_denoising_invoker.hpp"
#include "fast_nlmeans_multi_denoising_invoker.hpp"
void
cv
::
fastNlMeansDenoising
(
InputArray
_src
,
OutputArray
_dst
,
float
h
,
int
templateWindowSize
,
int
searchWindowSize
)
{
Mat
src
=
_src
.
getMat
();
_dst
.
create
(
src
.
size
(),
src
.
type
());
Mat
dst
=
_dst
.
getMat
();
#ifdef HAVE_TEGRA_OPTIMIZATION
if
(
tegra
::
fastNlMeansDenoising
(
src
,
dst
,
h
,
templateWindowSize
,
searchWindowSize
))
return
;
#endif
switch
(
src
.
type
())
{
case
CV_8U
:
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
),
FastNlMeansDenoisingInvoker
<
cv
::
Vec2b
>
(
src
,
dst
,
templateWindowSize
,
searchWindowSize
,
h
));
break
;
case
CV_8UC3
:
parallel_for
(
cv
::
BlockedRange
(
0
,
src
.
rows
),
FastNlMeansDenoisingInvoker
<
cv
::
Vec3b
>
(
src
,
dst
,
templateWindowSize
,
searchWindowSize
,
h
));
break
;
default
:
CV_Error
(
Error
::
StsBadArg
,
"Unsupported image format! Only CV_8UC1, CV_8UC2 and CV_8UC3 are supported"
);
}
}
void
cv
::
fastNlMeansDenoisingColored
(
InputArray
_src
,
OutputArray
_dst
,
float
h
,
float
hForColorComponents
,
int
templateWindowSize
,
int
searchWindowSize
)
{
Mat
src
=
_src
.
getMat
();
_dst
.
create
(
src
.
size
(),
src
.
type
());
Mat
dst
=
_dst
.
getMat
();
if
(
src
.
type
()
!=
CV_8UC3
)
{
CV_Error
(
Error
::
StsBadArg
,
"Type of input image should be CV_8UC3!"
);
return
;
}
Mat
src_lab
;
cvtColor
(
src
,
src_lab
,
COLOR_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
,
h
,
templateWindowSize
,
searchWindowSize
);
fastNlMeansDenoising
(
ab
,
ab
,
hForColorComponents
,
templateWindowSize
,
searchWindowSize
);
Mat
l_ab_denoised
[]
=
{
l
,
ab
};
Mat
dst_lab
(
src
.
size
(),
src
.
type
());
mixChannels
(
l_ab_denoised
,
2
,
&
dst_lab
,
1
,
from_to
,
3
);
cvtColor
(
dst_lab
,
dst
,
COLOR_Lab2LBGR
);
}
static
void
fastNlMeansDenoisingMultiCheckPreconditions
(
const
std
::
vector
<
Mat
>&
srcImgs
,
int
imgToDenoiseIndex
,
int
temporalWindowSize
,
int
templateWindowSize
,
int
searchWindowSize
)
{
int
src_imgs_size
=
(
int
)
srcImgs
.
size
();
if
(
src_imgs_size
==
0
)
{
CV_Error
(
Error
::
StsBadArg
,
"Input images vector should not be empty!"
);
}
if
(
temporalWindowSize
%
2
==
0
||
searchWindowSize
%
2
==
0
||
templateWindowSize
%
2
==
0
)
{
CV_Error
(
Error
::
StsBadArg
,
"All windows sizes should be odd!"
);
}
int
temporalWindowHalfSize
=
temporalWindowSize
/
2
;
if
(
imgToDenoiseIndex
-
temporalWindowHalfSize
<
0
||
imgToDenoiseIndex
+
temporalWindowHalfSize
>=
src_imgs_size
)
{
CV_Error
(
Error
::
StsBadArg
,
"imgToDenoiseIndex and temporalWindowSize "
"should be choosen corresponding srcImgs size!"
);
}
for
(
int
i
=
1
;
i
<
src_imgs_size
;
i
++
)
{
if
(
srcImgs
[
0
].
size
()
!=
srcImgs
[
i
].
size
()
||
srcImgs
[
0
].
type
()
!=
srcImgs
[
i
].
type
())
{
CV_Error
(
Error
::
StsBadArg
,
"Input images should have the same size and type!"
);
}
}
}
void
cv
::
fastNlMeansDenoisingMulti
(
InputArrayOfArrays
_srcImgs
,
OutputArray
_dst
,
int
imgToDenoiseIndex
,
int
temporalWindowSize
,
float
h
,
int
templateWindowSize
,
int
searchWindowSize
)
{
std
::
vector
<
Mat
>
srcImgs
;
_srcImgs
.
getMatVector
(
srcImgs
);
fastNlMeansDenoisingMultiCheckPreconditions
(
srcImgs
,
imgToDenoiseIndex
,
temporalWindowSize
,
templateWindowSize
,
searchWindowSize
);
_dst
.
create
(
srcImgs
[
0
].
size
(),
srcImgs
[
0
].
type
());
Mat
dst
=
_dst
.
getMat
();
switch
(
srcImgs
[
0
].
type
())
{
case
CV_8U
:
parallel_for
(
cv
::
BlockedRange
(
0
,
srcImgs
[
0
].
rows
),
FastNlMeansMultiDenoisingInvoker
<
uchar
>
(
srcImgs
,
imgToDenoiseIndex
,
temporalWindowSize
,
dst
,
templateWindowSize
,
searchWindowSize
,
h
));
break
;
case
CV_8UC2
:
parallel_for
(
cv
::
BlockedRange
(
0
,
srcImgs
[
0
].
rows
),
FastNlMeansMultiDenoisingInvoker
<
cv
::
Vec2b
>
(
srcImgs
,
imgToDenoiseIndex
,
temporalWindowSize
,
dst
,
templateWindowSize
,
searchWindowSize
,
h
));
break
;
case
CV_8UC3
:
parallel_for
(
cv
::
BlockedRange
(
0
,
srcImgs
[
0
].
rows
),
FastNlMeansMultiDenoisingInvoker
<
cv
::
Vec3b
>
(
srcImgs
,
imgToDenoiseIndex
,
temporalWindowSize
,
dst
,
templateWindowSize
,
searchWindowSize
,
h
));
break
;
default
:
CV_Error
(
Error
::
StsBadArg
,
"Unsupported matrix format! Only uchar, Vec2b, Vec3b are supported"
);
}
}
void
cv
::
fastNlMeansDenoisingColoredMulti
(
InputArrayOfArrays
_srcImgs
,
OutputArray
_dst
,
int
imgToDenoiseIndex
,
int
temporalWindowSize
,
float
h
,
float
hForColorComponents
,
int
templateWindowSize
,
int
searchWindowSize
)
{
std
::
vector
<
Mat
>
srcImgs
;
_srcImgs
.
getMatVector
(
srcImgs
);
fastNlMeansDenoisingMultiCheckPreconditions
(
srcImgs
,
imgToDenoiseIndex
,
temporalWindowSize
,
templateWindowSize
,
searchWindowSize
);
_dst
.
create
(
srcImgs
[
0
].
size
(),
srcImgs
[
0
].
type
());
Mat
dst
=
_dst
.
getMat
();
int
src_imgs_size
=
(
int
)
srcImgs
.
size
();
if
(
srcImgs
[
0
].
type
()
!=
CV_8UC3
)
{
CV_Error
(
Error
::
StsBadArg
,
"Type of input images should be CV_8UC3!"
);
return
;
}
int
from_to
[]
=
{
0
,
0
,
1
,
1
,
2
,
2
};
// TODO convert only required images
std
::
vector
<
Mat
>
src_lab
(
src_imgs_size
);
std
::
vector
<
Mat
>
l
(
src_imgs_size
);
std
::
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
],
COLOR_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
,
dst_l
,
imgToDenoiseIndex
,
temporalWindowSize
,
h
,
templateWindowSize
,
searchWindowSize
);
fastNlMeansDenoisingMulti
(
ab
,
dst_ab
,
imgToDenoiseIndex
,
temporalWindowSize
,
hForColorComponents
,
templateWindowSize
,
searchWindowSize
);
Mat
l_ab_denoised
[]
=
{
dst_l
,
dst_ab
};
Mat
dst_lab
(
srcImgs
[
0
].
size
(),
srcImgs
[
0
].
type
());
mixChannels
(
l_ab_denoised
,
2
,
&
dst_lab
,
1
,
from_to
,
3
);
cvtColor
(
dst_lab
,
dst
,
COLOR_Lab2LBGR
);
}
modules/optim/src/fast_nlmeans_denoising_invoker.hpp
deleted
100644 → 0
View file @
47ce461d
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective icvers.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef __OPENCV_FAST_NLMEANS_DENOISING_INVOKER_HPP__
#define __OPENCV_FAST_NLMEANS_DENOISING_INVOKER_HPP__
#include "precomp.hpp"
#include <limits>
#include "fast_nlmeans_denoising_invoker_commons.hpp"
#include "arrays.hpp"
using
namespace
cv
;
template
<
typename
T
>
struct
FastNlMeansDenoisingInvoker
{
public
:
FastNlMeansDenoisingInvoker
(
const
Mat
&
src
,
Mat
&
dst
,
int
template_window_size
,
int
search_window_size
,
const
float
h
);
void
operator
()
(
const
BlockedRange
&
range
)
const
;
private
:
void
operator
=
(
const
FastNlMeansDenoisingInvoker
&
);
const
Mat
&
src_
;
Mat
&
dst_
;
Mat
extended_src_
;
int
border_size_
;
int
template_window_size_
;
int
search_window_size_
;
int
template_window_half_size_
;
int
search_window_half_size_
;
int
fixed_point_mult_
;
int
almost_template_window_size_sq_bin_shift_
;
std
::
vector
<
int
>
almost_dist2weight_
;
void
calcDistSumsForFirstElementInRow
(
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
first_col_num
,
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
float
h
)
:
src_
(
src
),
dst_
(
dst
)
{
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
;
border_size_
=
search_window_half_size_
+
template_window_half_size_
;
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
;
fixed_point_mult_
=
std
::
numeric_limits
<
int
>::
max
()
/
max_estimate_sum_value
;
// 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_
=
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
=
255
*
255
*
sizeof
(
T
);
int
almost_max_dist
=
(
int
)
(
max_dist
/
almost_dist2actual_dist_multiplier
+
1
);
almost_dist2weight_
.
resize
(
almost_max_dist
);
const
double
WEIGHT_THRESHOLD
=
0.001
;
for
(
int
almost_dist
=
0
;
almost_dist
<
almost_max_dist
;
almost_dist
++
)
{
double
dist
=
almost_dist
*
almost_dist2actual_dist_multiplier
;
int
weight
=
cvRound
(
fixed_point_mult_
*
std
::
exp
(
-
dist
/
(
h
*
h
*
sizeof
(
T
))));
if
(
weight
<
WEIGHT_THRESHOLD
*
fixed_point_mult_
)
weight
=
0
;
almost_dist2weight_
[
almost_dist
]
=
weight
;
}
CV_Assert
(
almost_dist2weight_
[
0
]
==
fixed_point_mult_
);
// additional optimization init end
if
(
dst_
.
empty
())
{
dst_
=
Mat
::
zeros
(
src_
.
size
(),
src_
.
type
());
}
}
template
<
class
T
>
void
FastNlMeansDenoisingInvoker
<
T
>::
operator
()
(
const
BlockedRange
&
range
)
const
{
int
row_from
=
range
.
begin
();
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_
);
for
(
int
i
=
row_from
;
i
<=
row_to
;
i
++
)
{
for
(
int
j
=
0
;
j
<
src_
.
cols
;
j
++
)
{
int
search_window_y
=
i
-
search_window_half_size_
;
int
search_window_x
=
j
-
search_window_half_size_
;
// calc dist_sums
if
(
j
==
0
)
{
calcDistSumsForFirstElementInRow
(
i
,
dist_sums
,
col_dist_sums
,
up_col_dist_sums
);
first_col_num
=
0
;
}
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
);
}
else
{
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_
;
T
a_up
=
extended_src_
.
at
<
T
>
(
ay
-
template_window_half_size_
-
1
,
ax
);
T
a_down
=
extended_src_
.
at
<
T
>
(
ay
+
template_window_half_size_
,
ax
);
// copy class member to local variable for optimization
int
search_window_size
=
search_window_size_
;
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
=
extended_src_
.
ptr
<
T
>
(
start_by
-
template_window_half_size_
-
1
+
y
);
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
]
+
calcUpDownDist
(
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
];
for
(
size_t
channel_num
=
0
;
channel_num
<
sizeof
(
T
);
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
weight
=
almost_dist2weight_
[
almostAvgDist
];
weights_sum
+=
weight
;
T
p
=
cur_row_ptr
[
border_size_
+
search_window_x
+
x
];
incWithWeight
(
estimation
,
weight
,
p
);
}
}
for
(
size_t
channel_num
=
0
;
channel_num
<
sizeof
(
T
);
channel_num
++
)
estimation
[
channel_num
]
=
((
unsigned
)
estimation
[
channel_num
]
+
weights_sum
/
2
)
/
weights_sum
;
dst_
.
at
<
T
>
(
i
,
j
)
=
saturateCastFromArray
<
T
>
(
estimation
);
}
}
}
template
<
class
T
>
inline
void
FastNlMeansDenoisingInvoker
<
T
>::
calcDistSumsForFirstElementInRow
(
int
i
,
Array2d
<
int
>&
dist_sums
,
Array3d
<
int
>&
col_dist_sums
,
Array3d
<
int
>&
up_col_dist_sums
)
const
{
int
j
=
0
;
for
(
int
y
=
0
;
y
<
search_window_size_
;
y
++
)
{
for
(
int
x
=
0
;
x
<
search_window_size_
;
x
++
)
{
dist_sums
[
y
][
x
]
=
0
;
for
(
int
tx
=
0
;
tx
<
template_window_size_
;
tx
++
)
{
col_dist_sums
[
tx
][
y
][
x
]
=
0
;
}
int
start_y
=
i
+
y
-
search_window_half_size_
;
int
start_x
=
j
+
x
-
search_window_half_size_
;
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_
,
border_size_
+
i
+
ty
,
border_size_
+
j
+
tx
,
border_size_
+
start_y
+
ty
,
border_size_
+
start_x
+
tx
);
dist_sums
[
y
][
x
]
+=
dist
;
col_dist_sums
[
tx
+
template_window_half_size_
][
y
][
x
]
+=
dist
;
}
}
up_col_dist_sums
[
j
][
y
][
x
]
=
col_dist_sums
[
template_window_size_
-
1
][
y
][
x
];
}
}
}
template
<
class
T
>
inline
void
FastNlMeansDenoisingInvoker
<
T
>::
calcDistSumsForElementInFirstRow
(
int
i
,
int
j
,
int
first_col_num
,
Array2d
<
int
>&
dist_sums
,
Array3d
<
int
>&
col_dist_sums
,
Array3d
<
int
>&
up_col_dist_sums
)
const
{
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
;
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
]
+=
calcDist
<
T
>
(
extended_src_
,
ay
+
ty
,
ax
,
by
+
ty
,
bx
);
}
dist_sums
[
y
][
x
]
+=
col_dist_sums
[
new_last_col_num
][
y
][
x
];
up_col_dist_sums
[
j
][
y
][
x
]
=
col_dist_sums
[
new_last_col_num
][
y
][
x
];
}
}
}
#endif
modules/optim/src/fast_nlmeans_denoising_invoker_commons.hpp
deleted
100644 → 0
View file @
47ce461d
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective icvers.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef __OPENCV_FAST_NLMEANS_DENOISING_INVOKER_COMMONS_HPP__
#define __OPENCV_FAST_NLMEANS_DENOISING_INVOKER_COMMONS_HPP__
using
namespace
cv
;
template
<
typename
T
>
static
inline
int
calcDist
(
const
T
a
,
const
T
b
);
template
<>
inline
int
calcDist
(
const
uchar
a
,
const
uchar
b
)
{
return
(
a
-
b
)
*
(
a
-
b
);
}
template
<>
inline
int
calcDist
(
const
Vec2b
a
,
const
Vec2b
b
)
{
return
(
a
[
0
]
-
b
[
0
])
*
(
a
[
0
]
-
b
[
0
])
+
(
a
[
1
]
-
b
[
1
])
*
(
a
[
1
]
-
b
[
1
]);
}
template
<>
inline
int
calcDist
(
const
Vec3b
a
,
const
Vec3b
b
)
{
return
(
a
[
0
]
-
b
[
0
])
*
(
a
[
0
]
-
b
[
0
])
+
(
a
[
1
]
-
b
[
1
])
*
(
a
[
1
]
-
b
[
1
])
+
(
a
[
2
]
-
b
[
2
])
*
(
a
[
2
]
-
b
[
2
]);
}
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
);
return
calcDist
<
T
>
(
a
,
b
);
}
template
<
typename
T
>
static
inline
int
calcUpDownDist
(
T
a_up
,
T
a_down
,
T
b_up
,
T
b_down
)
{
return
calcDist
(
a_down
,
b_down
)
-
calcDist
(
a_up
,
b_up
);
}
template
<>
inline
int
calcUpDownDist
(
uchar
a_up
,
uchar
a_down
,
uchar
b_up
,
uchar
b_down
)
{
int
A
=
a_down
-
b_down
;
int
B
=
a_up
-
b_up
;
return
(
A
-
B
)
*
(
A
+
B
);
}
template
<
typename
T
>
static
inline
void
incWithWeight
(
int
*
estimation
,
int
weight
,
T
p
);
template
<>
inline
void
incWithWeight
(
int
*
estimation
,
int
weight
,
uchar
p
)
{
estimation
[
0
]
+=
weight
*
p
;
}
template
<>
inline
void
incWithWeight
(
int
*
estimation
,
int
weight
,
Vec2b
p
)
{
estimation
[
0
]
+=
weight
*
p
[
0
];
estimation
[
1
]
+=
weight
*
p
[
1
];
}
template
<>
inline
void
incWithWeight
(
int
*
estimation
,
int
weight
,
Vec3b
p
)
{
estimation
[
0
]
+=
weight
*
p
[
0
];
estimation
[
1
]
+=
weight
*
p
[
1
];
estimation
[
2
]
+=
weight
*
p
[
2
];
}
template
<
typename
T
>
static
inline
T
saturateCastFromArray
(
int
*
estimation
);
template
<>
inline
uchar
saturateCastFromArray
(
int
*
estimation
)
{
return
saturate_cast
<
uchar
>
(
estimation
[
0
]);
}
template
<>
inline
Vec2b
saturateCastFromArray
(
int
*
estimation
)
{
Vec2b
res
;
res
[
0
]
=
saturate_cast
<
uchar
>
(
estimation
[
0
]);
res
[
1
]
=
saturate_cast
<
uchar
>
(
estimation
[
1
]);
return
res
;
}
template
<>
inline
Vec3b
saturateCastFromArray
(
int
*
estimation
)
{
Vec3b
res
;
res
[
0
]
=
saturate_cast
<
uchar
>
(
estimation
[
0
]);
res
[
1
]
=
saturate_cast
<
uchar
>
(
estimation
[
1
]);
res
[
2
]
=
saturate_cast
<
uchar
>
(
estimation
[
2
]);
return
res
;
}
#endif
modules/optim/src/fast_nlmeans_multi_denoising_invoker.hpp
deleted
100644 → 0
View file @
47ce461d
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective icvers.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef __OPENCV_FAST_NLMEANS_MULTI_DENOISING_INVOKER_HPP__
#define __OPENCV_FAST_NLMEANS_MULTI_DENOISING_INVOKER_HPP__
#include "precomp.hpp"
#include <limits>
#include "fast_nlmeans_denoising_invoker_commons.hpp"
#include "arrays.hpp"
using
namespace
cv
;
template
<
typename
T
>
struct
FastNlMeansMultiDenoisingInvoker
{
public
:
FastNlMeansMultiDenoisingInvoker
(
const
std
::
vector
<
Mat
>&
srcImgs
,
int
imgToDenoiseIndex
,
int
temporalWindowSize
,
Mat
&
dst
,
int
template_window_size
,
int
search_window_size
,
const
float
h
);
void
operator
()
(
const
BlockedRange
&
range
)
const
;
private
:
void
operator
=
(
const
FastNlMeansMultiDenoisingInvoker
&
);
int
rows_
;
int
cols_
;
Mat
&
dst_
;
std
::
vector
<
Mat
>
extended_srcs_
;
Mat
main_extended_src_
;
int
border_size_
;
int
template_window_size_
;
int
search_window_size_
;
int
temporal_window_size_
;
int
template_window_half_size_
;
int
search_window_half_size_
;
int
temporal_window_half_size_
;
int
fixed_point_mult_
;
int
almost_template_window_size_sq_bin_shift
;
std
::
vector
<
int
>
almost_dist2weight
;
void
calcDistSumsForFirstElementInRow
(
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
first_col_num
,
Array3d
<
int
>&
dist_sums
,
Array4d
<
int
>&
col_dist_sums
,
Array4d
<
int
>&
up_col_dist_sums
)
const
;
};
template
<
class
T
>
FastNlMeansMultiDenoisingInvoker
<
T
>::
FastNlMeansMultiDenoisingInvoker
(
const
std
::
vector
<
Mat
>&
srcImgs
,
int
imgToDenoiseIndex
,
int
temporalWindowSize
,
cv
::
Mat
&
dst
,
int
template_window_size
,
int
search_window_size
,
const
float
h
)
:
dst_
(
dst
),
extended_srcs_
(
srcImgs
.
size
())
{
CV_Assert
(
srcImgs
.
size
()
>
0
);
CV_Assert
(
srcImgs
[
0
].
channels
()
==
sizeof
(
T
));
rows_
=
srcImgs
[
0
].
rows
;
cols_
=
srcImgs
[
0
].
cols
;
template_window_half_size_
=
template_window_size
/
2
;
search_window_half_size_
=
search_window_size
/
2
;
temporal_window_half_size_
=
temporalWindowSize
/
2
;
template_window_size_
=
template_window_half_size_
*
2
+
1
;
search_window_size_
=
search_window_half_size_
*
2
+
1
;
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
++
)
{
copyMakeBorder
(
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
=
temporal_window_size_
*
search_window_size_
*
search_window_size_
*
255
;
fixed_point_mult_
=
std
::
numeric_limits
<
int
>::
max
()
/
max_estimate_sum_value
;
// precalc weight for every possible l2 dist between blocks
// additional optimization of precalced weights to replace division(averaging) by binary shift
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
;
int
max_dist
=
255
*
255
*
sizeof
(
T
);
int
almost_max_dist
=
(
int
)
(
max_dist
/
almost_dist2actual_dist_multiplier
+
1
);
almost_dist2weight
.
resize
(
almost_max_dist
);
const
double
WEIGHT_THRESHOLD
=
0.001
;
for
(
int
almost_dist
=
0
;
almost_dist
<
almost_max_dist
;
almost_dist
++
)
{
double
dist
=
almost_dist
*
almost_dist2actual_dist_multiplier
;
int
weight
=
cvRound
(
fixed_point_mult_
*
std
::
exp
(
-
dist
/
(
h
*
h
*
sizeof
(
T
))));
if
(
weight
<
WEIGHT_THRESHOLD
*
fixed_point_mult_
)
{
weight
=
0
;
}
almost_dist2weight
[
almost_dist
]
=
weight
;
}
CV_Assert
(
almost_dist2weight
[
0
]
==
fixed_point_mult_
);
// additional optimization init end
if
(
dst_
.
empty
())
{
dst_
=
Mat
::
zeros
(
srcImgs
[
0
].
size
(),
srcImgs
[
0
].
type
());
}
}
template
<
class
T
>
void
FastNlMeansMultiDenoisingInvoker
<
T
>::
operator
()
(
const
BlockedRange
&
range
)
const
{
int
row_from
=
range
.
begin
();
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_
);
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_
;
int
search_window_x
=
j
-
search_window_half_size_
;
// calc dist_sums
if
(
j
==
0
)
{
calcDistSumsForFirstElementInRow
(
i
,
dist_sums
,
col_dist_sums
,
up_col_dist_sums
);
first_col_num
=
0
;
}
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
);
}
else
{
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_
;
T
a_up
=
main_extended_src_
.
at
<
T
>
(
ay
-
template_window_half_size_
-
1
,
ax
);
T
a_down
=
main_extended_src_
.
at
<
T
>
(
ay
+
template_window_half_size_
,
ax
);
// copy class member to local variable for optimization
int
search_window_size
=
search_window_size_
;
for
(
int
d
=
0
;
d
<
temporal_window_size_
;
d
++
)
{
Mat
cur_extended_src
=
extended_srcs_
[
d
];
Array2d
<
int
>
cur_dist_sums
=
dist_sums
[
d
];
Array2d
<
int
>
cur_col_dist_sums
=
col_dist_sums
[
first_col_num
][
d
];
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
=
cur_extended_src
.
ptr
<
T
>
(
start_by
-
template_window_half_size_
-
1
+
y
);
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
]
+
calcUpDownDist
(
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
];
for
(
size_t
channel_num
=
0
;
channel_num
<
sizeof
(
T
);
channel_num
++
)
{
estimation
[
channel_num
]
=
0
;
}
for
(
int
d
=
0
;
d
<
temporal_window_size_
;
d
++
)
{
const
Mat
&
esrc_d
=
extended_srcs_
[
d
];
for
(
int
y
=
0
;
y
<
search_window_size_
;
y
++
)
{
const
T
*
cur_row_ptr
=
esrc_d
.
ptr
<
T
>
(
border_size_
+
search_window_y
+
y
);
int
*
dist_sums_row
=
dist_sums
.
row_ptr
(
d
,
y
);
for
(
int
x
=
0
;
x
<
search_window_size_
;
x
++
)
{
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
);
}
}
}
for
(
size_t
channel_num
=
0
;
channel_num
<
sizeof
(
T
);
channel_num
++
)
estimation
[
channel_num
]
=
((
unsigned
)
estimation
[
channel_num
]
+
weights_sum
/
2
)
/
weights_sum
;
dst_
.
at
<
T
>
(
i
,
j
)
=
saturateCastFromArray
<
T
>
(
estimation
);
}
}
}
template
<
class
T
>
inline
void
FastNlMeansMultiDenoisingInvoker
<
T
>::
calcDistSumsForFirstElementInRow
(
int
i
,
Array3d
<
int
>&
dist_sums
,
Array4d
<
int
>&
col_dist_sums
,
Array4d
<
int
>&
up_col_dist_sums
)
const
{
int
j
=
0
;
for
(
int
d
=
0
;
d
<
temporal_window_size_
;
d
++
)
{
Mat
cur_extended_src
=
extended_srcs_
[
d
];
for
(
int
y
=
0
;
y
<
search_window_size_
;
y
++
)
{
for
(
int
x
=
0
;
x
<
search_window_size_
;
x
++
)
{
dist_sums
[
d
][
y
][
x
]
=
0
;
for
(
int
tx
=
0
;
tx
<
template_window_size_
;
tx
++
)
{
col_dist_sums
[
tx
][
d
][
y
][
x
]
=
0
;
}
int
start_y
=
i
+
y
-
search_window_half_size_
;
int
start_x
=
j
+
x
-
search_window_half_size_
;
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
);
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
>
(
main_extended_src_
.
at
<
T
>
(
border_size_
+
i
+
ty
,
border_size_
+
j
+
tx
),
cur_extended_src
.
at
<
T
>
(
border_size_
+
start_y
+
ty
,
border_size_
+
start_x
+
tx
)
);
*
dist_sums_ptr
+=
dist
;
*
col_dist_sums_ptr
+=
dist
;
}
col_dist_sums_ptr
+=
col_dist_sums_step
;
}
up_col_dist_sums
[
j
][
d
][
y
][
x
]
=
col_dist_sums
[
template_window_size_
-
1
][
d
][
y
][
x
];
}
}
}
}
template
<
class
T
>
inline
void
FastNlMeansMultiDenoisingInvoker
<
T
>::
calcDistSumsForElementInFirstRow
(
int
i
,
int
j
,
int
first_col_num
,
Array3d
<
int
>&
dist_sums
,
Array4d
<
int
>&
col_dist_sums
,
Array4d
<
int
>&
up_col_dist_sums
)
const
{
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
++
)
{
Mat
cur_extended_src
=
extended_srcs_
[
d
];
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
;
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
),
cur_extended_src
.
at
<
T
>
(
by
+
ty
,
bx
)
);
}
dist_sums
[
d
][
y
][
x
]
+=
col_dist_sums
[
new_last_col_num
][
d
][
y
][
x
];
up_col_dist_sums
[
j
][
d
][
y
][
x
]
=
col_dist_sums
[
new_last_col_num
][
d
][
y
][
x
];
}
}
}
}
#endif
modules/optim/src/inpaint.cpp
deleted
100644 → 0
View file @
47ce461d
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective icvers.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
/* ////////////////////////////////////////////////////////////////////
//
// Geometrical transforms on images and matrices: rotation, zoom etc.
//
// */
#include "precomp.hpp"
#include "opencv2/imgproc/imgproc_c.h"
#include "opencv2/photo/photo_c.h"
#undef CV_MAT_ELEM_PTR_FAST
#define CV_MAT_ELEM_PTR_FAST( mat, row, col, pix_size ) \
((mat).data.ptr + (size_t)(mat).step*(row) + (pix_size)*(col))
inline
float
min4
(
float
a
,
float
b
,
float
c
,
float
d
)
{
a
=
MIN
(
a
,
b
);
c
=
MIN
(
c
,
d
);
return
MIN
(
a
,
c
);
}
#define CV_MAT_3COLOR_ELEM(img,type,y,x,c) CV_MAT_ELEM(img,type,y,(x)*3+(c))
#define KNOWN 0 //known outside narrow band
#define BAND 1 //narrow band (known)
#define INSIDE 2 //unknown
#define CHANGE 3 //servise
typedef
struct
CvHeapElem
{
float
T
;
int
i
,
j
;
struct
CvHeapElem
*
prev
;
struct
CvHeapElem
*
next
;
}
CvHeapElem
;
class
CvPriorityQueueFloat
{
protected
:
CvHeapElem
*
mem
,
*
empty
,
*
head
,
*
tail
;
int
num
,
in
;
public
:
bool
Init
(
const
CvMat
*
f
)
{
int
i
,
j
;
for
(
i
=
num
=
0
;
i
<
f
->
rows
;
i
++
)
{
for
(
j
=
0
;
j
<
f
->
cols
;
j
++
)
num
+=
CV_MAT_ELEM
(
*
f
,
uchar
,
i
,
j
)
!=
0
;
}
if
(
num
<=
0
)
return
false
;
mem
=
(
CvHeapElem
*
)
cvAlloc
((
num
+
2
)
*
sizeof
(
CvHeapElem
));
if
(
mem
==
NULL
)
return
false
;
head
=
mem
;
head
->
i
=
head
->
j
=
-
1
;
head
->
prev
=
NULL
;
head
->
next
=
mem
+
1
;
head
->
T
=
-
FLT_MAX
;
empty
=
mem
+
1
;
for
(
i
=
1
;
i
<=
num
;
i
++
)
{
mem
[
i
].
prev
=
mem
+
i
-
1
;
mem
[
i
].
next
=
mem
+
i
+
1
;
mem
[
i
].
i
=
-
1
;
mem
[
i
].
T
=
FLT_MAX
;
}
tail
=
mem
+
i
;
tail
->
i
=
tail
->
j
=
-
1
;
tail
->
prev
=
mem
+
i
-
1
;
tail
->
next
=
NULL
;
tail
->
T
=
FLT_MAX
;
return
true
;
}
bool
Add
(
const
CvMat
*
f
)
{
int
i
,
j
;
for
(
i
=
0
;
i
<
f
->
rows
;
i
++
)
{
for
(
j
=
0
;
j
<
f
->
cols
;
j
++
)
{
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
i
,
j
)
!=
0
)
{
if
(
!
Push
(
i
,
j
,
0
))
return
false
;
}
}
}
return
true
;
}
bool
Push
(
int
i
,
int
j
,
float
T
)
{
CvHeapElem
*
tmp
=
empty
,
*
add
=
empty
;
if
(
empty
==
tail
)
return
false
;
while
(
tmp
->
prev
->
T
>
T
)
tmp
=
tmp
->
prev
;
if
(
tmp
!=
empty
)
{
add
->
prev
->
next
=
add
->
next
;
add
->
next
->
prev
=
add
->
prev
;
empty
=
add
->
next
;
add
->
prev
=
tmp
->
prev
;
add
->
next
=
tmp
;
add
->
prev
->
next
=
add
;
add
->
next
->
prev
=
add
;
}
else
{
empty
=
empty
->
next
;
}
add
->
i
=
i
;
add
->
j
=
j
;
add
->
T
=
T
;
in
++
;
// printf("push i %3d j %3d T %12.4e in %4d\n",i,j,T,in);
return
true
;
}
bool
Pop
(
int
*
i
,
int
*
j
)
{
CvHeapElem
*
tmp
=
head
->
next
;
if
(
empty
==
tmp
)
return
false
;
*
i
=
tmp
->
i
;
*
j
=
tmp
->
j
;
tmp
->
prev
->
next
=
tmp
->
next
;
tmp
->
next
->
prev
=
tmp
->
prev
;
tmp
->
prev
=
empty
->
prev
;
tmp
->
next
=
empty
;
tmp
->
prev
->
next
=
tmp
;
tmp
->
next
->
prev
=
tmp
;
empty
=
tmp
;
in
--
;
// printf("pop i %3d j %3d T %12.4e in %4d\n",tmp->i,tmp->j,tmp->T,in);
return
true
;
}
bool
Pop
(
int
*
i
,
int
*
j
,
float
*
T
)
{
CvHeapElem
*
tmp
=
head
->
next
;
if
(
empty
==
tmp
)
return
false
;
*
i
=
tmp
->
i
;
*
j
=
tmp
->
j
;
*
T
=
tmp
->
T
;
tmp
->
prev
->
next
=
tmp
->
next
;
tmp
->
next
->
prev
=
tmp
->
prev
;
tmp
->
prev
=
empty
->
prev
;
tmp
->
next
=
empty
;
tmp
->
prev
->
next
=
tmp
;
tmp
->
next
->
prev
=
tmp
;
empty
=
tmp
;
in
--
;
// printf("pop i %3d j %3d T %12.4e in %4d\n",tmp->i,tmp->j,tmp->T,in);
return
true
;
}
CvPriorityQueueFloat
(
void
)
{
num
=
in
=
0
;
mem
=
empty
=
head
=
tail
=
NULL
;
}
~
CvPriorityQueueFloat
(
void
)
{
cvFree
(
&
mem
);
}
};
inline
float
VectorScalMult
(
CvPoint2D32f
v1
,
CvPoint2D32f
v2
)
{
return
v1
.
x
*
v2
.
x
+
v1
.
y
*
v2
.
y
;
}
inline
float
VectorLength
(
CvPoint2D32f
v1
)
{
return
v1
.
x
*
v1
.
x
+
v1
.
y
*
v1
.
y
;
}
///////////////////////////////////////////////////////////////////////////////////////////
//HEAP::iterator Heap_Iterator;
//HEAP Heap;
static
float
FastMarching_solve
(
int
i1
,
int
j1
,
int
i2
,
int
j2
,
const
CvMat
*
f
,
const
CvMat
*
t
)
{
double
sol
,
a11
,
a22
,
m12
;
a11
=
CV_MAT_ELEM
(
*
t
,
float
,
i1
,
j1
);
a22
=
CV_MAT_ELEM
(
*
t
,
float
,
i2
,
j2
);
m12
=
MIN
(
a11
,
a22
);
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
i1
,
j1
)
!=
INSIDE
)
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
i2
,
j2
)
!=
INSIDE
)
if
(
fabs
(
a11
-
a22
)
>=
1.0
)
sol
=
1
+
m12
;
else
sol
=
(
a11
+
a22
+
sqrt
((
double
)(
2
-
(
a11
-
a22
)
*
(
a11
-
a22
))))
*
0.5
;
else
sol
=
1
+
a11
;
else
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
i2
,
j2
)
!=
INSIDE
)
sol
=
1
+
a22
;
else
sol
=
1
+
m12
;
return
(
float
)
sol
;
}
/////////////////////////////////////////////////////////////////////////////////////
static
void
icvCalcFMM
(
const
CvMat
*
f
,
CvMat
*
t
,
CvPriorityQueueFloat
*
Heap
,
bool
negate
)
{
int
i
,
j
,
ii
=
0
,
jj
=
0
,
q
;
float
dist
;
while
(
Heap
->
Pop
(
&
ii
,
&
jj
))
{
unsigned
known
=
(
negate
)
?
CHANGE
:
KNOWN
;
CV_MAT_ELEM
(
*
f
,
uchar
,
ii
,
jj
)
=
(
uchar
)
known
;
for
(
q
=
0
;
q
<
4
;
q
++
)
{
i
=
0
;
j
=
0
;
if
(
q
==
0
)
{
i
=
ii
-
1
;
j
=
jj
;}
else
if
(
q
==
1
)
{
i
=
ii
;
j
=
jj
-
1
;}
else
if
(
q
==
2
)
{
i
=
ii
+
1
;
j
=
jj
;}
else
{
i
=
ii
;
j
=
jj
+
1
;}
if
((
i
<=
0
)
||
(
j
<=
0
)
||
(
i
>
f
->
rows
)
||
(
j
>
f
->
cols
))
continue
;
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
i
,
j
)
==
INSIDE
)
{
dist
=
min4
(
FastMarching_solve
(
i
-
1
,
j
,
i
,
j
-
1
,
f
,
t
),
FastMarching_solve
(
i
+
1
,
j
,
i
,
j
-
1
,
f
,
t
),
FastMarching_solve
(
i
-
1
,
j
,
i
,
j
+
1
,
f
,
t
),
FastMarching_solve
(
i
+
1
,
j
,
i
,
j
+
1
,
f
,
t
));
CV_MAT_ELEM
(
*
t
,
float
,
i
,
j
)
=
dist
;
CV_MAT_ELEM
(
*
f
,
uchar
,
i
,
j
)
=
BAND
;
Heap
->
Push
(
i
,
j
,
dist
);
}
}
}
if
(
negate
)
{
for
(
i
=
0
;
i
<
f
->
rows
;
i
++
)
{
for
(
j
=
0
;
j
<
f
->
cols
;
j
++
)
{
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
i
,
j
)
==
CHANGE
)
{
CV_MAT_ELEM
(
*
f
,
uchar
,
i
,
j
)
=
KNOWN
;
CV_MAT_ELEM
(
*
t
,
float
,
i
,
j
)
=
-
CV_MAT_ELEM
(
*
t
,
float
,
i
,
j
);
}
}
}
}
}
static
void
icvTeleaInpaintFMM
(
const
CvMat
*
f
,
CvMat
*
t
,
CvMat
*
out
,
int
range
,
CvPriorityQueueFloat
*
Heap
)
{
int
i
=
0
,
j
=
0
,
ii
=
0
,
jj
=
0
,
k
,
l
,
q
,
color
=
0
;
float
dist
;
if
(
CV_MAT_CN
(
out
->
type
)
==
3
)
{
while
(
Heap
->
Pop
(
&
ii
,
&
jj
))
{
CV_MAT_ELEM
(
*
f
,
uchar
,
ii
,
jj
)
=
KNOWN
;
for
(
q
=
0
;
q
<
4
;
q
++
)
{
if
(
q
==
0
)
{
i
=
ii
-
1
;
j
=
jj
;}
else
if
(
q
==
1
)
{
i
=
ii
;
j
=
jj
-
1
;}
else
if
(
q
==
2
)
{
i
=
ii
+
1
;
j
=
jj
;}
else
if
(
q
==
3
)
{
i
=
ii
;
j
=
jj
+
1
;}
if
((
i
<=
1
)
||
(
j
<=
1
)
||
(
i
>
t
->
rows
-
1
)
||
(
j
>
t
->
cols
-
1
))
continue
;
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
i
,
j
)
==
INSIDE
)
{
dist
=
min4
(
FastMarching_solve
(
i
-
1
,
j
,
i
,
j
-
1
,
f
,
t
),
FastMarching_solve
(
i
+
1
,
j
,
i
,
j
-
1
,
f
,
t
),
FastMarching_solve
(
i
-
1
,
j
,
i
,
j
+
1
,
f
,
t
),
FastMarching_solve
(
i
+
1
,
j
,
i
,
j
+
1
,
f
,
t
));
CV_MAT_ELEM
(
*
t
,
float
,
i
,
j
)
=
dist
;
for
(
color
=
0
;
color
<=
2
;
color
++
)
{
CvPoint2D32f
gradI
,
gradT
,
r
;
float
Ia
=
0
,
Jx
=
0
,
Jy
=
0
,
s
=
1.0e-20
f
,
w
,
dst
,
lev
,
dir
,
sat
;
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
i
,
j
+
1
)
!=
INSIDE
)
{
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
i
,
j
-
1
)
!=
INSIDE
)
{
gradT
.
x
=
(
float
)((
CV_MAT_ELEM
(
*
t
,
float
,
i
,
j
+
1
)
-
CV_MAT_ELEM
(
*
t
,
float
,
i
,
j
-
1
)))
*
0.5
f
;
}
else
{
gradT
.
x
=
(
float
)((
CV_MAT_ELEM
(
*
t
,
float
,
i
,
j
+
1
)
-
CV_MAT_ELEM
(
*
t
,
float
,
i
,
j
)));
}
}
else
{
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
i
,
j
-
1
)
!=
INSIDE
)
{
gradT
.
x
=
(
float
)((
CV_MAT_ELEM
(
*
t
,
float
,
i
,
j
)
-
CV_MAT_ELEM
(
*
t
,
float
,
i
,
j
-
1
)));
}
else
{
gradT
.
x
=
0
;
}
}
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
i
+
1
,
j
)
!=
INSIDE
)
{
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
i
-
1
,
j
)
!=
INSIDE
)
{
gradT
.
y
=
(
float
)((
CV_MAT_ELEM
(
*
t
,
float
,
i
+
1
,
j
)
-
CV_MAT_ELEM
(
*
t
,
float
,
i
-
1
,
j
)))
*
0.5
f
;
}
else
{
gradT
.
y
=
(
float
)((
CV_MAT_ELEM
(
*
t
,
float
,
i
+
1
,
j
)
-
CV_MAT_ELEM
(
*
t
,
float
,
i
,
j
)));
}
}
else
{
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
i
-
1
,
j
)
!=
INSIDE
)
{
gradT
.
y
=
(
float
)((
CV_MAT_ELEM
(
*
t
,
float
,
i
,
j
)
-
CV_MAT_ELEM
(
*
t
,
float
,
i
-
1
,
j
)));
}
else
{
gradT
.
y
=
0
;
}
}
for
(
k
=
i
-
range
;
k
<=
i
+
range
;
k
++
)
{
int
km
=
k
-
1
+
(
k
==
1
),
kp
=
k
-
1
-
(
k
==
t
->
rows
-
2
);
for
(
l
=
j
-
range
;
l
<=
j
+
range
;
l
++
)
{
int
lm
=
l
-
1
+
(
l
==
1
),
lp
=
l
-
1
-
(
l
==
t
->
cols
-
2
);
if
(
k
>
0
&&
l
>
0
&&
k
<
t
->
rows
-
1
&&
l
<
t
->
cols
-
1
)
{
if
((
CV_MAT_ELEM
(
*
f
,
uchar
,
k
,
l
)
!=
INSIDE
)
&&
((
l
-
j
)
*
(
l
-
j
)
+
(
k
-
i
)
*
(
k
-
i
)
<=
range
*
range
))
{
r
.
y
=
(
float
)(
i
-
k
);
r
.
x
=
(
float
)(
j
-
l
);
dst
=
(
float
)(
1.
/
(
VectorLength
(
r
)
*
sqrt
((
double
)
VectorLength
(
r
))));
lev
=
(
float
)(
1.
/
(
1
+
fabs
(
CV_MAT_ELEM
(
*
t
,
float
,
k
,
l
)
-
CV_MAT_ELEM
(
*
t
,
float
,
i
,
j
))));
dir
=
VectorScalMult
(
r
,
gradT
);
if
(
fabs
(
dir
)
<=
0.01
)
dir
=
0.000001
f
;
w
=
(
float
)
fabs
(
dst
*
lev
*
dir
);
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
k
,
l
+
1
)
!=
INSIDE
)
{
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
k
,
l
-
1
)
!=
INSIDE
)
{
gradI
.
x
=
(
float
)((
CV_MAT_3COLOR_ELEM
(
*
out
,
uchar
,
km
,
lp
+
1
,
color
)
-
CV_MAT_3COLOR_ELEM
(
*
out
,
uchar
,
km
,
lm
-
1
,
color
)))
*
2.0
f
;
}
else
{
gradI
.
x
=
(
float
)((
CV_MAT_3COLOR_ELEM
(
*
out
,
uchar
,
km
,
lp
+
1
,
color
)
-
CV_MAT_3COLOR_ELEM
(
*
out
,
uchar
,
km
,
lm
,
color
)));
}
}
else
{
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
k
,
l
-
1
)
!=
INSIDE
)
{
gradI
.
x
=
(
float
)((
CV_MAT_3COLOR_ELEM
(
*
out
,
uchar
,
km
,
lp
,
color
)
-
CV_MAT_3COLOR_ELEM
(
*
out
,
uchar
,
km
,
lm
-
1
,
color
)));
}
else
{
gradI
.
x
=
0
;
}
}
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
k
+
1
,
l
)
!=
INSIDE
)
{
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
k
-
1
,
l
)
!=
INSIDE
)
{
gradI
.
y
=
(
float
)((
CV_MAT_3COLOR_ELEM
(
*
out
,
uchar
,
kp
+
1
,
lm
,
color
)
-
CV_MAT_3COLOR_ELEM
(
*
out
,
uchar
,
km
-
1
,
lm
,
color
)))
*
2.0
f
;
}
else
{
gradI
.
y
=
(
float
)((
CV_MAT_3COLOR_ELEM
(
*
out
,
uchar
,
kp
+
1
,
lm
,
color
)
-
CV_MAT_3COLOR_ELEM
(
*
out
,
uchar
,
km
,
lm
,
color
)));
}
}
else
{
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
k
-
1
,
l
)
!=
INSIDE
)
{
gradI
.
y
=
(
float
)((
CV_MAT_3COLOR_ELEM
(
*
out
,
uchar
,
kp
,
lm
,
color
)
-
CV_MAT_3COLOR_ELEM
(
*
out
,
uchar
,
km
-
1
,
lm
,
color
)));
}
else
{
gradI
.
y
=
0
;
}
}
Ia
+=
(
float
)
w
*
(
float
)(
CV_MAT_3COLOR_ELEM
(
*
out
,
uchar
,
km
,
lm
,
color
));
Jx
-=
(
float
)
w
*
(
float
)(
gradI
.
x
*
r
.
x
);
Jy
-=
(
float
)
w
*
(
float
)(
gradI
.
y
*
r
.
y
);
s
+=
w
;
}
}
}
}
sat
=
(
float
)((
Ia
/
s
+
(
Jx
+
Jy
)
/
(
sqrt
(
Jx
*
Jx
+
Jy
*
Jy
)
+
1.0e-20
f
)
+
0.5
f
));
{
CV_MAT_3COLOR_ELEM
(
*
out
,
uchar
,
i
-
1
,
j
-
1
,
color
)
=
cv
::
saturate_cast
<
uchar
>
(
sat
);
}
}
CV_MAT_ELEM
(
*
f
,
uchar
,
i
,
j
)
=
BAND
;
Heap
->
Push
(
i
,
j
,
dist
);
}
}
}
}
else
if
(
CV_MAT_CN
(
out
->
type
)
==
1
)
{
while
(
Heap
->
Pop
(
&
ii
,
&
jj
))
{
CV_MAT_ELEM
(
*
f
,
uchar
,
ii
,
jj
)
=
KNOWN
;
for
(
q
=
0
;
q
<
4
;
q
++
)
{
if
(
q
==
0
)
{
i
=
ii
-
1
;
j
=
jj
;}
else
if
(
q
==
1
)
{
i
=
ii
;
j
=
jj
-
1
;}
else
if
(
q
==
2
)
{
i
=
ii
+
1
;
j
=
jj
;}
else
if
(
q
==
3
)
{
i
=
ii
;
j
=
jj
+
1
;}
if
((
i
<=
1
)
||
(
j
<=
1
)
||
(
i
>
t
->
rows
-
1
)
||
(
j
>
t
->
cols
-
1
))
continue
;
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
i
,
j
)
==
INSIDE
)
{
dist
=
min4
(
FastMarching_solve
(
i
-
1
,
j
,
i
,
j
-
1
,
f
,
t
),
FastMarching_solve
(
i
+
1
,
j
,
i
,
j
-
1
,
f
,
t
),
FastMarching_solve
(
i
-
1
,
j
,
i
,
j
+
1
,
f
,
t
),
FastMarching_solve
(
i
+
1
,
j
,
i
,
j
+
1
,
f
,
t
));
CV_MAT_ELEM
(
*
t
,
float
,
i
,
j
)
=
dist
;
for
(
color
=
0
;
color
<=
0
;
color
++
)
{
CvPoint2D32f
gradI
,
gradT
,
r
;
float
Ia
=
0
,
Jx
=
0
,
Jy
=
0
,
s
=
1.0e-20
f
,
w
,
dst
,
lev
,
dir
,
sat
;
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
i
,
j
+
1
)
!=
INSIDE
)
{
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
i
,
j
-
1
)
!=
INSIDE
)
{
gradT
.
x
=
(
float
)((
CV_MAT_ELEM
(
*
t
,
float
,
i
,
j
+
1
)
-
CV_MAT_ELEM
(
*
t
,
float
,
i
,
j
-
1
)))
*
0.5
f
;
}
else
{
gradT
.
x
=
(
float
)((
CV_MAT_ELEM
(
*
t
,
float
,
i
,
j
+
1
)
-
CV_MAT_ELEM
(
*
t
,
float
,
i
,
j
)));
}
}
else
{
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
i
,
j
-
1
)
!=
INSIDE
)
{
gradT
.
x
=
(
float
)((
CV_MAT_ELEM
(
*
t
,
float
,
i
,
j
)
-
CV_MAT_ELEM
(
*
t
,
float
,
i
,
j
-
1
)));
}
else
{
gradT
.
x
=
0
;
}
}
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
i
+
1
,
j
)
!=
INSIDE
)
{
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
i
-
1
,
j
)
!=
INSIDE
)
{
gradT
.
y
=
(
float
)((
CV_MAT_ELEM
(
*
t
,
float
,
i
+
1
,
j
)
-
CV_MAT_ELEM
(
*
t
,
float
,
i
-
1
,
j
)))
*
0.5
f
;
}
else
{
gradT
.
y
=
(
float
)((
CV_MAT_ELEM
(
*
t
,
float
,
i
+
1
,
j
)
-
CV_MAT_ELEM
(
*
t
,
float
,
i
,
j
)));
}
}
else
{
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
i
-
1
,
j
)
!=
INSIDE
)
{
gradT
.
y
=
(
float
)((
CV_MAT_ELEM
(
*
t
,
float
,
i
,
j
)
-
CV_MAT_ELEM
(
*
t
,
float
,
i
-
1
,
j
)));
}
else
{
gradT
.
y
=
0
;
}
}
for
(
k
=
i
-
range
;
k
<=
i
+
range
;
k
++
)
{
int
km
=
k
-
1
+
(
k
==
1
),
kp
=
k
-
1
-
(
k
==
t
->
rows
-
2
);
for
(
l
=
j
-
range
;
l
<=
j
+
range
;
l
++
)
{
int
lm
=
l
-
1
+
(
l
==
1
),
lp
=
l
-
1
-
(
l
==
t
->
cols
-
2
);
if
(
k
>
0
&&
l
>
0
&&
k
<
t
->
rows
-
1
&&
l
<
t
->
cols
-
1
)
{
if
((
CV_MAT_ELEM
(
*
f
,
uchar
,
k
,
l
)
!=
INSIDE
)
&&
((
l
-
j
)
*
(
l
-
j
)
+
(
k
-
i
)
*
(
k
-
i
)
<=
range
*
range
))
{
r
.
y
=
(
float
)(
i
-
k
);
r
.
x
=
(
float
)(
j
-
l
);
dst
=
(
float
)(
1.
/
(
VectorLength
(
r
)
*
sqrt
(
VectorLength
(
r
))));
lev
=
(
float
)(
1.
/
(
1
+
fabs
(
CV_MAT_ELEM
(
*
t
,
float
,
k
,
l
)
-
CV_MAT_ELEM
(
*
t
,
float
,
i
,
j
))));
dir
=
VectorScalMult
(
r
,
gradT
);
if
(
fabs
(
dir
)
<=
0.01
)
dir
=
0.000001
f
;
w
=
(
float
)
fabs
(
dst
*
lev
*
dir
);
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
k
,
l
+
1
)
!=
INSIDE
)
{
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
k
,
l
-
1
)
!=
INSIDE
)
{
gradI
.
x
=
(
float
)((
CV_MAT_ELEM
(
*
out
,
uchar
,
km
,
lp
+
1
)
-
CV_MAT_ELEM
(
*
out
,
uchar
,
km
,
lm
-
1
)))
*
2.0
f
;
}
else
{
gradI
.
x
=
(
float
)((
CV_MAT_ELEM
(
*
out
,
uchar
,
km
,
lp
+
1
)
-
CV_MAT_ELEM
(
*
out
,
uchar
,
km
,
lm
)));
}
}
else
{
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
k
,
l
-
1
)
!=
INSIDE
)
{
gradI
.
x
=
(
float
)((
CV_MAT_ELEM
(
*
out
,
uchar
,
km
,
lp
)
-
CV_MAT_ELEM
(
*
out
,
uchar
,
km
,
lm
-
1
)));
}
else
{
gradI
.
x
=
0
;
}
}
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
k
+
1
,
l
)
!=
INSIDE
)
{
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
k
-
1
,
l
)
!=
INSIDE
)
{
gradI
.
y
=
(
float
)((
CV_MAT_ELEM
(
*
out
,
uchar
,
kp
+
1
,
lm
)
-
CV_MAT_ELEM
(
*
out
,
uchar
,
km
-
1
,
lm
)))
*
2.0
f
;
}
else
{
gradI
.
y
=
(
float
)((
CV_MAT_ELEM
(
*
out
,
uchar
,
kp
+
1
,
lm
)
-
CV_MAT_ELEM
(
*
out
,
uchar
,
km
,
lm
)));
}
}
else
{
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
k
-
1
,
l
)
!=
INSIDE
)
{
gradI
.
y
=
(
float
)((
CV_MAT_ELEM
(
*
out
,
uchar
,
kp
,
lm
)
-
CV_MAT_ELEM
(
*
out
,
uchar
,
km
-
1
,
lm
)));
}
else
{
gradI
.
y
=
0
;
}
}
Ia
+=
(
float
)
w
*
(
float
)(
CV_MAT_ELEM
(
*
out
,
uchar
,
km
,
lm
));
Jx
-=
(
float
)
w
*
(
float
)(
gradI
.
x
*
r
.
x
);
Jy
-=
(
float
)
w
*
(
float
)(
gradI
.
y
*
r
.
y
);
s
+=
w
;
}
}
}
}
sat
=
(
float
)((
Ia
/
s
+
(
Jx
+
Jy
)
/
(
sqrt
(
Jx
*
Jx
+
Jy
*
Jy
)
+
1.0e-20
f
)
+
0.5
f
));
{
CV_MAT_ELEM
(
*
out
,
uchar
,
i
-
1
,
j
-
1
)
=
cv
::
saturate_cast
<
uchar
>
(
sat
);
}
}
CV_MAT_ELEM
(
*
f
,
uchar
,
i
,
j
)
=
BAND
;
Heap
->
Push
(
i
,
j
,
dist
);
}
}
}
}
}
static
void
icvNSInpaintFMM
(
const
CvMat
*
f
,
CvMat
*
t
,
CvMat
*
out
,
int
range
,
CvPriorityQueueFloat
*
Heap
)
{
int
i
=
0
,
j
=
0
,
ii
=
0
,
jj
=
0
,
k
,
l
,
q
,
color
=
0
;
float
dist
;
if
(
CV_MAT_CN
(
out
->
type
)
==
3
)
{
while
(
Heap
->
Pop
(
&
ii
,
&
jj
))
{
CV_MAT_ELEM
(
*
f
,
uchar
,
ii
,
jj
)
=
KNOWN
;
for
(
q
=
0
;
q
<
4
;
q
++
)
{
if
(
q
==
0
)
{
i
=
ii
-
1
;
j
=
jj
;}
else
if
(
q
==
1
)
{
i
=
ii
;
j
=
jj
-
1
;}
else
if
(
q
==
2
)
{
i
=
ii
+
1
;
j
=
jj
;}
else
if
(
q
==
3
)
{
i
=
ii
;
j
=
jj
+
1
;}
if
((
i
<=
1
)
||
(
j
<=
1
)
||
(
i
>
t
->
rows
-
1
)
||
(
j
>
t
->
cols
-
1
))
continue
;
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
i
,
j
)
==
INSIDE
)
{
dist
=
min4
(
FastMarching_solve
(
i
-
1
,
j
,
i
,
j
-
1
,
f
,
t
),
FastMarching_solve
(
i
+
1
,
j
,
i
,
j
-
1
,
f
,
t
),
FastMarching_solve
(
i
-
1
,
j
,
i
,
j
+
1
,
f
,
t
),
FastMarching_solve
(
i
+
1
,
j
,
i
,
j
+
1
,
f
,
t
));
CV_MAT_ELEM
(
*
t
,
float
,
i
,
j
)
=
dist
;
for
(
color
=
0
;
color
<=
2
;
color
++
)
{
CvPoint2D32f
gradI
,
r
;
float
Ia
=
0
,
s
=
1.0e-20
f
,
w
,
dst
,
dir
;
for
(
k
=
i
-
range
;
k
<=
i
+
range
;
k
++
)
{
int
km
=
k
-
1
+
(
k
==
1
),
kp
=
k
-
1
-
(
k
==
f
->
rows
-
2
);
for
(
l
=
j
-
range
;
l
<=
j
+
range
;
l
++
)
{
int
lm
=
l
-
1
+
(
l
==
1
),
lp
=
l
-
1
-
(
l
==
f
->
cols
-
2
);
if
(
k
>
0
&&
l
>
0
&&
k
<
f
->
rows
-
1
&&
l
<
f
->
cols
-
1
)
{
if
((
CV_MAT_ELEM
(
*
f
,
uchar
,
k
,
l
)
!=
INSIDE
)
&&
((
l
-
j
)
*
(
l
-
j
)
+
(
k
-
i
)
*
(
k
-
i
)
<=
range
*
range
))
{
r
.
y
=
(
float
)(
k
-
i
);
r
.
x
=
(
float
)(
l
-
j
);
dst
=
1
/
(
VectorLength
(
r
)
*
VectorLength
(
r
)
+
1
);
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
k
+
1
,
l
)
!=
INSIDE
)
{
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
k
-
1
,
l
)
!=
INSIDE
)
{
gradI
.
x
=
(
float
)(
abs
(
CV_MAT_3COLOR_ELEM
(
*
out
,
uchar
,
kp
+
1
,
lm
,
color
)
-
CV_MAT_3COLOR_ELEM
(
*
out
,
uchar
,
kp
,
lm
,
color
))
+
abs
(
CV_MAT_3COLOR_ELEM
(
*
out
,
uchar
,
kp
,
lm
,
color
)
-
CV_MAT_3COLOR_ELEM
(
*
out
,
uchar
,
km
-
1
,
lm
,
color
)));
}
else
{
gradI
.
x
=
(
float
)(
abs
(
CV_MAT_3COLOR_ELEM
(
*
out
,
uchar
,
kp
+
1
,
lm
,
color
)
-
CV_MAT_3COLOR_ELEM
(
*
out
,
uchar
,
kp
,
lm
,
color
)))
*
2.0
f
;
}
}
else
{
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
k
-
1
,
l
)
!=
INSIDE
)
{
gradI
.
x
=
(
float
)(
abs
(
CV_MAT_3COLOR_ELEM
(
*
out
,
uchar
,
kp
,
lm
,
color
)
-
CV_MAT_3COLOR_ELEM
(
*
out
,
uchar
,
km
-
1
,
lm
,
color
)))
*
2.0
f
;
}
else
{
gradI
.
x
=
0
;
}
}
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
k
,
l
+
1
)
!=
INSIDE
)
{
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
k
,
l
-
1
)
!=
INSIDE
)
{
gradI
.
y
=
(
float
)(
abs
(
CV_MAT_3COLOR_ELEM
(
*
out
,
uchar
,
km
,
lp
+
1
,
color
)
-
CV_MAT_3COLOR_ELEM
(
*
out
,
uchar
,
km
,
lm
,
color
))
+
abs
(
CV_MAT_3COLOR_ELEM
(
*
out
,
uchar
,
km
,
lm
,
color
)
-
CV_MAT_3COLOR_ELEM
(
*
out
,
uchar
,
km
,
lm
-
1
,
color
)));
}
else
{
gradI
.
y
=
(
float
)(
abs
(
CV_MAT_3COLOR_ELEM
(
*
out
,
uchar
,
km
,
lp
+
1
,
color
)
-
CV_MAT_3COLOR_ELEM
(
*
out
,
uchar
,
km
,
lm
,
color
)))
*
2.0
f
;
}
}
else
{
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
k
,
l
-
1
)
!=
INSIDE
)
{
gradI
.
y
=
(
float
)(
abs
(
CV_MAT_3COLOR_ELEM
(
*
out
,
uchar
,
km
,
lm
,
color
)
-
CV_MAT_3COLOR_ELEM
(
*
out
,
uchar
,
km
,
lm
-
1
,
color
)))
*
2.0
f
;
}
else
{
gradI
.
y
=
0
;
}
}
gradI
.
x
=-
gradI
.
x
;
dir
=
VectorScalMult
(
r
,
gradI
);
if
(
fabs
(
dir
)
<=
0.01
)
{
dir
=
0.000001
f
;
}
else
{
dir
=
(
float
)
fabs
(
VectorScalMult
(
r
,
gradI
)
/
sqrt
(
VectorLength
(
r
)
*
VectorLength
(
gradI
)));
}
w
=
dst
*
dir
;
Ia
+=
(
float
)
w
*
(
float
)(
CV_MAT_3COLOR_ELEM
(
*
out
,
uchar
,
km
,
lm
,
color
));
s
+=
w
;
}
}
}
}
CV_MAT_3COLOR_ELEM
(
*
out
,
uchar
,
i
-
1
,
j
-
1
,
color
)
=
cv
::
saturate_cast
<
uchar
>
((
double
)
Ia
/
s
);
}
CV_MAT_ELEM
(
*
f
,
uchar
,
i
,
j
)
=
BAND
;
Heap
->
Push
(
i
,
j
,
dist
);
}
}
}
}
else
if
(
CV_MAT_CN
(
out
->
type
)
==
1
)
{
while
(
Heap
->
Pop
(
&
ii
,
&
jj
))
{
CV_MAT_ELEM
(
*
f
,
uchar
,
ii
,
jj
)
=
KNOWN
;
for
(
q
=
0
;
q
<
4
;
q
++
)
{
if
(
q
==
0
)
{
i
=
ii
-
1
;
j
=
jj
;}
else
if
(
q
==
1
)
{
i
=
ii
;
j
=
jj
-
1
;}
else
if
(
q
==
2
)
{
i
=
ii
+
1
;
j
=
jj
;}
else
if
(
q
==
3
)
{
i
=
ii
;
j
=
jj
+
1
;}
if
((
i
<=
1
)
||
(
j
<=
1
)
||
(
i
>
t
->
rows
-
1
)
||
(
j
>
t
->
cols
-
1
))
continue
;
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
i
,
j
)
==
INSIDE
)
{
dist
=
min4
(
FastMarching_solve
(
i
-
1
,
j
,
i
,
j
-
1
,
f
,
t
),
FastMarching_solve
(
i
+
1
,
j
,
i
,
j
-
1
,
f
,
t
),
FastMarching_solve
(
i
-
1
,
j
,
i
,
j
+
1
,
f
,
t
),
FastMarching_solve
(
i
+
1
,
j
,
i
,
j
+
1
,
f
,
t
));
CV_MAT_ELEM
(
*
t
,
float
,
i
,
j
)
=
dist
;
{
CvPoint2D32f
gradI
,
r
;
float
Ia
=
0
,
s
=
1.0e-20
f
,
w
,
dst
,
dir
;
for
(
k
=
i
-
range
;
k
<=
i
+
range
;
k
++
)
{
int
km
=
k
-
1
+
(
k
==
1
),
kp
=
k
-
1
-
(
k
==
t
->
rows
-
2
);
for
(
l
=
j
-
range
;
l
<=
j
+
range
;
l
++
)
{
int
lm
=
l
-
1
+
(
l
==
1
),
lp
=
l
-
1
-
(
l
==
t
->
cols
-
2
);
if
(
k
>
0
&&
l
>
0
&&
k
<
t
->
rows
-
1
&&
l
<
t
->
cols
-
1
)
{
if
((
CV_MAT_ELEM
(
*
f
,
uchar
,
k
,
l
)
!=
INSIDE
)
&&
((
l
-
j
)
*
(
l
-
j
)
+
(
k
-
i
)
*
(
k
-
i
)
<=
range
*
range
))
{
r
.
y
=
(
float
)(
i
-
k
);
r
.
x
=
(
float
)(
j
-
l
);
dst
=
1
/
(
VectorLength
(
r
)
*
VectorLength
(
r
)
+
1
);
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
k
+
1
,
l
)
!=
INSIDE
)
{
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
k
-
1
,
l
)
!=
INSIDE
)
{
gradI
.
x
=
(
float
)(
abs
(
CV_MAT_ELEM
(
*
out
,
uchar
,
kp
+
1
,
lm
)
-
CV_MAT_ELEM
(
*
out
,
uchar
,
kp
,
lm
))
+
abs
(
CV_MAT_ELEM
(
*
out
,
uchar
,
kp
,
lm
)
-
CV_MAT_ELEM
(
*
out
,
uchar
,
km
-
1
,
lm
)));
}
else
{
gradI
.
x
=
(
float
)(
abs
(
CV_MAT_ELEM
(
*
out
,
uchar
,
kp
+
1
,
lm
)
-
CV_MAT_ELEM
(
*
out
,
uchar
,
kp
,
lm
)))
*
2.0
f
;
}
}
else
{
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
k
-
1
,
l
)
!=
INSIDE
)
{
gradI
.
x
=
(
float
)(
abs
(
CV_MAT_ELEM
(
*
out
,
uchar
,
kp
,
lm
)
-
CV_MAT_ELEM
(
*
out
,
uchar
,
km
-
1
,
lm
)))
*
2.0
f
;
}
else
{
gradI
.
x
=
0
;
}
}
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
k
,
l
+
1
)
!=
INSIDE
)
{
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
k
,
l
-
1
)
!=
INSIDE
)
{
gradI
.
y
=
(
float
)(
abs
(
CV_MAT_ELEM
(
*
out
,
uchar
,
km
,
lp
+
1
)
-
CV_MAT_ELEM
(
*
out
,
uchar
,
km
,
lm
))
+
abs
(
CV_MAT_ELEM
(
*
out
,
uchar
,
km
,
lm
)
-
CV_MAT_ELEM
(
*
out
,
uchar
,
km
,
lm
-
1
)));
}
else
{
gradI
.
y
=
(
float
)(
abs
(
CV_MAT_ELEM
(
*
out
,
uchar
,
km
,
lp
+
1
)
-
CV_MAT_ELEM
(
*
out
,
uchar
,
km
,
lm
)))
*
2.0
f
;
}
}
else
{
if
(
CV_MAT_ELEM
(
*
f
,
uchar
,
k
,
l
-
1
)
!=
INSIDE
)
{
gradI
.
y
=
(
float
)(
abs
(
CV_MAT_ELEM
(
*
out
,
uchar
,
km
,
lm
)
-
CV_MAT_ELEM
(
*
out
,
uchar
,
km
,
lm
-
1
)))
*
2.0
f
;
}
else
{
gradI
.
y
=
0
;
}
}
gradI
.
x
=-
gradI
.
x
;
dir
=
VectorScalMult
(
r
,
gradI
);
if
(
fabs
(
dir
)
<=
0.01
)
{
dir
=
0.000001
f
;
}
else
{
dir
=
(
float
)
fabs
(
VectorScalMult
(
r
,
gradI
)
/
sqrt
(
VectorLength
(
r
)
*
VectorLength
(
gradI
)));
}
w
=
dst
*
dir
;
Ia
+=
(
float
)
w
*
(
float
)(
CV_MAT_ELEM
(
*
out
,
uchar
,
km
,
lm
));
s
+=
w
;
}
}
}
}
CV_MAT_ELEM
(
*
out
,
uchar
,
i
-
1
,
j
-
1
)
=
cv
::
saturate_cast
<
uchar
>
((
double
)
Ia
/
s
);
}
CV_MAT_ELEM
(
*
f
,
uchar
,
i
,
j
)
=
BAND
;
Heap
->
Push
(
i
,
j
,
dist
);
}
}
}
}
}
#define SET_BORDER1_C1(image,type,value) {\
int i,j;\
for(j=0; j<image->cols; j++) {\
CV_MAT_ELEM(*image,type,0,j) = value;\
}\
for (i=1; i<image->rows-1; i++) {\
CV_MAT_ELEM(*image,type,i,0) = CV_MAT_ELEM(*image,type,i,image->cols-1) = value;\
}\
for(j=0; j<image->cols; j++) {\
CV_MAT_ELEM(*image,type,erows-1,j) = value;\
}\
}
#define COPY_MASK_BORDER1_C1(src,dst,type) {\
int i,j;\
for (i=0; i<src->rows; i++) {\
for(j=0; j<src->cols; j++) {\
if (CV_MAT_ELEM(*src,type,i,j)!=0)\
CV_MAT_ELEM(*dst,type,i+1,j+1) = INSIDE;\
}\
}\
}
namespace
cv
{
template
<>
void
cv
::
Ptr
<
IplConvKernel
>::
delete_obj
()
{
cvReleaseStructuringElement
(
&
obj
);
}
}
void
cvInpaint
(
const
CvArr
*
_input_img
,
const
CvArr
*
_inpaint_mask
,
CvArr
*
_output_img
,
double
inpaintRange
,
int
flags
)
{
cv
::
Ptr
<
CvMat
>
mask
,
band
,
f
,
t
,
out
;
cv
::
Ptr
<
CvPriorityQueueFloat
>
Heap
,
Out
;
cv
::
Ptr
<
IplConvKernel
>
el_cross
,
el_range
;
CvMat
input_hdr
,
mask_hdr
,
output_hdr
;
CvMat
*
input_img
,
*
inpaint_mask
,
*
output_img
;
int
range
=
cvRound
(
inpaintRange
);
int
erows
,
ecols
;
input_img
=
cvGetMat
(
_input_img
,
&
input_hdr
);
inpaint_mask
=
cvGetMat
(
_inpaint_mask
,
&
mask_hdr
);
output_img
=
cvGetMat
(
_output_img
,
&
output_hdr
);
if
(
!
CV_ARE_SIZES_EQ
(
input_img
,
output_img
)
||
!
CV_ARE_SIZES_EQ
(
input_img
,
inpaint_mask
))
CV_Error
(
CV_StsUnmatchedSizes
,
"All the input and output images must have the same size"
);
if
(
(
CV_MAT_TYPE
(
input_img
->
type
)
!=
CV_8UC1
&&
CV_MAT_TYPE
(
input_img
->
type
)
!=
CV_8UC3
)
||
!
CV_ARE_TYPES_EQ
(
input_img
,
output_img
)
)
CV_Error
(
CV_StsUnsupportedFormat
,
"Only 8-bit 1-channel and 3-channel input/output images are supported"
);
if
(
CV_MAT_TYPE
(
inpaint_mask
->
type
)
!=
CV_8UC1
)
CV_Error
(
CV_StsUnsupportedFormat
,
"The mask must be 8-bit 1-channel image"
);
range
=
MAX
(
range
,
1
);
range
=
MIN
(
range
,
100
);
ecols
=
input_img
->
cols
+
2
;
erows
=
input_img
->
rows
+
2
;
f
=
cvCreateMat
(
erows
,
ecols
,
CV_8UC1
);
t
=
cvCreateMat
(
erows
,
ecols
,
CV_32FC1
);
band
=
cvCreateMat
(
erows
,
ecols
,
CV_8UC1
);
mask
=
cvCreateMat
(
erows
,
ecols
,
CV_8UC1
);
el_cross
=
cvCreateStructuringElementEx
(
3
,
3
,
1
,
1
,
CV_SHAPE_CROSS
,
NULL
);
cvCopy
(
input_img
,
output_img
);
cvSet
(
mask
,
cvScalar
(
KNOWN
,
0
,
0
,
0
));
COPY_MASK_BORDER1_C1
(
inpaint_mask
,
mask
,
uchar
);
SET_BORDER1_C1
(
mask
,
uchar
,
0
);
cvSet
(
f
,
cvScalar
(
KNOWN
,
0
,
0
,
0
));
cvSet
(
t
,
cvScalar
(
1.0e6
f
,
0
,
0
,
0
));
cvDilate
(
mask
,
band
,
el_cross
,
1
);
// image with narrow band
Heap
=
new
CvPriorityQueueFloat
;
if
(
!
Heap
->
Init
(
band
))
return
;
cvSub
(
band
,
mask
,
band
,
NULL
);
SET_BORDER1_C1
(
band
,
uchar
,
0
);
if
(
!
Heap
->
Add
(
band
))
return
;
cvSet
(
f
,
cvScalar
(
BAND
,
0
,
0
,
0
),
band
);
cvSet
(
f
,
cvScalar
(
INSIDE
,
0
,
0
,
0
),
mask
);
cvSet
(
t
,
cvScalar
(
0
,
0
,
0
,
0
),
band
);
if
(
flags
==
cv
::
INPAINT_TELEA
)
{
out
=
cvCreateMat
(
erows
,
ecols
,
CV_8UC1
);
el_range
=
cvCreateStructuringElementEx
(
2
*
range
+
1
,
2
*
range
+
1
,
range
,
range
,
CV_SHAPE_RECT
,
NULL
);
cvDilate
(
mask
,
out
,
el_range
,
1
);
cvSub
(
out
,
mask
,
out
,
NULL
);
Out
=
new
CvPriorityQueueFloat
;
if
(
!
Out
->
Init
(
out
))
return
;
if
(
!
Out
->
Add
(
band
))
return
;
cvSub
(
out
,
band
,
out
,
NULL
);
SET_BORDER1_C1
(
out
,
uchar
,
0
);
icvCalcFMM
(
out
,
t
,
Out
,
true
);
icvTeleaInpaintFMM
(
mask
,
t
,
output_img
,
range
,
Heap
);
}
else
if
(
flags
==
cv
::
INPAINT_NS
)
{
icvNSInpaintFMM
(
mask
,
t
,
output_img
,
range
,
Heap
);
}
else
{
CV_Error
(
cv
::
Error
::
StsBadArg
,
"The flags argument must be one of CV_INPAINT_TELEA or CV_INPAINT_NS"
);
}
}
void
cv
::
inpaint
(
InputArray
_src
,
InputArray
_mask
,
OutputArray
_dst
,
double
inpaintRange
,
int
flags
)
{
Mat
src
=
_src
.
getMat
(),
mask
=
_mask
.
getMat
();
_dst
.
create
(
src
.
size
(),
src
.
type
()
);
CvMat
c_src
=
src
,
c_mask
=
mask
,
c_dst
=
_dst
.
getMat
();
cvInpaint
(
&
c_src
,
&
c_mask
,
&
c_dst
,
inpaintRange
,
flags
);
}
modules/optim/src/lpsolver.cpp
0 → 100644
View file @
f2afe645
#include "opencv2/opencv.hpp"
namespace
cv
{
namespace
optim
{
class
Solver
:
public
Algorithm
/* Algorithm is base OpenCV class */
{
class
Function
{
public
:
virtual
~
Function
()
{}
virtual
double
calc
(
InputArray
args
)
const
=
0
;
virtual
double
calc
(
InputArgs
,
OutputArray
grad
)
const
=
0
;
};
// could be reused for all the generic algorithms like downhill simplex.
virtual
void
solve
(
InputArray
x0
,
OutputArray
result
)
const
=
0
;
virtual
void
setTermCriteria
(
const
TermCriteria
&
criteria
)
=
0
;
virtual
TermCriteria
getTermCriteria
()
=
0
;
// more detailed API to be defined later ...
};
class
LPSolver
:
public
Solver
{
public
:
virtual
void
solve
(
InputArray
coeffs
,
InputArray
constraints
,
OutputArray
result
)
const
=
0
;
// ...
};
Ptr
<
LPSolver
>
createLPSimplexSolver
();
}}
/*===============
Hill climbing solver is more generic one:*/
/*
class DownhillSolver : public Solver
{
public:
// various setters and getters, if needed
};
Ptr<DownhillSolver> createDownhillSolver(const Ptr<Solver::Function>& func);*/
modules/optim/src/precomp.cpp
deleted
100644 → 0
View file @
47ce461d
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "precomp.hpp"
/* End of file. */
modules/optim/src/precomp.hpp
deleted
100644 → 0
View file @
47ce461d
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef __OPENCV_PRECOMP_H__
#define __OPENCV_PRECOMP_H__
#include "opencv2/photo.hpp"
#include "opencv2/core/private.hpp"
#ifdef HAVE_TEGRA_OPTIMIZATION
#include "opencv2/photo/photo_tegra.hpp"
#endif
#endif
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