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
c4c1c4c9
Commit
c4c1c4c9
authored
Feb 27, 2017
by
Maksim Shabunin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Replaced several hal:: classes with functions, marked old variants deprecated
parent
dcbed8d6
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
620 additions
and
649 deletions
+620
-649
hal.hpp
modules/imgproc/include/opencv2/imgproc/hal/hal.hpp
+72
-32
filter.cpp
modules/imgproc/src/filter.cpp
+311
-344
morph.cpp
modules/imgproc/src/morph.cpp
+237
-273
No files found.
modules/imgproc/include/opencv2/imgproc/hal/hal.hpp
View file @
c4c1c4c9
...
@@ -10,53 +10,93 @@ namespace cv { namespace hal {
...
@@ -10,53 +10,93 @@ namespace cv { namespace hal {
//! @addtogroup imgproc_hal_functions
//! @addtogroup imgproc_hal_functions
//! @{
//! @{
//---------------------------
//! @cond IGNORED
struct
CV_EXPORTS
Filter2D
struct
CV_EXPORTS
Filter2D
{
{
static
Ptr
<
hal
::
Filter2D
>
create
(
uchar
*
kernel_data
,
size_t
kernel_step
,
int
kernel_type
,
CV_DEPRECATED
static
Ptr
<
hal
::
Filter2D
>
create
(
uchar
*
,
size_t
,
int
,
int
kernel_width
,
int
kernel_height
,
int
,
int
,
int
max_width
,
int
max_height
,
int
,
int
,
int
stype
,
int
dtype
,
int
,
int
,
int
borderType
,
double
delta
,
int
,
double
,
int
anchor_x
,
int
anchor_y
,
int
,
int
,
bool
isSubmatrix
,
bool
isInplace
);
bool
,
bool
);
virtual
void
apply
(
uchar
*
src_data
,
size_t
src_step
,
virtual
void
apply
(
uchar
*
,
size_t
,
uchar
*
dst_data
,
size_t
dst_step
,
uchar
*
,
size_t
,
int
width
,
int
height
,
int
,
int
,
int
full_width
,
int
full_height
,
int
,
int
,
int
offset_x
,
int
offset_y
)
=
0
;
int
,
int
)
=
0
;
virtual
~
Filter2D
()
{}
virtual
~
Filter2D
()
{}
};
};
struct
CV_EXPORTS
SepFilter2D
struct
CV_EXPORTS
SepFilter2D
{
{
static
Ptr
<
hal
::
SepFilter2D
>
create
(
int
stype
,
int
dtype
,
int
ktype
,
CV_DEPRECATED
static
Ptr
<
hal
::
SepFilter2D
>
create
(
int
,
int
,
int
,
uchar
*
kernelx_data
,
int
kernelx_len
,
uchar
*
,
int
,
uchar
*
kernely_data
,
int
kernely_len
,
uchar
*
,
int
,
int
anchor_x
,
int
anchor_y
,
int
,
int
,
double
delta
,
int
borderType
);
double
,
int
);
virtual
void
apply
(
uchar
*
src_data
,
size_t
src_step
,
virtual
void
apply
(
uchar
*
,
size_t
,
uchar
*
dst_data
,
size_t
dst_step
,
uchar
*
,
size_t
,
int
width
,
int
height
,
int
,
int
,
int
full_width
,
int
full_height
,
int
,
int
,
int
offset_x
,
int
offset_y
)
=
0
;
int
,
int
)
=
0
;
virtual
~
SepFilter2D
()
{}
virtual
~
SepFilter2D
()
{}
};
};
struct
CV_EXPORTS
Morph
struct
CV_EXPORTS
Morph
{
{
static
Ptr
<
Morph
>
create
(
int
op
,
int
src_type
,
int
dst_type
,
int
max_width
,
int
max_height
,
CV_DEPRECATED
static
Ptr
<
hal
::
Morph
>
create
(
int
,
int
,
int
,
int
,
int
,
int
kernel_type
,
uchar
*
kernel_data
,
size_t
kernel_step
,
int
,
uchar
*
,
size_t
,
int
kernel_width
,
int
kernel_height
,
int
,
int
,
int
anchor_x
,
int
anchor_y
,
int
,
int
,
int
borderType
,
const
double
borderValue
[
4
]
,
int
,
const
double
*
,
int
iterations
,
bool
isSubmatrix
,
bool
allowInplace
);
int
,
bool
,
bool
);
virtual
void
apply
(
uchar
*
src_data
,
size_t
src_step
,
uchar
*
dst_data
,
size_t
dst_step
,
int
width
,
int
height
,
virtual
void
apply
(
uchar
*
,
size_t
,
uchar
*
,
size_t
,
int
,
int
,
int
roi_width
,
int
roi_height
,
int
roi_x
,
int
roi_y
,
int
,
int
,
int
,
int
,
int
roi_width2
,
int
roi_height2
,
int
roi_x2
,
int
roi_y2
)
=
0
;
int
,
int
,
int
,
int
)
=
0
;
virtual
~
Morph
()
{}
virtual
~
Morph
()
{}
};
};
//! @endcond
//---------------------------
CV_EXPORTS
void
filter2D
(
int
stype
,
int
dtype
,
int
kernel_type
,
uchar
*
src_data
,
size_t
src_step
,
uchar
*
dst_data
,
size_t
dst_step
,
int
width
,
int
height
,
int
full_width
,
int
full_height
,
int
offset_x
,
int
offset_y
,
uchar
*
kernel_data
,
size_t
kernel_step
,
int
kernel_width
,
int
kernel_height
,
int
anchor_x
,
int
anchor_y
,
double
delta
,
int
borderType
,
bool
isSubmatrix
);
CV_EXPORTS
void
sepFilter2D
(
int
stype
,
int
dtype
,
int
ktype
,
uchar
*
src_data
,
size_t
src_step
,
uchar
*
dst_data
,
size_t
dst_step
,
int
width
,
int
height
,
int
full_width
,
int
full_height
,
int
offset_x
,
int
offset_y
,
uchar
*
kernelx_data
,
int
kernelx_len
,
uchar
*
kernely_data
,
int
kernely_len
,
int
anchor_x
,
int
anchor_y
,
double
delta
,
int
borderType
);
CV_EXPORTS
void
morph
(
int
op
,
int
src_type
,
int
dst_type
,
uchar
*
src_data
,
size_t
src_step
,
uchar
*
dst_data
,
size_t
dst_step
,
int
width
,
int
height
,
int
roi_width
,
int
roi_height
,
int
roi_x
,
int
roi_y
,
int
roi_width2
,
int
roi_height2
,
int
roi_x2
,
int
roi_y2
,
int
kernel_type
,
uchar
*
kernel_data
,
size_t
kernel_step
,
int
kernel_width
,
int
kernel_height
,
int
anchor_x
,
int
anchor_y
,
int
borderType
,
const
double
borderValue
[
4
],
int
iterations
,
bool
isSubmatrix
);
CV_EXPORTS
void
resize
(
int
src_type
,
CV_EXPORTS
void
resize
(
int
src_type
,
const
uchar
*
src_data
,
size_t
src_step
,
int
src_width
,
int
src_height
,
const
uchar
*
src_data
,
size_t
src_step
,
int
src_width
,
int
src_height
,
...
...
modules/imgproc/src/filter.cpp
View file @
c4c1c4c9
...
@@ -4509,39 +4509,29 @@ cv::Ptr<cv::FilterEngine> cv::createLinearFilter( int _srcType, int _dstType,
...
@@ -4509,39 +4509,29 @@ cv::Ptr<cv::FilterEngine> cv::createLinearFilter( int _srcType, int _dstType,
using
namespace
cv
;
using
namespace
cv
;
struct
ReplacementFilter
:
public
hal
::
Filter2D
static
bool
replacementFilter2D
(
int
stype
,
int
dtype
,
int
kernel_type
,
uchar
*
src_data
,
size_t
src_step
,
uchar
*
dst_data
,
size_t
dst_step
,
int
width
,
int
height
,
int
full_width
,
int
full_height
,
int
offset_x
,
int
offset_y
,
uchar
*
kernel_data
,
size_t
kernel_step
,
int
kernel_width
,
int
kernel_height
,
int
anchor_x
,
int
anchor_y
,
double
delta
,
int
borderType
,
bool
isSubmatrix
)
{
{
cvhalFilter2D
*
ctx
;
cvhalFilter2D
*
ctx
;
bool
isInitialized
;
int
res
=
cv_hal_filterInit
(
&
ctx
,
kernel_data
,
kernel_step
,
kernel_type
,
kernel_width
,
kernel_height
,
width
,
height
,
ReplacementFilter
()
:
ctx
(
0
),
isInitialized
(
false
)
{
}
stype
,
dtype
,
borderType
,
delta
,
anchor_x
,
anchor_y
,
isSubmatrix
,
src_data
==
dst_data
);
bool
init
(
uchar
*
kernel_data
,
size_t
kernel_step
,
int
kernel_type
,
int
kernel_width
,
if
(
res
!=
CV_HAL_ERROR_OK
)
int
kernel_height
,
int
max_width
,
int
max_height
,
int
stype
,
int
dtype
,
int
borderType
,
double
delta
,
return
false
;
int
anchor_x
,
int
anchor_y
,
bool
isSubmatrix
,
bool
isInplace
)
res
=
cv_hal_filter
(
ctx
,
src_data
,
src_step
,
dst_data
,
dst_step
,
width
,
height
,
full_width
,
full_height
,
offset_x
,
offset_y
);
{
bool
success
=
(
res
==
CV_HAL_ERROR_OK
);
int
res
=
cv_hal_filterInit
(
&
ctx
,
kernel_data
,
kernel_step
,
kernel_type
,
kernel_width
,
kernel_height
,
max_width
,
max_height
,
res
=
cv_hal_filterFree
(
ctx
);
stype
,
dtype
,
borderType
,
delta
,
anchor_x
,
anchor_y
,
isSubmatrix
,
isInplace
);
if
(
res
!=
CV_HAL_ERROR_OK
)
isInitialized
=
(
res
==
CV_HAL_ERROR_OK
);
return
false
;
return
isInitialized
;
return
success
;
}
}
void
apply
(
uchar
*
src_data
,
size_t
src_step
,
uchar
*
dst_data
,
size_t
dst_step
,
int
width
,
int
height
,
int
full_width
,
int
full_height
,
int
offset_x
,
int
offset_y
)
{
if
(
isInitialized
)
{
int
res
=
cv_hal_filter
(
ctx
,
src_data
,
src_step
,
dst_data
,
dst_step
,
width
,
height
,
full_width
,
full_height
,
offset_x
,
offset_y
);
if
(
res
!=
CV_HAL_ERROR_OK
)
CV_Error
(
Error
::
StsNotImplemented
,
"HAL Filter returned an error"
);
}
}
~
ReplacementFilter
()
{
if
(
isInitialized
)
{
int
res
=
cv_hal_filterFree
(
ctx
);
if
(
res
!=
CV_HAL_ERROR_OK
)
CV_Error
(
Error
::
StsNotImplemented
,
"HAL Filter Free returned an error"
);
}
}
};
#ifdef HAVE_IPP
#ifdef HAVE_IPP
typedef
IppStatus
(
CV_STDCALL
*
IppiFilterBorder
)(
typedef
IppStatus
(
CV_STDCALL
*
IppiFilterBorder
)(
...
@@ -4613,8 +4603,17 @@ struct IppFilterTrait<CV_32F>
...
@@ -4613,8 +4603,17 @@ struct IppFilterTrait<CV_32F>
};
};
template
<
int
kdepth
>
template
<
int
kdepth
>
struct
IppFilter
:
public
hal
::
Filter2D
static
bool
ippFilter2D
(
int
stype
,
int
dtype
,
uchar
*
src_data
,
size_t
src_step
,
uchar
*
dst_data
,
size_t
dst_step
,
int
width
,
int
height
,
uchar
*
kernel_data
,
size_t
kernel_step
,
int
kernel_width
,
int
kernel_height
,
int
anchor_x
,
int
anchor_y
,
double
delta
,
int
borderType
,
bool
isSubmatrix
)
{
{
CV_INSTRUMENT_REGION_IPP
();
typedef
IppFilterTrait
<
kdepth
>
trait
;
typedef
IppFilterTrait
<
kdepth
>
trait
;
typedef
typename
trait
::
kernel_type
kernel_type
;
typedef
typename
trait
::
kernel_type
kernel_type
;
...
@@ -4624,105 +4623,92 @@ struct IppFilter : public hal::Filter2D
...
@@ -4624,105 +4623,92 @@ struct IppFilter : public hal::Filter2D
IppiBorderType
ippBorderType
;
IppiBorderType
ippBorderType
;
int
src_type
;
int
src_type
;
bool
init
(
uchar
*
kernel_data
,
size_t
kernel_step
,
int
,
int
kernel_width
,
int
kernel_height
,
Point
anchor
(
anchor_x
,
anchor_y
);
int
max_width
,
int
max_height
,
int
stype
,
int
dtype
,
int
borderType
,
double
delta
,
int
anchor_x
,
int
anchor_y
,
bool
isSubmatrix
,
bool
isInplace
)
{
Point
anchor
(
anchor_x
,
anchor_y
);
#if IPP_VERSION_X100 >= 900
#if IPP_VERSION_X100 >= 900
Point
ippAnchor
((
kernel_width
-
1
)
/
2
,
(
kernel_height
-
1
)
/
2
);
Point
ippAnchor
((
kernel_width
-
1
)
/
2
,
(
kernel_height
-
1
)
/
2
);
#else
#else
Point
ippAnchor
(
kernel_width
>>
1
,
kernel_height
>>
1
);
Point
ippAnchor
(
kernel_width
>>
1
,
kernel_height
>>
1
);
#endif
#endif
bool
isIsolated
=
(
borderType
&
BORDER_ISOLATED
)
!=
0
;
bool
isIsolated
=
(
borderType
&
BORDER_ISOLATED
)
!=
0
;
int
borderTypeNI
=
borderType
&
~
BORDER_ISOLATED
;
int
borderTypeNI
=
borderType
&
~
BORDER_ISOLATED
;
ippBorderType
=
ippiGetBorderType
(
borderTypeNI
);
ippBorderType
=
ippiGetBorderType
(
borderTypeNI
);
int
ddepth
=
CV_MAT_DEPTH
(
dtype
);
int
ddepth
=
CV_MAT_DEPTH
(
dtype
);
int
sdepth
=
CV_MAT_DEPTH
(
stype
);
int
sdepth
=
CV_MAT_DEPTH
(
stype
);
#if IPP_VERSION_X100 >= 201700 && IPP_VERSION_X100 < 201702 // IPP bug with 1x1 kernel
#if IPP_VERSION_X100 >= 201700 && IPP_VERSION_X100 < 201702 // IPP bug with 1x1 kernel
if
(
kernel_width
==
1
&&
kernel_height
==
1
)
if
(
kernel_width
==
1
&&
kernel_height
==
1
)
return
false
;
return
false
;
#endif
#endif
bool
runIpp
=
true
bool
runIpp
=
true
&&
(
borderTypeNI
==
BORDER_CONSTANT
||
borderTypeNI
==
BORDER_REPLICATE
)
&&
(
borderTypeNI
==
BORDER_CONSTANT
||
borderTypeNI
==
BORDER_REPLICATE
)
&&
(
sdepth
==
ddepth
)
&&
(
sdepth
==
ddepth
)
&&
(
getIppFunc
(
stype
))
&&
(
getIppFunc
(
stype
))
&&
((
int
)
ippBorderType
>
0
)
&&
((
int
)
ippBorderType
>
0
)
&&
(
!
isSubmatrix
||
isIsolated
)
&&
(
!
isSubmatrix
||
isIsolated
)
&&
(
std
::
fabs
(
delta
-
0
)
<
DBL_EPSILON
)
&&
(
std
::
fabs
(
delta
-
0
)
<
DBL_EPSILON
)
&&
(
ippAnchor
==
anchor
)
&&
(
ippAnchor
==
anchor
)
&&
!
isInplace
;
&&
src_data
!=
dst_data
;
if
(
!
runIpp
)
if
(
!
runIpp
)
return
false
;
return
false
;
src_type
=
stype
;
int
cn
=
CV_MAT_CN
(
stype
);
IppiSize
kernelSize
=
{
kernel_width
,
kernel_height
};
IppDataType
dataType
=
ippiGetDataType
(
ddepth
);
IppDataType
kernelType
=
ippiGetDataType
(
kdepth
);
Ipp32s
specSize
=
0
;
Ipp32s
bufsize
=
0
;
IppiSize
dstRoiSize
=
{
width
,
height
};
IppStatus
status
;
status
=
ippiFilterBorderGetSize
(
kernelSize
,
dstRoiSize
,
dataType
,
kernelType
,
cn
,
&
specSize
,
&
bufsize
);
if
(
status
<
0
)
return
false
;
src_type
=
stype
;
kernel_type
*
pKerBuffer
=
(
kernel_type
*
)
kernel_data
;
int
cn
=
CV_MAT_CN
(
stype
);
size_t
good_kernel_step
=
sizeof
(
kernel_type
)
*
static_cast
<
size_t
>
(
kernelSize
.
width
);
IppiSize
kernelSize
=
{
kernel_width
,
kernel_height
};
IppDataType
dataType
=
ippiGetDataType
(
ddepth
);
IppDataType
kernelType
=
ippiGetDataType
(
kdepth
);
Ipp32s
specSize
=
0
;
Ipp32s
bufsize
=
0
;
IppiSize
dstRoiSize
=
{
max_width
,
max_height
};
IppStatus
status
;
status
=
ippiFilterBorderGetSize
(
kernelSize
,
dstRoiSize
,
dataType
,
kernelType
,
cn
,
&
specSize
,
&
bufsize
);
if
(
status
>=
0
)
{
kernel_type
*
pKerBuffer
=
(
kernel_type
*
)
kernel_data
;
size_t
good_kernel_step
=
sizeof
(
kernel_type
)
*
static_cast
<
size_t
>
(
kernelSize
.
width
);
#if IPP_VERSION_X100 >= 900
#if IPP_VERSION_X100 >= 900
if
(
kernel_step
!=
good_kernel_step
)
{
if
(
kernel_step
!=
good_kernel_step
)
{
kernelBuffer
.
Alloc
((
int
)
good_kernel_step
*
kernelSize
.
height
);
kernelBuffer
.
Alloc
((
int
)
good_kernel_step
*
kernelSize
.
height
);
status
=
trait
::
get_copy_fun
()((
kernel_type
*
)
kernel_data
,
(
int
)
kernel_step
,
kernelBuffer
,
(
int
)
good_kernel_step
,
kernelSize
);
status
=
trait
::
get_copy_fun
()((
kernel_type
*
)
kernel_data
,
(
int
)
kernel_step
,
kernelBuffer
,
(
int
)
good_kernel_step
,
kernelSize
);
if
(
status
<
0
)
if
(
status
<
0
)
return
false
;
return
false
;
pKerBuffer
=
kernelBuffer
;
pKerBuffer
=
kernelBuffer
;
}
}
#else
#else
kernelBuffer
.
Alloc
(
good_kernel_step
*
kernelSize
.
height
);
kernelBuffer
.
Alloc
(
good_kernel_step
*
kernelSize
.
height
);
Mat
kerFlip
(
Size
(
kernelSize
.
width
,
kernelSize
.
height
),
trait
::
kernel_type_id
,
kernelBuffer
,
(
int
)
good_kernel_step
);
Mat
kerFlip
(
Size
(
kernelSize
.
width
,
kernelSize
.
height
),
trait
::
kernel_type_id
,
kernelBuffer
,
(
int
)
good_kernel_step
);
Mat
kernel
(
Size
(
kernel_width
,
kernel_height
),
trait
::
kernel_type_id
,
kernel_data
,
kernel_step
);
Mat
kernel
(
Size
(
kernel_width
,
kernel_height
),
trait
::
kernel_type_id
,
kernel_data
,
kernel_step
);
flip
(
kernel
,
kerFlip
,
-
1
);
flip
(
kernel
,
kerFlip
,
-
1
);
pKerBuffer
=
kernelBuffer
;
pKerBuffer
=
kernelBuffer
;
#endif
#endif
spec
.
Alloc
(
specSize
);
spec
.
Alloc
(
specSize
);
buffer
.
Alloc
(
bufsize
);
buffer
.
Alloc
(
bufsize
);
status
=
trait
::
runInit
(
pKerBuffer
,
kernelSize
,
0
,
dataType
,
cn
,
ippRndFinancial
,
spec
);
status
=
trait
::
runInit
(
pKerBuffer
,
kernelSize
,
0
,
dataType
,
cn
,
ippRndFinancial
,
spec
);
if
(
status
>=
0
)
{
if
(
status
<
0
)
{
return
true
;
}
}
return
false
;
return
false
;
}
}
IppiFilterBorder
ippiFilterBorder
=
getIppFunc
(
src_type
);
void
apply
(
uchar
*
src_data
,
size_t
src_step
,
uchar
*
dst_data
,
size_t
dst_step
,
int
width
,
int
height
,
int
,
int
,
int
,
int
)
kernel_type
borderValue
[
4
]
=
{
0
,
0
,
0
,
0
};
{
status
=
CV_INSTRUMENT_FUN_IPP
(
ippiFilterBorder
,
src_data
,
(
int
)
src_step
,
dst_data
,
(
int
)
dst_step
,
dstRoiSize
,
ippBorderType
,
borderValue
,
spec
,
buffer
);
CV_INSTRUMENT_REGION_IPP
()
if
(
status
>=
0
)
{
CV_IMPL_ADD
(
CV_IMPL_IPP
);
if
(
dst_data
==
src_data
)
return
true
;
CV_Error
(
Error
::
StsBadArg
,
"Inplace IPP Filter2D is not supported"
);
IppiFilterBorder
ippiFilterBorder
=
getIppFunc
(
src_type
);
IppiSize
dstRoiSize
=
{
width
,
height
};
kernel_type
borderValue
[
4
]
=
{
0
,
0
,
0
,
0
};
IppStatus
status
=
CV_INSTRUMENT_FUN_IPP
(
ippiFilterBorder
,
src_data
,
(
int
)
src_step
,
dst_data
,
(
int
)
dst_step
,
dstRoiSize
,
ippBorderType
,
borderValue
,
spec
,
buffer
);
if
(
status
>=
0
)
{
CV_IMPL_ADD
(
CV_IMPL_IPP
);
}
}
}
};
return
false
;
}
#endif
#endif
struct
DftFilter
:
public
hal
::
Filter2D
static
bool
dftFilter2D
(
int
stype
,
int
dtype
,
int
kernel_type
,
uchar
*
src_data
,
size_t
src_step
,
uchar
*
dst_data
,
size_t
dst_step
,
int
width
,
int
height
,
uchar
*
kernel_data
,
size_t
kernel_step
,
int
kernel_width
,
int
kernel_height
,
int
anchor_x
,
int
anchor_y
,
double
delta
,
int
borderType
)
{
{
int
src_type
;
int
dst_type
;
double
delta
;
Mat
kernel
;
Point
anchor
;
int
borderType
;
static
bool
isAppropriate
(
int
stype
,
int
dtype
,
int
kernel_width
,
int
kernel_height
)
{
{
#if CV_SSE2
#if CV_SSE2
int
sdepth
=
CV_MAT_DEPTH
(
stype
);
int
sdepth
=
CV_MAT_DEPTH
(
stype
);
...
@@ -4733,162 +4719,112 @@ struct DftFilter : public hal::Filter2D
...
@@ -4733,162 +4719,112 @@ struct DftFilter : public hal::Filter2D
CV_UNUSED
(
dtype
);
CV_UNUSED
(
dtype
);
int
dft_filter_size
=
50
;
int
dft_filter_size
=
50
;
#endif
#endif
return
kernel_width
*
kernel_height
>=
dft_filter_size
;
if
(
kernel_width
*
kernel_height
<
dft_filter_size
)
}
return
false
;
bool
init
(
uchar
*
kernel_data
,
size_t
kernel_step
,
int
kernel_type
,
int
kernel_width
,
int
kernel_height
,
int
,
int
,
int
stype
,
int
dtype
,
int
borderType_
,
double
delta_
,
int
anchor_x
,
int
anchor_y
,
bool
,
bool
)
{
anchor
=
Point
(
anchor_x
,
anchor_y
);
borderType
=
borderType_
;
kernel
=
Mat
(
Size
(
kernel_width
,
kernel_height
),
kernel_type
,
kernel_data
,
kernel_step
);
src_type
=
stype
;
dst_type
=
dtype
;
delta
=
delta_
;
if
(
isAppropriate
(
stype
,
dtype
,
kernel_width
,
kernel_height
))
return
true
;
return
false
;
}
}
void
apply
(
uchar
*
src_data
,
size_t
src_step
,
uchar
*
dst_data
,
size_t
dst_step
,
int
width
,
int
height
,
int
,
int
,
int
,
int
)
Point
anchor
=
Point
(
anchor_x
,
anchor_y
);
{
Mat
kernel
=
Mat
(
Size
(
kernel_width
,
kernel_height
),
kernel_type
,
kernel_data
,
kernel_step
);
Mat
src
(
Size
(
width
,
height
),
src_type
,
src_data
,
src_step
);
Mat
dst
(
Size
(
width
,
height
),
dst_type
,
dst_data
,
dst_step
);
Mat
src
(
Size
(
width
,
height
),
stype
,
src_data
,
src_step
);
Mat
temp
;
Mat
dst
(
Size
(
width
,
height
),
dtype
,
dst_data
,
dst_step
);
int
src_channels
=
CV_MAT_CN
(
src_type
);
Mat
temp
;
int
dst_channels
=
CV_MAT_CN
(
dst_type
);
int
src_channels
=
CV_MAT_CN
(
stype
);
int
ddepth
=
CV_MAT_DEPTH
(
dst_type
);
int
dst_channels
=
CV_MAT_CN
(
dtype
);
// crossCorr doesn't accept non-zero delta with multiple channels
int
ddepth
=
CV_MAT_DEPTH
(
dtype
);
if
(
src_channels
!=
1
&&
delta
!=
0
)
{
// crossCorr doesn't accept non-zero delta with multiple channels
// The semantics of filter2D require that the delta be applied
if
(
src_channels
!=
1
&&
delta
!=
0
)
{
// as floating-point math. So wee need an intermediate Mat
// The semantics of filter2D require that the delta be applied
// with a float datatype. If the dest is already floats,
// as floating-point math. So wee need an intermediate Mat
// we just use that.
// with a float datatype. If the dest is already floats,
int
corrDepth
=
ddepth
;
// we just use that.
if
((
ddepth
==
CV_32F
||
ddepth
==
CV_64F
)
&&
src_data
!=
dst_data
)
{
int
corrDepth
=
ddepth
;
temp
=
Mat
(
Size
(
width
,
height
),
dst_type
,
dst_data
,
dst_step
);
if
((
ddepth
==
CV_32F
||
ddepth
==
CV_64F
)
&&
src_data
!=
dst_data
)
{
}
else
{
temp
=
Mat
(
Size
(
width
,
height
),
dtype
,
dst_data
,
dst_step
);
corrDepth
=
ddepth
==
CV_64F
?
CV_64F
:
CV_32F
;
temp
.
create
(
Size
(
width
,
height
),
CV_MAKETYPE
(
corrDepth
,
dst_channels
));
}
crossCorr
(
src
,
kernel
,
temp
,
src
.
size
(),
CV_MAKETYPE
(
corrDepth
,
src_channels
),
anchor
,
0
,
borderType
);
add
(
temp
,
delta
,
temp
);
if
(
temp
.
data
!=
dst_data
)
{
temp
.
convertTo
(
dst
,
dst
.
type
());
}
}
else
{
}
else
{
if
(
src_data
!=
dst_data
)
corrDepth
=
ddepth
==
CV_64F
?
CV_64F
:
CV_32F
;
temp
=
Mat
(
Size
(
width
,
height
),
dst_type
,
dst_data
,
dst_step
);
temp
.
create
(
Size
(
width
,
height
),
CV_MAKETYPE
(
corrDepth
,
dst_channels
)
);
else
}
temp
.
create
(
Size
(
width
,
height
),
dst_type
);
crossCorr
(
src
,
kernel
,
temp
,
src
.
size
(),
crossCorr
(
src
,
kernel
,
temp
,
src
.
size
(
),
CV_MAKETYPE
(
corrDepth
,
src_channels
),
CV_MAKETYPE
(
ddepth
,
src_channels
),
anchor
,
0
,
borderType
);
anchor
,
delta
,
borderType
);
add
(
temp
,
delta
,
temp
);
if
(
temp
.
data
!=
dst_data
)
if
(
temp
.
data
!=
dst_data
)
{
temp
.
copyTo
(
dst
);
temp
.
convertTo
(
dst
,
dst
.
type
()
);
}
}
}
else
{
if
(
src_data
!=
dst_data
)
temp
=
Mat
(
Size
(
width
,
height
),
dtype
,
dst_data
,
dst_step
);
else
temp
.
create
(
Size
(
width
,
height
),
dtype
);
crossCorr
(
src
,
kernel
,
temp
,
src
.
size
(),
CV_MAKETYPE
(
ddepth
,
src_channels
),
anchor
,
delta
,
borderType
);
if
(
temp
.
data
!=
dst_data
)
temp
.
copyTo
(
dst
);
}
}
};
return
true
;
}
struct
OcvFilter
:
public
hal
::
Filter2D
static
void
ocvFilter2D
(
int
stype
,
int
dtype
,
int
kernel_type
,
uchar
*
src_data
,
size_t
src_step
,
uchar
*
dst_data
,
size_t
dst_step
,
int
width
,
int
height
,
int
full_width
,
int
full_height
,
int
offset_x
,
int
offset_y
,
uchar
*
kernel_data
,
size_t
kernel_step
,
int
kernel_width
,
int
kernel_height
,
int
anchor_x
,
int
anchor_y
,
double
delta
,
int
borderType
)
{
{
Ptr
<
FilterEngine
>
f
;
int
borderTypeValue
=
borderType
&
~
BORDER_ISOLATED
;
int
src_type
;
Mat
kernel
=
Mat
(
Size
(
kernel_width
,
kernel_height
),
kernel_type
,
kernel_data
,
kernel_step
);
int
dst_type
;
Ptr
<
FilterEngine
>
f
=
createLinearFilter
(
stype
,
dtype
,
kernel
,
Point
(
anchor_x
,
anchor_y
),
delta
,
bool
isIsolated
;
borderTypeValue
);
Mat
src
(
Size
(
width
,
height
),
stype
,
src_data
,
src_step
);
bool
init
(
uchar
*
kernel_data
,
size_t
kernel_step
,
int
kernel_type
,
int
kernel_width
,
Mat
dst
(
Size
(
width
,
height
),
dtype
,
dst_data
,
dst_step
);
int
kernel_height
,
int
,
int
,
int
stype
,
int
dtype
,
int
borderType
,
double
delta
,
f
->
apply
(
src
,
dst
,
Size
(
full_width
,
full_height
),
Point
(
offset_x
,
offset_y
));
int
anchor_x
,
int
anchor_y
,
bool
,
bool
)
}
{
isIsolated
=
(
borderType
&
BORDER_ISOLATED
)
!=
0
;
src_type
=
stype
;
dst_type
=
dtype
;
int
borderTypeValue
=
borderType
&
~
BORDER_ISOLATED
;
Mat
kernel
=
Mat
(
Size
(
kernel_width
,
kernel_height
),
kernel_type
,
kernel_data
,
kernel_step
);
f
=
createLinearFilter
(
src_type
,
dst_type
,
kernel
,
Point
(
anchor_x
,
anchor_y
),
delta
,
borderTypeValue
);
return
true
;
}
void
apply
(
uchar
*
src_data
,
size_t
src_step
,
uchar
*
dst_data
,
size_t
dst_step
,
int
width
,
int
height
,
int
full_width
,
int
full_height
,
int
offset_x
,
int
offset_y
)
{
Mat
src
(
Size
(
width
,
height
),
src_type
,
src_data
,
src_step
);
Mat
dst
(
Size
(
width
,
height
),
dst_type
,
dst_data
,
dst_step
);
f
->
apply
(
src
,
dst
,
Size
(
full_width
,
full_height
),
Point
(
offset_x
,
offset_y
));
}
};
struct
ReplacementSepFilter
:
public
hal
::
SepFilter2D
static
bool
replacementSepFilter
(
int
stype
,
int
dtype
,
int
ktype
,
uchar
*
src_data
,
size_t
src_step
,
uchar
*
dst_data
,
size_t
dst_step
,
int
width
,
int
height
,
int
full_width
,
int
full_height
,
int
offset_x
,
int
offset_y
,
uchar
*
kernelx_data
,
int
kernelx_len
,
uchar
*
kernely_data
,
int
kernely_len
,
int
anchor_x
,
int
anchor_y
,
double
delta
,
int
borderType
)
{
{
cvhalFilter2D
*
ctx
;
cvhalFilter2D
*
ctx
;
bool
isInitialized
;
int
res
=
cv_hal_sepFilterInit
(
&
ctx
,
stype
,
dtype
,
ktype
,
ReplacementSepFilter
()
:
ctx
(
0
),
isInitialized
(
false
)
{}
kernelx_data
,
kernelx_len
,
bool
init
(
int
stype
,
int
dtype
,
int
ktype
,
kernely_data
,
kernely_len
,
uchar
*
kernelx_data
,
int
kernelx_len
,
anchor_x
,
anchor_y
,
delta
,
borderType
);
uchar
*
kernely_data
,
int
kernely_len
,
if
(
res
!=
CV_HAL_ERROR_OK
)
int
anchor_x
,
int
anchor_y
,
double
delta
,
int
borderType
)
return
false
;
{
res
=
cv_hal_sepFilter
(
ctx
,
src_data
,
src_step
,
dst_data
,
dst_step
,
width
,
height
,
full_width
,
full_height
,
offset_x
,
offset_y
);
int
res
=
cv_hal_sepFilterInit
(
&
ctx
,
stype
,
dtype
,
ktype
,
bool
success
=
(
res
==
CV_HAL_ERROR_OK
);
kernelx_data
,
kernelx_len
,
res
=
cv_hal_sepFilterFree
(
ctx
);
kernely_data
,
kernely_len
,
if
(
res
!=
CV_HAL_ERROR_OK
)
anchor_x
,
anchor_y
,
delta
,
borderType
);
return
false
;
isInitialized
=
(
res
==
CV_HAL_ERROR_OK
);
return
success
;
return
isInitialized
;
}
}
void
apply
(
uchar
*
src_data
,
size_t
src_step
,
uchar
*
dst_data
,
size_t
dst_step
,
int
width
,
int
height
,
int
full_width
,
int
full_height
,
int
offset_x
,
int
offset_y
)
{
if
(
isInitialized
)
{
int
res
=
cv_hal_sepFilter
(
ctx
,
src_data
,
src_step
,
dst_data
,
dst_step
,
width
,
height
,
full_width
,
full_height
,
offset_x
,
offset_y
);
if
(
res
!=
CV_HAL_ERROR_OK
)
CV_Error
(
Error
::
StsNotImplemented
,
"Failed to run HAL sepFilter implementation"
);
}
}
~
ReplacementSepFilter
()
{
if
(
isInitialized
)
{
int
res
=
cv_hal_sepFilterFree
(
ctx
);
if
(
res
!=
CV_HAL_ERROR_OK
)
CV_Error
(
Error
::
StsNotImplemented
,
"Failed to run HAL sepFilter implementation"
);
}
}
};
struct
OcvSepFilter
:
public
hal
::
SepFilter2D
static
void
ocvSepFilter
(
int
stype
,
int
dtype
,
int
ktype
,
uchar
*
src_data
,
size_t
src_step
,
uchar
*
dst_data
,
size_t
dst_step
,
int
width
,
int
height
,
int
full_width
,
int
full_height
,
int
offset_x
,
int
offset_y
,
uchar
*
kernelx_data
,
int
kernelx_len
,
uchar
*
kernely_data
,
int
kernely_len
,
int
anchor_x
,
int
anchor_y
,
double
delta
,
int
borderType
)
{
{
Ptr
<
FilterEngine
>
f
;
Mat
kernelX
(
Size
(
kernelx_len
,
1
),
ktype
,
kernelx_data
);
int
src_type
;
Mat
kernelY
(
Size
(
kernely_len
,
1
),
ktype
,
kernely_data
);
int
dst_type
;
Ptr
<
FilterEngine
>
f
=
createSeparableLinearFilter
(
stype
,
dtype
,
kernelX
,
kernelY
,
bool
init
(
int
stype
,
int
dtype
,
int
ktype
,
Point
(
anchor_x
,
anchor_y
),
uchar
*
kernelx_data
,
int
kernelx_len
,
delta
,
borderType
&
~
BORDER_ISOLATED
);
uchar
*
kernely_data
,
int
kernely_len
,
Mat
src
(
Size
(
width
,
height
),
stype
,
src_data
,
src_step
);
int
anchor_x
,
int
anchor_y
,
double
delta
,
int
borderType
)
Mat
dst
(
Size
(
width
,
height
),
dtype
,
dst_data
,
dst_step
);
{
f
->
apply
(
src
,
dst
,
Size
(
full_width
,
full_height
),
Point
(
offset_x
,
offset_y
));
src_type
=
stype
;
dst_type
=
dtype
;
Mat
kernelX
(
Size
(
kernelx_len
,
1
),
ktype
,
kernelx_data
);
Mat
kernelY
(
Size
(
kernely_len
,
1
),
ktype
,
kernely_data
);
f
=
createSeparableLinearFilter
(
stype
,
dtype
,
kernelX
,
kernelY
,
Point
(
anchor_x
,
anchor_y
),
delta
,
borderType
&
~
BORDER_ISOLATED
);
return
true
;
}
void
apply
(
uchar
*
src_data
,
size_t
src_step
,
uchar
*
dst_data
,
size_t
dst_step
,
int
width
,
int
height
,
int
full_width
,
int
full_height
,
int
offset_x
,
int
offset_y
)
{
Mat
src
(
Size
(
width
,
height
),
src_type
,
src_data
,
src_step
);
Mat
dst
(
Size
(
width
,
height
),
dst_type
,
dst_data
,
dst_step
);
f
->
apply
(
src
,
dst
,
Size
(
full_width
,
full_height
),
Point
(
offset_x
,
offset_y
));
}
};
};
//===================================================================
//===================================================================
...
@@ -4898,97 +4834,124 @@ struct OcvSepFilter : public hal::SepFilter2D
...
@@ -4898,97 +4834,124 @@ struct OcvSepFilter : public hal::SepFilter2D
namespace
cv
{
namespace
cv
{
namespace
hal
{
namespace
hal
{
Ptr
<
hal
::
Filter2D
>
Filter2D
::
create
(
uchar
*
kernel_data
,
size_t
kernel_step
,
int
kernel_type
,
int
kernel_width
,
int
kernel_height
,
int
max_width
,
int
max_height
,
int
stype
,
int
dtype
,
int
borderType
,
double
delta
,
int
anchor_x
,
int
anchor_y
,
bool
isSubmatrix
,
bool
isInplace
)
{
{
ReplacementFilter
*
impl
=
new
ReplacementFilter
();
if
(
impl
->
init
(
kernel_data
,
kernel_step
,
kernel_type
,
kernel_width
,
kernel_height
,
max_width
,
max_height
,
stype
,
dtype
,
borderType
,
delta
,
anchor_x
,
anchor_y
,
isSubmatrix
,
isInplace
))
{
return
Ptr
<
hal
::
Filter2D
>
(
impl
);
}
delete
impl
;
}
CV_DEPRECATED
Ptr
<
hal
::
Filter2D
>
Filter2D
::
create
(
uchar
*
,
size_t
,
int
,
int
,
int
,
int
,
int
,
int
,
int
,
int
,
double
,
int
,
int
,
bool
,
bool
)
{
return
Ptr
<
hal
::
Filter2D
>
();
}
CV_DEPRECATED
Ptr
<
hal
::
SepFilter2D
>
SepFilter2D
::
create
(
int
,
int
,
int
,
uchar
*
,
int
,
uchar
*
,
int
,
int
,
int
,
double
,
int
)
{
return
Ptr
<
hal
::
SepFilter2D
>
();
}
void
filter2D
(
int
stype
,
int
dtype
,
int
kernel_type
,
uchar
*
src_data
,
size_t
src_step
,
uchar
*
dst_data
,
size_t
dst_step
,
int
width
,
int
height
,
int
full_width
,
int
full_height
,
int
offset_x
,
int
offset_y
,
uchar
*
kernel_data
,
size_t
kernel_step
,
int
kernel_width
,
int
kernel_height
,
int
anchor_x
,
int
anchor_y
,
double
delta
,
int
borderType
,
bool
isSubmatrix
)
{
bool
res
;
res
=
replacementFilter2D
(
stype
,
dtype
,
kernel_type
,
src_data
,
src_step
,
dst_data
,
dst_step
,
width
,
height
,
full_width
,
full_height
,
offset_x
,
offset_y
,
kernel_data
,
kernel_step
,
kernel_width
,
kernel_height
,
anchor_x
,
anchor_y
,
delta
,
borderType
,
isSubmatrix
);
if
(
res
)
return
;
#ifdef HAVE_IPP
#ifdef HAVE_IPP
CV_IPP_CHECK
()
CV_IPP_CHECK
()
{
{
res
=
false
;
if
(
kernel_type
==
CV_32FC1
)
{
if
(
kernel_type
==
CV_32FC1
)
{
IppFilter
<
CV_32F
>*
impl
=
new
IppFilter
<
CV_32F
>
();
res
=
ippFilter2D
<
CV_32F
>
(
stype
,
dtype
,
if
(
impl
->
init
(
kernel_data
,
kernel_step
,
kernel_type
,
kernel_width
,
kernel_height
,
src_data
,
src_step
,
max_width
,
max_height
,
stype
,
dtype
,
dst_data
,
dst_step
,
borderType
,
delta
,
anchor_x
,
anchor_y
,
isSubmatrix
,
isInplace
))
width
,
height
,
{
kernel_data
,
kernel_step
,
return
Ptr
<
hal
::
Filter2D
>
(
impl
);
kernel_width
,
kernel_height
,
}
anchor_x
,
anchor_y
,
delete
impl
;
delta
,
borderType
,
isSubmatrix
)
;
}
}
else
if
(
kernel_type
==
CV_16SC1
)
{
if
(
kernel_type
==
CV_16SC1
)
{
res
=
ippFilter2D
<
CV_16S
>
(
stype
,
dtype
,
IppFilter
<
CV_16S
>*
impl
=
new
IppFilter
<
CV_16S
>
();
src_data
,
src_step
,
if
(
impl
->
init
(
kernel_data
,
kernel_step
,
kernel_type
,
kernel_width
,
kernel_height
,
dst_data
,
dst_step
,
max_width
,
max_height
,
stype
,
dtype
,
width
,
height
,
borderType
,
delta
,
anchor_x
,
anchor_y
,
isSubmatrix
,
isInplace
))
kernel_data
,
kernel_step
,
{
kernel_width
,
kernel_height
,
return
Ptr
<
hal
::
Filter2D
>
(
impl
);
anchor_x
,
anchor_y
,
}
delta
,
borderType
,
isSubmatrix
);
delete
impl
;
}
}
if
(
res
)
return
;
}
}
#endif
#endif
res
=
dftFilter2D
(
stype
,
dtype
,
kernel_type
,
if
(
DftFilter
::
isAppropriate
(
stype
,
dtype
,
kernel_width
,
kernel_height
))
src_data
,
src_step
,
{
dst_data
,
dst_step
,
DftFilter
*
impl
=
new
DftFilter
();
width
,
height
,
if
(
impl
->
init
(
kernel_data
,
kernel_step
,
kernel_type
,
kernel_width
,
kernel_height
,
kernel_data
,
kernel_step
,
max_width
,
max_height
,
stype
,
dtype
,
kernel_width
,
kernel_height
,
borderType
,
delta
,
anchor_x
,
anchor_y
,
isSubmatrix
,
isInplace
))
anchor_x
,
anchor_y
,
{
delta
,
borderType
);
return
Ptr
<
hal
::
Filter2D
>
(
impl
);
if
(
res
)
}
return
;
delete
impl
;
ocvFilter2D
(
stype
,
dtype
,
kernel_type
,
}
src_data
,
src_step
,
dst_data
,
dst_step
,
{
width
,
height
,
OcvFilter
*
impl
=
new
OcvFilter
();
full_width
,
full_height
,
impl
->
init
(
kernel_data
,
kernel_step
,
kernel_type
,
kernel_width
,
kernel_height
,
offset_x
,
offset_y
,
max_width
,
max_height
,
stype
,
dtype
,
kernel_data
,
kernel_step
,
borderType
,
delta
,
anchor_x
,
anchor_y
,
isSubmatrix
,
isInplace
);
kernel_width
,
kernel_height
,
return
Ptr
<
hal
::
Filter2D
>
(
impl
);
anchor_x
,
anchor_y
,
}
delta
,
borderType
);
}
}
//---------------------------------------------------------------
//---------------------------------------------------------------
Ptr
<
SepFilter2D
>
SepFilter2D
::
create
(
int
stype
,
int
dtype
,
int
ktype
,
void
sepFilter2D
(
int
stype
,
int
dtype
,
int
ktype
,
uchar
*
kernelx_data
,
int
kernelx_len
,
uchar
*
src_data
,
size_t
src_step
,
uchar
*
dst_data
,
size_t
dst_step
,
uchar
*
kernely_data
,
int
kernely_len
,
int
width
,
int
height
,
int
full_width
,
int
full_height
,
int
anchor_x
,
int
anchor_y
,
double
delta
,
int
borderType
)
int
offset_x
,
int
offset_y
,
uchar
*
kernelx_data
,
int
kernelx_len
,
uchar
*
kernely_data
,
int
kernely_len
,
int
anchor_x
,
int
anchor_y
,
double
delta
,
int
borderType
)
{
{
{
ReplacementSepFilter
*
impl
=
new
ReplacementSepFilter
();
bool
res
=
replacementSepFilter
(
stype
,
dtype
,
ktype
,
if
(
impl
->
init
(
stype
,
dtype
,
ktype
,
src_data
,
src_step
,
dst_data
,
dst_step
,
kernelx_data
,
kernelx_len
,
width
,
height
,
full_width
,
full_height
,
kernely_data
,
kernely_len
,
offset_x
,
offset_y
,
anchor_x
,
anchor_y
,
delta
,
borderType
))
kernelx_data
,
kernelx_len
,
{
kernely_data
,
kernely_len
,
return
Ptr
<
hal
::
SepFilter2D
>
(
impl
);
anchor_x
,
anchor_y
,
delta
,
borderType
);
}
if
(
res
)
delete
impl
;
return
;
}
ocvSepFilter
(
stype
,
dtype
,
ktype
,
{
src_data
,
src_step
,
dst_data
,
dst_step
,
OcvSepFilter
*
impl
=
new
OcvSepFilter
();
width
,
height
,
full_width
,
full_height
,
impl
->
init
(
stype
,
dtype
,
ktype
,
offset_x
,
offset_y
,
kernelx_data
,
kernelx_len
,
kernelx_data
,
kernelx_len
,
kernely_data
,
kernely_len
,
kernely_data
,
kernely_len
,
anchor_x
,
anchor_y
,
delta
,
borderType
);
anchor_x
,
anchor_y
,
delta
,
borderType
);
return
Ptr
<
hal
::
SepFilter2D
>
(
impl
);
}
}
}
}
// cv::hal::
}
// cv::hal::
...
@@ -5021,10 +4984,12 @@ void cv::filter2D( InputArray _src, OutputArray _dst, int ddepth,
...
@@ -5021,10 +4984,12 @@ void cv::filter2D( InputArray _src, OutputArray _dst, int ddepth,
if
(
(
borderType
&
BORDER_ISOLATED
)
==
0
)
if
(
(
borderType
&
BORDER_ISOLATED
)
==
0
)
src
.
locateROI
(
wsz
,
ofs
);
src
.
locateROI
(
wsz
,
ofs
);
Ptr
<
hal
::
Filter2D
>
c
=
hal
::
Filter2D
::
create
(
kernel
.
data
,
kernel
.
step
,
kernel
.
type
(),
kernel
.
cols
,
kernel
.
rows
,
hal
::
filter2D
(
src
.
type
(),
dst
.
type
(),
kernel
.
type
(),
dst
.
cols
,
dst
.
rows
,
src
.
type
(),
dst
.
type
(),
src
.
data
,
src
.
step
,
dst
.
data
,
dst
.
step
,
borderType
,
delta
,
anchor
.
x
,
anchor
.
y
,
src
.
isSubmatrix
(),
src
.
data
==
dst
.
data
);
dst
.
cols
,
dst
.
rows
,
wsz
.
width
,
wsz
.
height
,
ofs
.
x
,
ofs
.
y
,
c
->
apply
(
src
.
data
,
src
.
step
,
dst
.
data
,
dst
.
step
,
dst
.
cols
,
dst
.
rows
,
wsz
.
width
,
wsz
.
height
,
ofs
.
x
,
ofs
.
y
);
kernel
.
data
,
kernel
.
step
,
kernel
.
cols
,
kernel
.
rows
,
anchor
.
x
,
anchor
.
y
,
delta
,
borderType
,
src
.
isSubmatrix
());
}
}
void
cv
::
sepFilter2D
(
InputArray
_src
,
OutputArray
_dst
,
int
ddepth
,
void
cv
::
sepFilter2D
(
InputArray
_src
,
OutputArray
_dst
,
int
ddepth
,
...
@@ -5055,11 +5020,13 @@ void cv::sepFilter2D( InputArray _src, OutputArray _dst, int ddepth,
...
@@ -5055,11 +5020,13 @@ void cv::sepFilter2D( InputArray _src, OutputArray _dst, int ddepth,
Mat
contKernelX
=
kernelX
.
isContinuous
()
?
kernelX
:
kernelX
.
clone
();
Mat
contKernelX
=
kernelX
.
isContinuous
()
?
kernelX
:
kernelX
.
clone
();
Mat
contKernelY
=
kernelY
.
isContinuous
()
?
kernelY
:
kernelY
.
clone
();
Mat
contKernelY
=
kernelY
.
isContinuous
()
?
kernelY
:
kernelY
.
clone
();
Ptr
<
hal
::
SepFilter2D
>
c
=
hal
::
SepFilter2D
::
create
(
src
.
type
(),
dst
.
type
(),
kernelX
.
type
(),
contKernelX
.
data
,
kernelX
.
cols
+
kernelX
.
rows
-
1
,
hal
::
sepFilter2D
(
src
.
type
(),
dst
.
type
(),
kernelX
.
type
(),
contKernelY
.
data
,
kernelY
.
cols
+
kernelY
.
rows
-
1
,
src
.
data
,
src
.
step
,
dst
.
data
,
dst
.
step
,
anchor
.
x
,
anchor
.
y
,
delta
,
borderType
&
~
BORDER_ISOLATED
);
dst
.
cols
,
dst
.
rows
,
wsz
.
width
,
wsz
.
height
,
ofs
.
x
,
ofs
.
y
,
c
->
apply
(
src
.
data
,
src
.
step
,
dst
.
data
,
dst
.
step
,
dst
.
cols
,
dst
.
rows
,
wsz
.
width
,
wsz
.
height
,
ofs
.
x
,
ofs
.
y
);
contKernelX
.
data
,
kernelX
.
cols
+
kernelX
.
rows
-
1
,
contKernelY
.
data
,
kernelY
.
cols
+
kernelY
.
rows
-
1
,
anchor
.
x
,
anchor
.
y
,
delta
,
borderType
&
~
BORDER_ISOLATED
);
}
}
...
...
modules/imgproc/src/morph.cpp
View file @
c4c1c4c9
...
@@ -1079,49 +1079,38 @@ namespace cv
...
@@ -1079,49 +1079,38 @@ namespace cv
// ===== 1. replacement implementation
// ===== 1. replacement implementation
struct
ReplacementMorphImpl
:
public
hal
::
Morph
static
bool
halMorph
(
int
op
,
int
src_type
,
int
dst_type
,
uchar
*
src_data
,
size_t
src_step
,
uchar
*
dst_data
,
size_t
dst_step
,
int
width
,
int
height
,
int
roi_width
,
int
roi_height
,
int
roi_x
,
int
roi_y
,
int
roi_width2
,
int
roi_height2
,
int
roi_x2
,
int
roi_y2
,
int
kernel_type
,
uchar
*
kernel_data
,
size_t
kernel_step
,
int
kernel_width
,
int
kernel_height
,
int
anchor_x
,
int
anchor_y
,
int
borderType
,
const
double
borderValue
[
4
],
int
iterations
,
bool
isSubmatrix
)
{
{
cvhalFilter2D
*
ctx
;
cvhalFilter2D
*
ctx
;
bool
isInitialized
;
int
res
=
cv_hal_morphInit
(
&
ctx
,
op
,
src_type
,
dst_type
,
width
,
height
,
bool
init
(
int
op
,
int
src_type
,
int
dst_type
,
int
max_width
,
int
max_height
,
kernel_type
,
kernel_data
,
kernel_step
,
kernel_width
,
kernel_height
,
int
kernel_type
,
uchar
*
kernel_data
,
size_t
kernel_step
,
int
kernel_width
,
int
kernel_height
,
anchor_x
,
anchor_y
,
int
anchor_x
,
int
anchor_y
,
borderType
,
borderValue
,
int
borderType
,
const
double
borderValue
[
4
],
iterations
,
isSubmatrix
,
src_data
==
dst_data
);
int
iterations
,
bool
isSubmatrix
,
bool
allowInplace
)
if
(
res
!=
CV_HAL_ERROR_OK
)
{
return
false
;
int
res
=
cv_hal_morphInit
(
&
ctx
,
op
,
src_type
,
dst_type
,
max_width
,
max_height
,
kernel_type
,
kernel_data
,
kernel_step
,
kernel_width
,
kernel_height
,
res
=
cv_hal_morph
(
ctx
,
src_data
,
src_step
,
dst_data
,
dst_step
,
width
,
height
,
anchor_x
,
anchor_y
,
roi_width
,
roi_height
,
borderType
,
borderValue
,
roi_x
,
roi_y
,
iterations
,
isSubmatrix
,
allowInplace
);
roi_width2
,
roi_height2
,
isInitialized
=
(
res
==
CV_HAL_ERROR_OK
);
roi_x2
,
roi_y2
);
return
isInitialized
;
bool
success
=
(
res
==
CV_HAL_ERROR_OK
);
}
void
apply
(
uchar
*
src_data
,
size_t
src_step
,
uchar
*
dst_data
,
size_t
dst_step
,
int
width
,
int
height
,
res
=
cv_hal_morphFree
(
ctx
);
int
roi_width
,
int
roi_height
,
int
roi_x
,
int
roi_y
,
if
(
res
!=
CV_HAL_ERROR_OK
)
int
roi_width2
,
int
roi_height2
,
int
roi_x2
,
int
roi_y2
)
return
false
;
{
if
(
isInitialized
)
return
success
;
{
}
int
res
=
cv_hal_morph
(
ctx
,
src_data
,
src_step
,
dst_data
,
dst_step
,
width
,
height
,
roi_width
,
roi_height
,
roi_x
,
roi_y
,
roi_width2
,
roi_height2
,
roi_x2
,
roi_y2
);
if
(
res
!=
CV_HAL_ERROR_OK
)
CV_Error
(
Error
::
StsNotImplemented
,
"Failed to run HAL morph implementation"
);
}
}
~
ReplacementMorphImpl
()
{
if
(
isInitialized
)
{
int
res
=
cv_hal_morphFree
(
ctx
);
if
(
res
!=
CV_HAL_ERROR_OK
)
CV_Error
(
Error
::
StsNotImplemented
,
"Failed to run HAL morph implementation"
);
}
}
};
// ===== 2. IPP implementation
// ===== 2. IPP implementation
...
@@ -1133,7 +1122,7 @@ template <int cvtype> struct IppMorphTrait {};
...
@@ -1133,7 +1122,7 @@ template <int cvtype> struct IppMorphTrait {};
#if IPP_VERSION_X100 >= 900
#if IPP_VERSION_X100 >= 900
#define
INIT
_TRAIT(cvtype, ipptype, flavor, channels, zerodef)\
#define
DEFINE
_TRAIT(cvtype, ipptype, flavor, channels, zerodef)\
template <>\
template <>\
struct IppMorphTrait<cvtype>\
struct IppMorphTrait<cvtype>\
{\
{\
...
@@ -1153,7 +1142,7 @@ struct IppMorphTrait<cvtype>\
...
@@ -1153,7 +1142,7 @@ struct IppMorphTrait<cvtype>\
#else
#else
#define
INIT
_TRAIT(cvtype, ipptype, flavor, channels, zerodef)\
#define
DEFINE
_TRAIT(cvtype, ipptype, flavor, channels, zerodef)\
template <>\
template <>\
struct IppMorphTrait<cvtype>\
struct IppMorphTrait<cvtype>\
{\
{\
...
@@ -1173,28 +1162,28 @@ struct IppMorphTrait<cvtype>\
...
@@ -1173,28 +1162,28 @@ struct IppMorphTrait<cvtype>\
#endif
#endif
INIT
_TRAIT
(
CV_8UC1
,
8u
,
8u
_C1R
,
1
,
zero
=
0
)
DEFINE
_TRAIT
(
CV_8UC1
,
8u
,
8u
_C1R
,
1
,
zero
=
0
)
INIT
_TRAIT
(
CV_8UC3
,
8u
,
8u
_C3R
,
3
,
zero
[
3
]
=
{
0
})
DEFINE
_TRAIT
(
CV_8UC3
,
8u
,
8u
_C3R
,
3
,
zero
[
3
]
=
{
0
})
INIT
_TRAIT
(
CV_8UC4
,
8u
,
8u
_C4R
,
4
,
zero
[
4
]
=
{
0
})
DEFINE
_TRAIT
(
CV_8UC4
,
8u
,
8u
_C4R
,
4
,
zero
[
4
]
=
{
0
})
INIT
_TRAIT
(
CV_32FC1
,
32
f
,
32
f_C1R
,
1
,
zero
=
0
)
DEFINE
_TRAIT
(
CV_32FC1
,
32
f
,
32
f_C1R
,
1
,
zero
=
0
)
INIT
_TRAIT
(
CV_32FC3
,
32
f
,
32
f_C3R
,
3
,
zero
[
3
]
=
{
0
})
DEFINE
_TRAIT
(
CV_32FC3
,
32
f
,
32
f_C3R
,
3
,
zero
[
3
]
=
{
0
})
INIT
_TRAIT
(
CV_32FC4
,
32
f
,
32
f_C4R
,
4
,
zero
[
4
]
=
{
0
})
DEFINE
_TRAIT
(
CV_32FC4
,
32
f
,
32
f_C4R
,
4
,
zero
[
4
]
=
{
0
})
#undef
INIT
_TRAIT
#undef
DEFINE
_TRAIT
//--------------------------------------
//--------------------------------------
struct
IppMorphBaseImpl
:
public
hal
::
Morph
{
virtual
bool
init
(
int
_op
,
int
_src_type
,
int
dst_type
,
int
max_width
,
int
max_height
,
int
kernel_type
,
uchar
*
kernel_data
,
size_t
kernel_step
,
int
kernel_width
,
int
kernel_height
,
int
anchor_x
,
int
anchor_y
,
int
borderType
,
const
double
borderValue
[
4
],
int
iterations
,
bool
isSubmatrix
,
bool
allowInplace
)
=
0
;
};
template
<
int
cvtype
>
template
<
int
cvtype
>
struct
IppMorphImpl
:
public
IppMorphBaseImpl
static
bool
ippMorph
(
int
op
,
int
src_type
,
int
dst_type
,
const
uchar
*
src_data
,
size_t
src_step
,
uchar
*
dst_data
,
size_t
dst_step
,
int
width
,
int
height
,
int
roi_width
,
int
roi_height
,
int
roi_x
,
int
roi_y
,
int
roi_width2
,
int
roi_height2
,
int
roi_x2
,
int
roi_y2
,
int
kernel_type
,
uchar
*
kernel_data
,
size_t
kernel_step
,
int
kernel_width
,
int
kernel_height
,
int
anchor_x
,
int
anchor_y
,
int
borderType
,
const
double
borderValue
[
4
],
int
iterations
,
bool
isSubmatrix
)
{
{
IppMorphTrait
<
cvtype
>
trait
;
IppMorphTrait
<
cvtype
>
trait
;
typedef
typename
IppMorphTrait
<
cvtype
>::
ipp_data_type
ipp_data_type
;
typedef
typename
IppMorphTrait
<
cvtype
>::
ipp_data_type
ipp_data_type
;
...
@@ -1203,177 +1192,136 @@ struct IppMorphImpl : public IppMorphBaseImpl
...
@@ -1203,177 +1192,136 @@ struct IppMorphImpl : public IppMorphBaseImpl
IppiSize
kernelSize
;
IppiSize
kernelSize
;
bool
rectKernel
;
bool
rectKernel
;
IppiPoint
anchor
;
IppiPoint
anchor
;
int
op
;
int
src_type
;
int
border
;
bool
init
(
int
_op
,
int
_src_type
,
int
dst_type
,
int
max_width
,
int
max_height
,
int
kernel_type
,
uchar
*
kernel_data
,
size_t
kernel_step
,
int
kernel_width
,
int
kernel_height
,
int
anchor_x
,
int
anchor_y
,
int
borderType
,
const
double
borderValue
[
4
],
int
iterations
,
bool
isSubmatrix
,
bool
allowInplace
)
{
border
=
borderType
;
// TODO: remove
anchor
=
ippiPoint
(
anchor_x
,
anchor_y
);
CV_UNUSED
(
dst_type
);
src_type
=
_src_type
;
Mat
kernel
(
Size
(
kernel_width
,
kernel_height
),
kernel_type
,
kernel_data
,
kernel_step
);
int
depth
=
CV_MAT_DEPTH
(
src_type
),
cn
=
CV_MAT_CN
(
src_type
);
if
(
!
(
depth
==
CV_8U
||
depth
==
CV_32F
)
||
!
(
cn
==
1
||
cn
==
3
||
cn
==
4
)
||
!
(
borderType
==
cv
::
BORDER_REPLICATE
||
(
borderType
==
cv
::
BORDER_CONSTANT
&&
Vec
<
double
,
4
>
(
borderValue
)
==
morphologyDefaultBorderValue
()
&&
kernel
.
size
()
==
Size
(
3
,
3
)))
||
!
(
op
==
MORPH_DILATE
||
op
==
MORPH_ERODE
)
||
isSubmatrix
||
allowInplace
)
return
false
;
// In case BORDER_CONSTANT, IPPMorphReplicate works correct with kernels of size 3*3 only
CV_INSTRUMENT_REGION_IPP
()
if
(
borderType
==
cv
::
BORDER_CONSTANT
&&
kernel
.
data
)
{
int
x
,
y
;
for
(
y
=
0
;
y
<
kernel
.
rows
;
y
++
)
{
if
(
kernel
.
at
<
uchar
>
(
y
,
anchor
.
x
)
!=
0
)
continue
;
for
(
x
=
0
;
x
<
kernel
.
cols
;
x
++
)
{
if
(
kernel
.
at
<
uchar
>
(
y
,
x
)
!=
0
)
return
false
;
}
}
for
(
x
=
0
;
x
<
kernel
.
cols
;
x
++
)
{
if
(
kernel
.
at
<
uchar
>
(
anchor
.
y
,
x
)
!=
0
)
continue
;
for
(
y
=
0
;
y
<
kernel
.
rows
;
y
++
)
{
if
(
kernel
.
at
<
uchar
>
(
y
,
x
)
!=
0
)
return
false
;
}
}
}
CV_UNUSED
(
roi_width
);
CV_UNUSED
(
roi_height
);
CV_UNUSED
(
roi_x
);
CV_UNUSED
(
roi_y
);
CV_UNUSED
(
roi_width2
);
CV_UNUSED
(
roi_height2
);
CV_UNUSED
(
roi_x2
);
CV_UNUSED
(
roi_y2
);
Size
ksize
=
!
kernel
.
empty
()
?
kernel
.
size
()
:
Size
(
3
,
3
);
CV_UNUSED
(
dst_type
);
rectKernel
=
false
;
anchor
=
ippiPoint
(
anchor_x
,
anchor_y
);
if
(
kernel
.
empty
()
)
{
ksize
=
Size
(
1
+
iterations
*
2
,
1
+
iterations
*
2
);
anchor
=
ippiPoint
(
iterations
,
iterations
);
rectKernel
=
true
;
iterations
=
1
;
}
else
if
(
iterations
>=
1
&&
countNonZero
(
kernel
)
==
kernel
.
rows
*
kernel
.
cols
)
{
ksize
=
Size
(
ksize
.
width
+
(
iterations
-
1
)
*
(
ksize
.
width
-
1
),
ksize
.
height
+
(
iterations
-
1
)
*
(
ksize
.
height
-
1
)),
anchor
=
ippiPoint
(
anchor
.
x
*
iterations
,
anchor
.
y
*
iterations
);
kernel
=
Mat
();
rectKernel
=
true
;
iterations
=
1
;
}
// TODO: implement the case of iterations > 1.
Mat
kernel
(
Size
(
kernel_width
,
kernel_height
),
kernel_type
,
kernel_data
,
kernel_step
);
if
(
iterations
>
1
)
int
depth
=
CV_MAT_DEPTH
(
src_type
),
cn
=
CV_MAT_CN
(
src_type
);
return
false
;
IppiSize
roiSize
=
{
max_width
,
max_height
};
if
(
!
(
depth
==
CV_8U
||
depth
==
CV_32F
)
kernelSize
=
ippiSize
(
ksize
);
||
!
(
cn
==
1
||
cn
==
3
||
cn
==
4
)
op
=
_op
;
||
!
(
borderType
==
cv
::
BORDER_REPLICATE
||
(
borderType
==
cv
::
BORDER_CONSTANT
&&
Vec
<
double
,
4
>
(
borderValue
)
==
morphologyDefaultBorderValue
()
&&
kernel
.
size
()
==
Size
(
3
,
3
)))
||
!
(
op
==
MORPH_DILATE
||
op
==
MORPH_ERODE
)
||
isSubmatrix
||
src_data
==
dst_data
)
return
false
;
IppStatus
res
;
// In case BORDER_CONSTANT, IPPMorphReplicate works correct with kernels of size 3*3 only
if
(
!
rectKernel
)
if
(
borderType
==
cv
::
BORDER_CONSTANT
&&
kernel
.
data
)
{
int
x
,
y
;
for
(
y
=
0
;
y
<
kernel
.
rows
;
y
++
)
{
{
if
(((
kernel
.
cols
-
1
)
/
2
!=
anchor
.
x
)
||
((
kernel
.
rows
-
1
)
/
2
!=
anchor
.
y
))
if
(
kernel
.
at
<
uchar
>
(
y
,
anchor
.
x
)
!=
0
)
return
false
;
continue
;
int
specSize
=
0
,
bufferSize
=
0
;
for
(
x
=
0
;
x
<
kernel
.
cols
;
x
++
)
res
=
trait
.
getMorphSize
(
roiSize
,
kernelSize
,
&
specSize
,
&
bufferSize
);
if
(
res
>=
0
)
{
{
specBuf
.
Alloc
(
specSize
);
if
(
kernel
.
at
<
uchar
>
(
y
,
x
)
!=
0
)
workBuf
.
Alloc
(
bufferSize
);
return
false
;
res
=
trait
.
morphInit
(
roiSize
,
kernel
.
ptr
(),
kernelSize
,
specBuf
,
workBuf
);
if
(
res
>=
0
)
return
true
;
}
}
}
}
else
for
(
x
=
0
;
x
<
kernel
.
cols
;
x
++
)
{
{
if
(((
kernelSize
.
width
-
1
)
/
2
!=
anchor
.
x
)
||
((
kernelSize
.
height
-
1
)
/
2
!=
anchor
.
y
))
if
(
kernel
.
at
<
uchar
>
(
anchor
.
y
,
x
)
!=
0
)
return
false
;
continue
;
if
(
op
==
MORPH_ERODE
)
for
(
y
=
0
;
y
<
kernel
.
rows
;
y
++
)
{
int
bufSize
=
0
;
res
=
trait
.
filterGetMinSize
(
roiSize
,
kernelSize
,
trait
.
getDataType
(),
trait
.
cn
,
&
bufSize
);
if
(
res
>=
0
)
{
workBuf
.
Alloc
(
bufSize
);
return
true
;
}
}
else
{
{
int
bufSize
=
0
;
if
(
kernel
.
at
<
uchar
>
(
y
,
x
)
!=
0
)
res
=
trait
.
filterGetMaxSize
(
roiSize
,
kernelSize
,
trait
.
getDataType
(),
trait
.
cn
,
&
bufSize
);
return
false
;
if
(
res
>=
0
)
{
workBuf
.
Alloc
(
bufSize
);
return
true
;
}
}
}
}
}
return
false
;
}
}
void
apply
(
uchar
*
src_data
,
size_t
src_step
,
uchar
*
dst_data
,
size_t
dst_step
,
int
width
,
int
height
,
Size
ksize
=
!
kernel
.
empty
()
?
kernel
.
size
()
:
Size
(
3
,
3
);
int
roi_width
,
int
roi_height
,
int
roi_x
,
int
roi_y
,
int
roi_width2
,
int
roi_height2
,
int
roi_x2
,
int
roi_y2
)
rectKernel
=
false
;
if
(
kernel
.
empty
()
)
{
{
CV_INSTRUMENT_REGION_IPP
()
ksize
=
Size
(
1
+
iterations
*
2
,
1
+
iterations
*
2
);
anchor
=
ippiPoint
(
iterations
,
iterations
);
rectKernel
=
true
;
iterations
=
1
;
}
else
if
(
iterations
>=
1
&&
countNonZero
(
kernel
)
==
kernel
.
rows
*
kernel
.
cols
)
{
ksize
=
Size
(
ksize
.
width
+
(
iterations
-
1
)
*
(
ksize
.
width
-
1
),
ksize
.
height
+
(
iterations
-
1
)
*
(
ksize
.
height
-
1
)),
anchor
=
ippiPoint
(
anchor
.
x
*
iterations
,
anchor
.
y
*
iterations
);
kernel
=
Mat
();
rectKernel
=
true
;
iterations
=
1
;
}
CV_UNUSED
(
roi_width
);
CV_UNUSED
(
roi_height
);
CV_UNUSED
(
roi_x
);
CV_UNUSED
(
roi_y
);
// TODO: implement the case of iterations > 1.
CV_UNUSED
(
roi_width2
);
CV_UNUSED
(
roi_height2
);
CV_UNUSED
(
roi_x2
);
CV_UNUSED
(
roi_y2
);
if
(
iterations
>
1
)
if
(
src_data
==
dst_data
)
return
false
;
CV_Error
(
Error
::
StsBadArg
,
"IPP Morph inplace is not alowed"
);
IppiSize
roiSize
=
{
width
,
height
};
IppiSize
roiSize
=
{
width
,
height
};
kernelSize
=
ippiSize
(
ksize
);
IppStatus
res
;
IppStatus
res
;
if
(
!
rectKernel
)
if
(
!
rectKernel
)
{
if
(((
kernel
.
cols
-
1
)
/
2
!=
anchor
.
x
)
||
((
kernel
.
rows
-
1
)
/
2
!=
anchor
.
y
))
return
false
;
int
specSize
=
0
,
bufferSize
=
0
;
res
=
trait
.
getMorphSize
(
roiSize
,
kernelSize
,
&
specSize
,
&
bufferSize
);
if
(
res
>=
0
)
{
specBuf
.
Alloc
(
specSize
);
workBuf
.
Alloc
(
bufferSize
);
res
=
trait
.
morphInit
(
roiSize
,
kernel
.
ptr
(),
kernelSize
,
specBuf
,
workBuf
);
if
(
res
<
0
)
return
false
;
}
}
else
{
if
(((
kernelSize
.
width
-
1
)
/
2
!=
anchor
.
x
)
||
((
kernelSize
.
height
-
1
)
/
2
!=
anchor
.
y
))
return
false
;
if
(
op
==
MORPH_ERODE
)
{
{
if
(
op
==
MORPH_ERODE
)
int
bufSize
=
0
;
res
=
(
trait
.
morphErode
((
ipp_data_type
*
)
src_data
,
(
int
)
src_step
,
(
ipp_data_type
*
)
dst_data
,
(
int
)
dst_step
,
roiSize
,
specBuf
,
workBuf
));
res
=
trait
.
filterGetMinSize
(
roiSize
,
kernelSize
,
trait
.
getDataType
(),
trait
.
cn
,
&
bufSize
);
if
(
res
>=
0
)
workBuf
.
Alloc
(
bufSize
);
else
else
re
s
=
(
trait
.
morphDilate
((
ipp_data_type
*
)
src_data
,
(
int
)
src_step
,
(
ipp_data_type
*
)
dst_data
,
(
int
)
dst_step
,
roiSize
,
specBuf
,
workBuf
))
;
re
turn
false
;
}
}
else
else
{
{
if
(
op
==
MORPH_ERODE
)
int
bufSize
=
0
;
res
=
(
trait
.
filterMinBorder
((
ipp_data_type
*
)
src_data
,
(
int
)
src_step
,
(
ipp_data_type
*
)
dst_data
,
(
int
)
dst_step
,
roiSize
,
kernelSize
,
anchor
,
workBuf
));
res
=
trait
.
filterGetMaxSize
(
roiSize
,
kernelSize
,
trait
.
getDataType
(),
trait
.
cn
,
&
bufSize
);
if
(
res
>=
0
)
workBuf
.
Alloc
(
bufSize
);
else
else
re
s
=
(
trait
.
filterMaxBorder
((
ipp_data_type
*
)
src_data
,
(
int
)
src_step
,
(
ipp_data_type
*
)
dst_data
,
(
int
)
dst_step
,
roiSize
,
kernelSize
,
anchor
,
workBuf
))
;
re
turn
false
;
}
}
if
(
res
<
0
)
CV_Error
(
Error
::
StsBadArg
,
"Failed to run IPP morph"
);
}
}
};
static
IppMorphBaseImpl
*
createIppImpl
(
int
type
)
if
(
!
rectKernel
)
{
switch
(
type
)
{
{
case
CV_8UC1
:
return
new
IppMorphImpl
<
CV_8UC1
>
();
if
(
op
==
MORPH_ERODE
)
case
CV_8UC3
:
return
new
IppMorphImpl
<
CV_8UC3
>
();
res
=
(
trait
.
morphErode
((
ipp_data_type
*
)
src_data
,
(
int
)
src_step
,
(
ipp_data_type
*
)
dst_data
,
(
int
)
dst_step
,
roiSize
,
specBuf
,
workBuf
));
case
CV_8UC4
:
return
new
IppMorphImpl
<
CV_8UC4
>
();
else
case
CV_32FC1
:
return
new
IppMorphImpl
<
CV_32FC1
>
();
res
=
(
trait
.
morphDilate
((
ipp_data_type
*
)
src_data
,
(
int
)
src_step
,
(
ipp_data_type
*
)
dst_data
,
(
int
)
dst_step
,
roiSize
,
specBuf
,
workBuf
));
case
CV_32FC3
:
return
new
IppMorphImpl
<
CV_32FC3
>
();
case
CV_32FC4
:
return
new
IppMorphImpl
<
CV_32FC4
>
();
}
}
return
0
;
else
{
if
(
op
==
MORPH_ERODE
)
res
=
(
trait
.
filterMinBorder
((
ipp_data_type
*
)
src_data
,
(
int
)
src_step
,
(
ipp_data_type
*
)
dst_data
,
(
int
)
dst_step
,
roiSize
,
kernelSize
,
anchor
,
workBuf
));
else
res
=
(
trait
.
filterMaxBorder
((
ipp_data_type
*
)
src_data
,
(
int
)
src_step
,
(
ipp_data_type
*
)
dst_data
,
(
int
)
dst_step
,
roiSize
,
kernelSize
,
anchor
,
workBuf
));
}
return
res
>=
0
;
}
}
#endif // IPP_VERSION_X100 >= 810
#endif // IPP_VERSION_X100 >= 810
...
@@ -1381,94 +1329,108 @@ static IppMorphBaseImpl * createIppImpl(int type)
...
@@ -1381,94 +1329,108 @@ static IppMorphBaseImpl * createIppImpl(int type)
// ===== 3. Fallback implementation
// ===== 3. Fallback implementation
struct
OcvMorphImpl
:
public
hal
::
Morph
static
void
ocvMorph
(
int
op
,
int
src_type
,
int
dst_type
,
uchar
*
src_data
,
size_t
src_step
,
uchar
*
dst_data
,
size_t
dst_step
,
int
width
,
int
height
,
int
roi_width
,
int
roi_height
,
int
roi_x
,
int
roi_y
,
int
roi_width2
,
int
roi_height2
,
int
roi_x2
,
int
roi_y2
,
int
kernel_type
,
uchar
*
kernel_data
,
size_t
kernel_step
,
int
kernel_width
,
int
kernel_height
,
int
anchor_x
,
int
anchor_y
,
int
borderType
,
const
double
borderValue
[
4
],
int
iterations
)
{
{
Ptr
<
FilterEngine
>
f
;
Mat
kernel
(
Size
(
kernel_width
,
kernel_height
),
kernel_type
,
kernel_data
,
kernel_step
);
int
iterations
;
Point
anchor
(
anchor_x
,
anchor_y
);
int
src_type
;
Vec
<
double
,
4
>
borderVal
(
borderValue
);
int
dst_type
;
Ptr
<
FilterEngine
>
f
=
createMorphologyFilter
(
op
,
src_type
,
kernel
,
anchor
,
borderType
,
borderType
,
borderVal
);
bool
init
(
int
op
,
int
_src_type
,
int
_dst_type
,
int
,
int
,
Mat
src
(
Size
(
width
,
height
),
src_type
,
src_data
,
src_step
);
int
kernel_type
,
uchar
*
kernel_data
,
size_t
kernel_step
,
int
kernel_width
,
int
kernel_height
,
Mat
dst
(
Size
(
width
,
height
),
dst_type
,
dst_data
,
dst_step
);
int
anchor_x
,
int
anchor_y
,
int
borderType
,
const
double
_borderValue
[
4
],
int
_iterations
,
bool
,
bool
)
{
{
iterations
=
_iterations
;
Point
ofs
(
roi_x
,
roi_y
);
src_type
=
_src_type
;
Size
wsz
(
roi_width
,
roi_height
);
dst_type
=
_dst_type
;
f
->
apply
(
src
,
dst
,
wsz
,
ofs
);
Mat
kernel
(
Size
(
kernel_width
,
kernel_height
),
kernel_type
,
kernel_data
,
kernel_step
);
Point
anchor
(
anchor_x
,
anchor_y
);
Vec
<
double
,
4
>
borderValue
(
_borderValue
);
f
=
createMorphologyFilter
(
op
,
src_type
,
kernel
,
anchor
,
borderType
,
borderType
,
borderValue
);
return
true
;
}
}
void
apply
(
uchar
*
src_data
,
size_t
src_step
,
uchar
*
dst_data
,
size_t
dst_step
,
int
width
,
int
height
,
int
roi_width
,
int
roi_height
,
int
roi_x
,
int
roi_y
,
int
roi_width2
,
int
roi_height2
,
int
roi_x2
,
int
roi_y2
)
{
{
Mat
src
(
Size
(
width
,
height
),
src_type
,
src_data
,
src_step
);
Point
ofs
(
roi_x2
,
roi_y2
);
Mat
dst
(
Size
(
width
,
height
),
dst_type
,
dst_data
,
dst_step
);
Size
wsz
(
roi_width2
,
roi_height2
);
{
for
(
int
i
=
1
;
i
<
iterations
;
i
++
)
Point
ofs
(
roi_x
,
roi_y
);
f
->
apply
(
dst
,
dst
,
wsz
,
ofs
);
Size
wsz
(
roi_width
,
roi_height
);
f
->
apply
(
src
,
dst
,
wsz
,
ofs
);
}
{
Point
ofs
(
roi_x2
,
roi_y2
);
Size
wsz
(
roi_width2
,
roi_height2
);
for
(
int
i
=
1
;
i
<
iterations
;
i
++
)
f
->
apply
(
dst
,
dst
,
wsz
,
ofs
);
}
}
}
};
}
// ===== HAL interface implementation
// ===== HAL interface implementation
namespace
hal
{
namespace
hal
{
Ptr
<
Morph
>
Morph
::
create
(
int
op
,
int
src_type
,
int
dst_type
,
int
max_width
,
int
max_height
,
int
kernel_type
,
uchar
*
kernel_data
,
size_t
kernel_step
,
int
kernel_width
,
int
kernel_height
,
CV_DEPRECATED
Ptr
<
Morph
>
Morph
::
create
(
int
,
int
,
int
,
int
,
int
,
int
anchor_x
,
int
anchor_y
,
int
,
uchar
*
,
size_t
,
int
borderType
,
const
double
borderValue
[
4
],
int
,
int
,
int
iterations
,
bool
isSubmatrix
,
bool
allowInplace
)
int
,
int
,
int
,
const
double
*
,
int
,
bool
,
bool
)
{
return
Ptr
<
hal
::
Morph
>
();
}
void
morph
(
int
op
,
int
src_type
,
int
dst_type
,
uchar
*
src_data
,
size_t
src_step
,
uchar
*
dst_data
,
size_t
dst_step
,
int
width
,
int
height
,
int
roi_width
,
int
roi_height
,
int
roi_x
,
int
roi_y
,
int
roi_width2
,
int
roi_height2
,
int
roi_x2
,
int
roi_y2
,
int
kernel_type
,
uchar
*
kernel_data
,
size_t
kernel_step
,
int
kernel_width
,
int
kernel_height
,
int
anchor_x
,
int
anchor_y
,
int
borderType
,
const
double
borderValue
[
4
],
int
iterations
,
bool
isSubmatrix
)
{
{
{
{
ReplacementMorphImpl
*
impl
=
new
ReplacementMorphImpl
();
bool
res
=
halMorph
(
op
,
src_type
,
dst_type
,
src_data
,
src_step
,
dst_data
,
dst_step
,
width
,
height
,
if
(
impl
->
init
(
op
,
src_type
,
dst_type
,
max_width
,
max_height
,
roi_width
,
roi_height
,
roi_x
,
roi_y
,
kernel_type
,
kernel_data
,
kernel_step
,
kernel_width
,
kernel_height
,
roi_width2
,
roi_height2
,
roi_x2
,
roi_y2
,
anchor_x
,
anchor_y
,
kernel_type
,
kernel_data
,
kernel_step
,
borderType
,
borderValue
,
iterations
,
isSubmatrix
,
allowInplace
))
kernel_width
,
kernel_height
,
anchor_x
,
anchor_y
,
{
borderType
,
borderValue
,
iterations
,
isSubmatrix
);
return
Ptr
<
Morph
>
(
impl
);
if
(
res
)
}
return
;
delete
impl
;
}
}
#if defined(HAVE_IPP) && IPP_VERSION_X100 >= 810
#if defined(HAVE_IPP) && IPP_VERSION_X100 >= 810
#define ONE_CASE(type) \
case type: \
res = ippMorph<type>(op, src_type, dst_type, src_data, src_step, dst_data, dst_step, width, height, \
roi_width, roi_height, roi_x, roi_y, \
roi_width2, roi_height2, roi_x2, roi_y2, \
kernel_type, kernel_data, kernel_step, \
kernel_width, kernel_height, anchor_x, anchor_y, \
borderType, borderValue, iterations, isSubmatrix); \
break;
CV_IPP_CHECK
()
CV_IPP_CHECK
()
{
{
IppMorphBaseImpl
*
impl
=
createIppImpl
(
src_type
)
;
bool
res
=
false
;
if
(
impl
)
switch
(
src_type
)
{
{
if
(
impl
->
init
(
op
,
src_type
,
dst_type
,
max_width
,
max_height
,
ONE_CASE
(
CV_8UC1
)
kernel_type
,
kernel_data
,
kernel_step
,
kernel_width
,
kernel_height
,
ONE_CASE
(
CV_8UC3
)
anchor_x
,
anchor_y
,
ONE_CASE
(
CV_8UC4
)
borderType
,
borderValue
,
iterations
,
isSubmatrix
,
allowInplace
))
ONE_CASE
(
CV_32FC1
)
{
ONE_CASE
(
CV_32FC3
)
return
Ptr
<
Morph
>
(
impl
);
ONE_CASE
(
CV_32FC4
)
}
delete
impl
;
}
}
if
(
res
)
return
;
}
}
#undef ONE_CASE
#endif
#endif
{
OcvMorphImpl
*
impl
=
new
OcvMorphImpl
();
ocvMorph
(
op
,
src_type
,
dst_type
,
src_data
,
src_step
,
dst_data
,
dst_step
,
width
,
height
,
impl
->
init
(
op
,
src_type
,
dst_type
,
max_width
,
max_height
,
roi_width
,
roi_height
,
roi_x
,
roi_y
,
kernel_type
,
kernel_data
,
kernel_step
,
kernel_width
,
kernel_height
,
roi_width2
,
roi_height2
,
roi_x2
,
roi_y2
,
anchor_x
,
anchor_y
,
kernel_type
,
kernel_data
,
kernel_step
,
borderType
,
borderValue
,
iterations
,
isSubmatrix
,
allowInplace
);
kernel_width
,
kernel_height
,
anchor_x
,
anchor_y
,
return
Ptr
<
Morph
>
(
impl
);
borderType
,
borderValue
,
iterations
);
}
}
}
}
// cv::hal
}
// cv::hal
...
@@ -1941,13 +1903,15 @@ static void morphOp( int op, InputArray _src, OutputArray _dst,
...
@@ -1941,13 +1903,15 @@ static void morphOp( int op, InputArray _src, OutputArray _dst,
dst
.
locateROI
(
d_wsz
,
d_ofs
);
dst
.
locateROI
(
d_wsz
,
d_ofs
);
}
}
Ptr
<
hal
::
Morph
>
ctx
=
hal
::
Morph
::
create
(
op
,
src
.
type
(),
dst
.
type
(),
src
.
cols
,
src
.
rows
,
hal
::
morph
(
op
,
src
.
type
(),
dst
.
type
(),
kernel
.
type
(),
kernel
.
data
,
kernel
.
step
,
kernel
.
cols
,
kernel
.
rows
,
src
.
data
,
src
.
step
,
anchor
.
x
,
anchor
.
y
,
borderType
,
borderValue
.
val
,
iterations
,
dst
.
data
,
dst
.
step
,
(
src
.
isSubmatrix
()
&&
!
isolated
),
src
.
data
==
dst
.
data
);
src
.
cols
,
src
.
rows
,
ctx
->
apply
(
src
.
data
,
src
.
step
,
dst
.
data
,
dst
.
step
,
src
.
cols
,
src
.
rows
,
s_wsz
.
width
,
s_wsz
.
height
,
s_ofs
.
x
,
s_ofs
.
y
,
s_wsz
.
width
,
s_wsz
.
height
,
s_ofs
.
x
,
s_ofs
.
y
,
d_wsz
.
width
,
d_wsz
.
height
,
d_ofs
.
x
,
d_ofs
.
y
);
d_wsz
.
width
,
d_wsz
.
height
,
d_ofs
.
x
,
d_ofs
.
y
,
kernel
.
type
(),
kernel
.
data
,
kernel
.
step
,
kernel
.
cols
,
kernel
.
rows
,
anchor
.
x
,
anchor
.
y
,
borderType
,
borderValue
.
val
,
iterations
,
(
src
.
isSubmatrix
()
&&
!
isolated
));
}
}
}
}
...
...
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