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 {
//! @addtogroup imgproc_hal_functions
//! @{
//---------------------------
//! @cond IGNORED
struct
CV_EXPORTS
Filter2D
{
static
Ptr
<
hal
::
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
);
virtual
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
)
=
0
;
CV_DEPRECATED
static
Ptr
<
hal
::
Filter2D
>
create
(
uchar
*
,
size_t
,
int
,
int
,
int
,
int
,
int
,
int
,
int
,
int
,
double
,
int
,
int
,
bool
,
bool
);
virtual
void
apply
(
uchar
*
,
size_t
,
uchar
*
,
size_t
,
int
,
int
,
int
,
int
,
int
,
int
)
=
0
;
virtual
~
Filter2D
()
{}
};
struct
CV_EXPORTS
SepFilter2D
{
static
Ptr
<
hal
::
SepFilter2D
>
create
(
int
stype
,
int
dtype
,
int
ktype
,
uchar
*
kernelx_data
,
int
kernelx_len
,
uchar
*
kernely_data
,
int
kernely_len
,
int
anchor_x
,
int
anchor_y
,
double
delta
,
int
borderType
);
virtual
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
)
=
0
;
CV_DEPRECATED
static
Ptr
<
hal
::
SepFilter2D
>
create
(
int
,
int
,
int
,
uchar
*
,
int
,
uchar
*
,
int
,
int
,
int
,
double
,
int
);
virtual
void
apply
(
uchar
*
,
size_t
,
uchar
*
,
size_t
,
int
,
int
,
int
,
int
,
int
,
int
)
=
0
;
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
,
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
);
virtual
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
)
=
0
;
CV_DEPRECATED
static
Ptr
<
hal
::
Morph
>
create
(
int
,
int
,
int
,
int
,
int
,
int
,
uchar
*
,
size_t
,
int
,
int
,
int
,
int
,
int
,
const
double
*
,
int
,
bool
,
bool
);
virtual
void
apply
(
uchar
*
,
size_t
,
uchar
*
,
size_t
,
int
,
int
,
int
,
int
,
int
,
int
,
int
,
int
,
int
,
int
)
=
0
;
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
,
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,
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
;
bool
isInitialized
;
ReplacementFilter
()
:
ctx
(
0
),
isInitialized
(
false
)
{
}
bool
init
(
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
)
{
int
res
=
cv_hal_filterInit
(
&
ctx
,
kernel_data
,
kernel_step
,
kernel_type
,
kernel_width
,
kernel_height
,
max_width
,
max_height
,
stype
,
dtype
,
borderType
,
delta
,
anchor_x
,
anchor_y
,
isSubmatrix
,
isInplace
);
isInitialized
=
(
res
==
CV_HAL_ERROR_OK
);
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_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"
);
}
}
};
int
res
=
cv_hal_filterInit
(
&
ctx
,
kernel_data
,
kernel_step
,
kernel_type
,
kernel_width
,
kernel_height
,
width
,
height
,
stype
,
dtype
,
borderType
,
delta
,
anchor_x
,
anchor_y
,
isSubmatrix
,
src_data
==
dst_data
);
if
(
res
!=
CV_HAL_ERROR_OK
)
return
false
;
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
);
res
=
cv_hal_filterFree
(
ctx
);
if
(
res
!=
CV_HAL_ERROR_OK
)
return
false
;
return
success
;
}
#ifdef HAVE_IPP
typedef
IppStatus
(
CV_STDCALL
*
IppiFilterBorder
)(
...
...
@@ -4613,8 +4603,17 @@ struct IppFilterTrait<CV_32F>
};
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
typename
trait
::
kernel_type
kernel_type
;
...
...
@@ -4624,105 +4623,92 @@ struct IppFilter : public hal::Filter2D
IppiBorderType
ippBorderType
;
int
src_type
;
bool
init
(
uchar
*
kernel_data
,
size_t
kernel_step
,
int
,
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
)
{
Point
anchor
(
anchor_x
,
anchor_y
);
Point
anchor
(
anchor_x
,
anchor_y
);
#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
Point
ippAnchor
(
kernel_width
>>
1
,
kernel_height
>>
1
);
Point
ippAnchor
(
kernel_width
>>
1
,
kernel_height
>>
1
);
#endif
bool
isIsolated
=
(
borderType
&
BORDER_ISOLATED
)
!=
0
;
int
borderTypeNI
=
borderType
&
~
BORDER_ISOLATED
;
ippBorderType
=
ippiGetBorderType
(
borderTypeNI
);
int
ddepth
=
CV_MAT_DEPTH
(
dtype
);
int
sdepth
=
CV_MAT_DEPTH
(
stype
);
bool
isIsolated
=
(
borderType
&
BORDER_ISOLATED
)
!=
0
;
int
borderTypeNI
=
borderType
&
~
BORDER_ISOLATED
;
ippBorderType
=
ippiGetBorderType
(
borderTypeNI
);
int
ddepth
=
CV_MAT_DEPTH
(
dtype
);
int
sdepth
=
CV_MAT_DEPTH
(
stype
);
#if IPP_VERSION_X100 >= 201700 && IPP_VERSION_X100 < 201702 // IPP bug with 1x1 kernel
if
(
kernel_width
==
1
&&
kernel_height
==
1
)
return
false
;
if
(
kernel_width
==
1
&&
kernel_height
==
1
)
return
false
;
#endif
bool
runIpp
=
true
&&
(
borderTypeNI
==
BORDER_CONSTANT
||
borderTypeNI
==
BORDER_REPLICATE
)
&&
(
sdepth
==
ddepth
)
&&
(
getIppFunc
(
stype
))
&&
((
int
)
ippBorderType
>
0
)
&&
(
!
isSubmatrix
||
isIsolated
)
&&
(
std
::
fabs
(
delta
-
0
)
<
DBL_EPSILON
)
&&
(
ippAnchor
==
anchor
)
&&
!
isInplace
;
if
(
!
runIpp
)
return
false
;
bool
runIpp
=
true
&&
(
borderTypeNI
==
BORDER_CONSTANT
||
borderTypeNI
==
BORDER_REPLICATE
)
&&
(
sdepth
==
ddepth
)
&&
(
getIppFunc
(
stype
))
&&
((
int
)
ippBorderType
>
0
)
&&
(
!
isSubmatrix
||
isIsolated
)
&&
(
std
::
fabs
(
delta
-
0
)
<
DBL_EPSILON
)
&&
(
ippAnchor
==
anchor
)
&&
src_data
!=
dst_data
;
if
(
!
runIpp
)
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
;
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
=
{
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
);
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
(
kernel_step
!=
good_kernel_step
)
{
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
);
if
(
status
<
0
)
return
false
;
pKerBuffer
=
kernelBuffer
;
}
if
(
kernel_step
!=
good_kernel_step
)
{
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
);
if
(
status
<
0
)
return
false
;
pKerBuffer
=
kernelBuffer
;
}
#else
kernelBuffer
.
Alloc
(
good_kernel_step
*
kernelSize
.
height
);
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
);
flip
(
kernel
,
kerFlip
,
-
1
);
pKerBuffer
=
kernelBuffer
;
kernelBuffer
.
Alloc
(
good_kernel_step
*
kernelSize
.
height
);
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
);
flip
(
kernel
,
kerFlip
,
-
1
);
pKerBuffer
=
kernelBuffer
;
#endif
spec
.
Alloc
(
specSize
);
buffer
.
Alloc
(
bufsize
);
status
=
trait
::
runInit
(
pKerBuffer
,
kernelSize
,
0
,
dataType
,
cn
,
ippRndFinancial
,
spec
);
if
(
status
>=
0
)
{
return
true
;
}
}
spec
.
Alloc
(
specSize
);
buffer
.
Alloc
(
bufsize
);
status
=
trait
::
runInit
(
pKerBuffer
,
kernelSize
,
0
,
dataType
,
cn
,
ippRndFinancial
,
spec
);
if
(
status
<
0
)
{
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
)
{
CV_INSTRUMENT_REGION_IPP
()
if
(
dst_data
==
src_data
)
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
);
}
IppiFilterBorder
ippiFilterBorder
=
getIppFunc
(
src_type
);
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
);
if
(
status
>=
0
)
{
CV_IMPL_ADD
(
CV_IMPL_IPP
);
return
true
;
}
};
return
false
;
}
#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
int
sdepth
=
CV_MAT_DEPTH
(
stype
);
...
...
@@ -4733,162 +4719,112 @@ struct DftFilter : public hal::Filter2D
CV_UNUSED
(
dtype
);
int
dft_filter_size
=
50
;
#endif
return
kernel_width
*
kernel_height
>=
dft_filter_size
;
}
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
;
if
(
kernel_width
*
kernel_height
<
dft_filter_size
)
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
)
{
Mat
src
(
Size
(
width
,
height
),
src_type
,
src_data
,
src_step
);
Mat
dst
(
Size
(
width
,
height
),
dst_type
,
dst_data
,
dst_step
);
Mat
temp
;
int
src_channels
=
CV_MAT_CN
(
src_type
);
int
dst_channels
=
CV_MAT_CN
(
dst_type
);
int
ddepth
=
CV_MAT_DEPTH
(
dst_type
);
// crossCorr doesn't accept non-zero delta with multiple channels
if
(
src_channels
!=
1
&&
delta
!=
0
)
{
// The semantics of filter2D require that the delta be applied
// as floating-point math. So wee need an intermediate Mat
// with a float datatype. If the dest is already floats,
// we just use that.
int
corrDepth
=
ddepth
;
if
((
ddepth
==
CV_32F
||
ddepth
==
CV_64F
)
&&
src_data
!=
dst_data
)
{
temp
=
Mat
(
Size
(
width
,
height
),
dst_type
,
dst_data
,
dst_step
);
}
else
{
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
());
}
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
),
stype
,
src_data
,
src_step
);
Mat
dst
(
Size
(
width
,
height
),
dtype
,
dst_data
,
dst_step
);
Mat
temp
;
int
src_channels
=
CV_MAT_CN
(
stype
);
int
dst_channels
=
CV_MAT_CN
(
dtype
);
int
ddepth
=
CV_MAT_DEPTH
(
dtype
);
// crossCorr doesn't accept non-zero delta with multiple channels
if
(
src_channels
!=
1
&&
delta
!=
0
)
{
// The semantics of filter2D require that the delta be applied
// as floating-point math. So wee need an intermediate Mat
// with a float datatype. If the dest is already floats,
// we just use that.
int
corrDepth
=
ddepth
;
if
((
ddepth
==
CV_32F
||
ddepth
==
CV_64F
)
&&
src_data
!=
dst_data
)
{
temp
=
Mat
(
Size
(
width
,
height
),
dtype
,
dst_data
,
dst_step
);
}
else
{
if
(
src_data
!=
dst_data
)
temp
=
Mat
(
Size
(
width
,
height
),
dst_type
,
dst_data
,
dst_step
);
else
temp
.
create
(
Size
(
width
,
height
),
dst_type
);
crossCorr
(
src
,
kernel
,
temp
,
src
.
size
(
),
CV_MAKETYPE
(
ddepth
,
src_channels
),
anchor
,
delta
,
borderType
);
if
(
temp
.
data
!=
dst_data
)
temp
.
copyTo
(
dst
);
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
{
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
src_type
;
int
dst_type
;
bool
isIsolated
;
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
)
{
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
));
}
};
int
borderTypeValue
=
borderType
&
~
BORDER_ISOLATED
;
Mat
kernel
=
Mat
(
Size
(
kernel_width
,
kernel_height
),
kernel_type
,
kernel_data
,
kernel_step
);
Ptr
<
FilterEngine
>
f
=
createLinearFilter
(
stype
,
dtype
,
kernel
,
Point
(
anchor_x
,
anchor_y
),
delta
,
borderTypeValue
);
Mat
src
(
Size
(
width
,
height
),
stype
,
src_data
,
src_step
);
Mat
dst
(
Size
(
width
,
height
),
dtype
,
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
;
bool
isInitialized
;
ReplacementSepFilter
()
:
ctx
(
0
),
isInitialized
(
false
)
{}
bool
init
(
int
stype
,
int
dtype
,
int
ktype
,
uchar
*
kernelx_data
,
int
kernelx_len
,
uchar
*
kernely_data
,
int
kernely_len
,
int
anchor_x
,
int
anchor_y
,
double
delta
,
int
borderType
)
{
int
res
=
cv_hal_sepFilterInit
(
&
ctx
,
stype
,
dtype
,
ktype
,
kernelx_data
,
kernelx_len
,
kernely_data
,
kernely_len
,
anchor_x
,
anchor_y
,
delta
,
borderType
);
isInitialized
=
(
res
==
CV_HAL_ERROR_OK
);
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"
);
}
}
};
int
res
=
cv_hal_sepFilterInit
(
&
ctx
,
stype
,
dtype
,
ktype
,
kernelx_data
,
kernelx_len
,
kernely_data
,
kernely_len
,
anchor_x
,
anchor_y
,
delta
,
borderType
);
if
(
res
!=
CV_HAL_ERROR_OK
)
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
);
bool
success
=
(
res
==
CV_HAL_ERROR_OK
);
res
=
cv_hal_sepFilterFree
(
ctx
);
if
(
res
!=
CV_HAL_ERROR_OK
)
return
false
;
return
success
;
}
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
;
int
src_type
;
int
dst_type
;
bool
init
(
int
stype
,
int
dtype
,
int
ktype
,
uchar
*
kernelx_data
,
int
kernelx_len
,
uchar
*
kernely_data
,
int
kernely_len
,
int
anchor_x
,
int
anchor_y
,
double
delta
,
int
borderType
)
{
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
));
}
Mat
kernelX
(
Size
(
kernelx_len
,
1
),
ktype
,
kernelx_data
);
Mat
kernelY
(
Size
(
kernely_len
,
1
),
ktype
,
kernely_data
);
Ptr
<
FilterEngine
>
f
=
createSeparableLinearFilter
(
stype
,
dtype
,
kernelX
,
kernelY
,
Point
(
anchor_x
,
anchor_y
),
delta
,
borderType
&
~
BORDER_ISOLATED
);
Mat
src
(
Size
(
width
,
height
),
stype
,
src_data
,
src_step
);
Mat
dst
(
Size
(
width
,
height
),
dtype
,
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
namespace
cv
{
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
CV_IPP_CHECK
()
{
res
=
false
;
if
(
kernel_type
==
CV_32FC1
)
{
IppFilter
<
CV_32F
>*
impl
=
new
IppFilter
<
CV_32F
>
();
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
;
res
=
ippFilter2D
<
CV_32F
>
(
stype
,
dtype
,
src_data
,
src_step
,
dst_data
,
dst_step
,
width
,
height
,
kernel_data
,
kernel_step
,
kernel_width
,
kernel_height
,
anchor_x
,
anchor_y
,
delta
,
borderType
,
isSubmatrix
)
;
}
if
(
kernel_type
==
CV_16SC1
)
{
IppFilter
<
CV_16S
>*
impl
=
new
IppFilter
<
CV_16S
>
();
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
;
else
if
(
kernel_type
==
CV_16SC1
)
{
res
=
ippFilter2D
<
CV_16S
>
(
stype
,
dtype
,
src_data
,
src_step
,
dst_data
,
dst_step
,
width
,
height
,
kernel_data
,
kernel_step
,
kernel_width
,
kernel_height
,
anchor_x
,
anchor_y
,
delta
,
borderType
,
isSubmatrix
);
}
if
(
res
)
return
;
}
#endif
if
(
DftFilter
::
isAppropriate
(
stype
,
dtype
,
kernel_width
,
kernel_height
))
{
DftFilter
*
impl
=
new
DftFilter
();
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
;
}
{
OcvFilter
*
impl
=
new
OcvFilter
();
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
);
}
res
=
dftFilter2D
(
stype
,
dtype
,
kernel_type
,
src_data
,
src_step
,
dst_data
,
dst_step
,
width
,
height
,
kernel_data
,
kernel_step
,
kernel_width
,
kernel_height
,
anchor_x
,
anchor_y
,
delta
,
borderType
);
if
(
res
)
return
;
ocvFilter2D
(
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
);
}
//---------------------------------------------------------------
Ptr
<
SepFilter2D
>
SepFilter2D
::
create
(
int
stype
,
int
dtype
,
int
ktype
,
uchar
*
kernelx_data
,
int
kernelx_len
,
uchar
*
kernely_data
,
int
kernely_len
,
int
anchor_x
,
int
anchor_y
,
double
delta
,
int
borderType
)
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
)
{
{
ReplacementSepFilter
*
impl
=
new
ReplacementSepFilter
();
if
(
impl
->
init
(
stype
,
dtype
,
ktype
,
kernelx_data
,
kernelx_len
,
kernely_data
,
kernely_len
,
anchor_x
,
anchor_y
,
delta
,
borderType
))
{
return
Ptr
<
hal
::
SepFilter2D
>
(
impl
);
}
delete
impl
;
}
{
OcvSepFilter
*
impl
=
new
OcvSepFilter
();
impl
->
init
(
stype
,
dtype
,
ktype
,
kernelx_data
,
kernelx_len
,
kernely_data
,
kernely_len
,
anchor_x
,
anchor_y
,
delta
,
borderType
);
return
Ptr
<
hal
::
SepFilter2D
>
(
impl
);
}
bool
res
=
replacementSepFilter
(
stype
,
dtype
,
ktype
,
src_data
,
src_step
,
dst_data
,
dst_step
,
width
,
height
,
full_width
,
full_height
,
offset_x
,
offset_y
,
kernelx_data
,
kernelx_len
,
kernely_data
,
kernely_len
,
anchor_x
,
anchor_y
,
delta
,
borderType
);
if
(
res
)
return
;
ocvSepFilter
(
stype
,
dtype
,
ktype
,
src_data
,
src_step
,
dst_data
,
dst_step
,
width
,
height
,
full_width
,
full_height
,
offset_x
,
offset_y
,
kernelx_data
,
kernelx_len
,
kernely_data
,
kernely_len
,
anchor_x
,
anchor_y
,
delta
,
borderType
);
}
}
// cv::hal::
...
...
@@ -5021,10 +4984,12 @@ void cv::filter2D( InputArray _src, OutputArray _dst, int ddepth,
if
(
(
borderType
&
BORDER_ISOLATED
)
==
0
)
src
.
locateROI
(
wsz
,
ofs
);
Ptr
<
hal
::
Filter2D
>
c
=
hal
::
Filter2D
::
create
(
kernel
.
data
,
kernel
.
step
,
kernel
.
type
(),
kernel
.
cols
,
kernel
.
rows
,
dst
.
cols
,
dst
.
rows
,
src
.
type
(),
dst
.
type
(),
borderType
,
delta
,
anchor
.
x
,
anchor
.
y
,
src
.
isSubmatrix
(),
src
.
data
==
dst
.
data
);
c
->
apply
(
src
.
data
,
src
.
step
,
dst
.
data
,
dst
.
step
,
dst
.
cols
,
dst
.
rows
,
wsz
.
width
,
wsz
.
height
,
ofs
.
x
,
ofs
.
y
);
hal
::
filter2D
(
src
.
type
(),
dst
.
type
(),
kernel
.
type
(),
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
,
...
...
@@ -5055,11 +5020,13 @@ void cv::sepFilter2D( InputArray _src, OutputArray _dst, int ddepth,
Mat
contKernelX
=
kernelX
.
isContinuous
()
?
kernelX
:
kernelX
.
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
,
contKernelY
.
data
,
kernelY
.
cols
+
kernelY
.
rows
-
1
,
anchor
.
x
,
anchor
.
y
,
delta
,
borderType
&
~
BORDER_ISOLATED
);
c
->
apply
(
src
.
data
,
src
.
step
,
dst
.
data
,
dst
.
step
,
dst
.
cols
,
dst
.
rows
,
wsz
.
width
,
wsz
.
height
,
ofs
.
x
,
ofs
.
y
);
hal
::
sepFilter2D
(
src
.
type
(),
dst
.
type
(),
kernelX
.
type
(),
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
// ===== 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
;
bool
isInitialized
;
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
)
{
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
,
anchor_x
,
anchor_y
,
borderType
,
borderValue
,
iterations
,
isSubmatrix
,
allowInplace
);
isInitialized
=
(
res
==
CV_HAL_ERROR_OK
);
return
isInitialized
;
}
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
)
{
if
(
isInitialized
)
{
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"
);
}
}
};
int
res
=
cv_hal_morphInit
(
&
ctx
,
op
,
src_type
,
dst_type
,
width
,
height
,
kernel_type
,
kernel_data
,
kernel_step
,
kernel_width
,
kernel_height
,
anchor_x
,
anchor_y
,
borderType
,
borderValue
,
iterations
,
isSubmatrix
,
src_data
==
dst_data
);
if
(
res
!=
CV_HAL_ERROR_OK
)
return
false
;
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
);
bool
success
=
(
res
==
CV_HAL_ERROR_OK
);
res
=
cv_hal_morphFree
(
ctx
);
if
(
res
!=
CV_HAL_ERROR_OK
)
return
false
;
return
success
;
}
// ===== 2. IPP implementation
...
...
@@ -1133,7 +1122,7 @@ template <int cvtype> struct IppMorphTrait {};
#if IPP_VERSION_X100 >= 900
#define
INIT
_TRAIT(cvtype, ipptype, flavor, channels, zerodef)\
#define
DEFINE
_TRAIT(cvtype, ipptype, flavor, channels, zerodef)\
template <>\
struct IppMorphTrait<cvtype>\
{\
...
...
@@ -1153,7 +1142,7 @@ struct IppMorphTrait<cvtype>\
#else
#define
INIT
_TRAIT(cvtype, ipptype, flavor, channels, zerodef)\
#define
DEFINE
_TRAIT(cvtype, ipptype, flavor, channels, zerodef)\
template <>\
struct IppMorphTrait<cvtype>\
{\
...
...
@@ -1173,28 +1162,28 @@ struct IppMorphTrait<cvtype>\
#endif
INIT
_TRAIT
(
CV_8UC1
,
8u
,
8u
_C1R
,
1
,
zero
=
0
)
INIT
_TRAIT
(
CV_8UC3
,
8u
,
8u
_C3R
,
3
,
zero
[
3
]
=
{
0
})
INIT
_TRAIT
(
CV_8UC4
,
8u
,
8u
_C4R
,
4
,
zero
[
4
]
=
{
0
})
INIT
_TRAIT
(
CV_32FC1
,
32
f
,
32
f_C1R
,
1
,
zero
=
0
)
INIT
_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_8UC1
,
8u
,
8u
_C1R
,
1
,
zero
=
0
)
DEFINE
_TRAIT
(
CV_8UC3
,
8u
,
8u
_C3R
,
3
,
zero
[
3
]
=
{
0
})
DEFINE
_TRAIT
(
CV_8UC4
,
8u
,
8u
_C4R
,
4
,
zero
[
4
]
=
{
0
})
DEFINE
_TRAIT
(
CV_32FC1
,
32
f
,
32
f_C1R
,
1
,
zero
=
0
)
DEFINE
_TRAIT
(
CV_32FC3
,
32
f
,
32
f_C3R
,
3
,
zero
[
3
]
=
{
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
>
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
;
typedef
typename
IppMorphTrait
<
cvtype
>::
ipp_data_type
ipp_data_type
;
...
...
@@ -1203,177 +1192,136 @@ struct IppMorphImpl : public IppMorphBaseImpl
IppiSize
kernelSize
;
bool
rectKernel
;
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
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_INSTRUMENT_REGION_IPP
()
}
Size
ksize
=
!
kernel
.
empty
()
?
kernel
.
size
()
:
Size
(
3
,
3
);
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
);
CV_UNUSED
(
dst_type
);
rectKernel
=
false
;
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
;
}
anchor
=
ippiPoint
(
anchor_x
,
anchor_y
);
// TODO: implement the case of iterations > 1.
if
(
iterations
>
1
)
return
false
;
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
);
IppiSize
roiSize
=
{
max_width
,
max_height
};
kernelSize
=
ippiSize
(
ksize
);
op
=
_op
;
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
||
src_data
==
dst_data
)
return
false
;
IppStatus
res
;
if
(
!
rectKernel
)
// In case BORDER_CONSTANT, IPPMorphReplicate works correct with kernels of size 3*3 only
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
))
return
false
;
int
specSize
=
0
,
bufferSize
=
0
;
res
=
trait
.
getMorphSize
(
roiSize
,
kernelSize
,
&
specSize
,
&
bufferSize
);
if
(
res
>=
0
)
if
(
kernel
.
at
<
uchar
>
(
y
,
anchor
.
x
)
!=
0
)
continue
;
for
(
x
=
0
;
x
<
kernel
.
cols
;
x
++
)
{
specBuf
.
Alloc
(
specSize
);
workBuf
.
Alloc
(
bufferSize
);
res
=
trait
.
morphInit
(
roiSize
,
kernel
.
ptr
(),
kernelSize
,
specBuf
,
workBuf
);
if
(
res
>=
0
)
return
true
;
if
(
kernel
.
at
<
uchar
>
(
y
,
x
)
!=
0
)
return
false
;
}
}
else
for
(
x
=
0
;
x
<
kernel
.
cols
;
x
++
)
{
if
(((
kernelSize
.
width
-
1
)
/
2
!=
anchor
.
x
)
||
((
kernelSize
.
height
-
1
)
/
2
!=
anchor
.
y
))
return
false
;
if
(
op
==
MORPH_ERODE
)
{
int
bufSize
=
0
;
res
=
trait
.
filterGetMinSize
(
roiSize
,
kernelSize
,
trait
.
getDataType
(),
trait
.
cn
,
&
bufSize
);
if
(
res
>=
0
)
{
workBuf
.
Alloc
(
bufSize
);
return
true
;
}
}
else
if
(
kernel
.
at
<
uchar
>
(
anchor
.
y
,
x
)
!=
0
)
continue
;
for
(
y
=
0
;
y
<
kernel
.
rows
;
y
++
)
{
int
bufSize
=
0
;
res
=
trait
.
filterGetMaxSize
(
roiSize
,
kernelSize
,
trait
.
getDataType
(),
trait
.
cn
,
&
bufSize
);
if
(
res
>=
0
)
{
workBuf
.
Alloc
(
bufSize
);
return
true
;
}
if
(
kernel
.
at
<
uchar
>
(
y
,
x
)
!=
0
)
return
false
;
}
}
return
false
;
}
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
)
Size
ksize
=
!
kernel
.
empty
()
?
kernel
.
size
()
:
Size
(
3
,
3
);
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
);
CV_UNUSED
(
roi_width2
);
CV_UNUSED
(
roi_height2
);
CV_UNUSED
(
roi_x2
);
CV_UNUSED
(
roi_y2
);
if
(
src_data
==
dst_data
)
CV_Error
(
Error
::
StsBadArg
,
"IPP Morph inplace is not alowed"
);
// TODO: implement the case of iterations > 1.
if
(
iterations
>
1
)
return
false
;
IppiSize
roiSize
=
{
width
,
height
};
IppiSize
roiSize
=
{
width
,
height
};
kernelSize
=
ippiSize
(
ksize
);
IppStatus
res
;
if
(
!
rectKernel
)
IppStatus
res
;
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
)
res
=
(
trait
.
morphErode
((
ipp_data_type
*
)
src_data
,
(
int
)
src_step
,
(
ipp_data_type
*
)
dst_data
,
(
int
)
dst_step
,
roiSize
,
specBuf
,
workBuf
));
int
bufSize
=
0
;
res
=
trait
.
filterGetMinSize
(
roiSize
,
kernelSize
,
trait
.
getDataType
(),
trait
.
cn
,
&
bufSize
);
if
(
res
>=
0
)
workBuf
.
Alloc
(
bufSize
);
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
{
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
));
int
bufSize
=
0
;
res
=
trait
.
filterGetMaxSize
(
roiSize
,
kernelSize
,
trait
.
getDataType
(),
trait
.
cn
,
&
bufSize
);
if
(
res
>=
0
)
workBuf
.
Alloc
(
bufSize
);
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
)
{
switch
(
type
)
if
(
!
rectKernel
)
{
case
CV_8UC1
:
return
new
IppMorphImpl
<
CV_8UC1
>
();
case
CV_8UC3
:
return
new
IppMorphImpl
<
CV_8UC3
>
();
case
CV_8UC4
:
return
new
IppMorphImpl
<
CV_8UC4
>
();
case
CV_32FC1
:
return
new
IppMorphImpl
<
CV_32FC1
>
();
case
CV_32FC3
:
return
new
IppMorphImpl
<
CV_32FC3
>
();
case
CV_32FC4
:
return
new
IppMorphImpl
<
CV_32FC4
>
();
if
(
op
==
MORPH_ERODE
)
res
=
(
trait
.
morphErode
((
ipp_data_type
*
)
src_data
,
(
int
)
src_step
,
(
ipp_data_type
*
)
dst_data
,
(
int
)
dst_step
,
roiSize
,
specBuf
,
workBuf
));
else
res
=
(
trait
.
morphDilate
((
ipp_data_type
*
)
src_data
,
(
int
)
src_step
,
(
ipp_data_type
*
)
dst_data
,
(
int
)
dst_step
,
roiSize
,
specBuf
,
workBuf
));
}
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
...
...
@@ -1381,94 +1329,108 @@ static IppMorphBaseImpl * createIppImpl(int type)
// ===== 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
;
int
iterations
;
int
src_type
;
int
dst_type
;
bool
init
(
int
op
,
int
_src_type
,
int
_dst_type
,
int
,
int
,
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
,
bool
)
Mat
kernel
(
Size
(
kernel_width
,
kernel_height
),
kernel_type
,
kernel_data
,
kernel_step
);
Point
anchor
(
anchor_x
,
anchor_y
);
Vec
<
double
,
4
>
borderVal
(
borderValue
);
Ptr
<
FilterEngine
>
f
=
createMorphologyFilter
(
op
,
src_type
,
kernel
,
anchor
,
borderType
,
borderType
,
borderVal
);
Mat
src
(
Size
(
width
,
height
),
src_type
,
src_data
,
src_step
);
Mat
dst
(
Size
(
width
,
height
),
dst_type
,
dst_data
,
dst_step
);
{
iterations
=
_iterations
;
src_type
=
_src_type
;
dst_type
=
_dst_type
;
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
;
Point
ofs
(
roi_x
,
roi_y
);
Size
wsz
(
roi_width
,
roi_height
);
f
->
apply
(
src
,
dst
,
wsz
,
ofs
);
}
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
);
Mat
dst
(
Size
(
width
,
height
),
dst_type
,
dst_data
,
dst_step
);
{
Point
ofs
(
roi_x
,
roi_y
);
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
);
}
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
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
,
int
anchor_x
,
int
anchor_y
,
int
borderType
,
const
double
borderValue
[
4
],
int
iterations
,
bool
isSubmatrix
,
bool
allowInplace
)
CV_DEPRECATED
Ptr
<
Morph
>
Morph
::
create
(
int
,
int
,
int
,
int
,
int
,
int
,
uchar
*
,
size_t
,
int
,
int
,
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
();
if
(
impl
->
init
(
op
,
src_type
,
dst_type
,
max_width
,
max_height
,
kernel_type
,
kernel_data
,
kernel_step
,
kernel_width
,
kernel_height
,
anchor_x
,
anchor_y
,
borderType
,
borderValue
,
iterations
,
isSubmatrix
,
allowInplace
))
{
return
Ptr
<
Morph
>
(
impl
);
}
delete
impl
;
bool
res
=
halMorph
(
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
);
if
(
res
)
return
;
}
#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
()
{
IppMorphBaseImpl
*
impl
=
createIppImpl
(
src_type
)
;
if
(
impl
)
bool
res
=
false
;
switch
(
src_type
)
{
if
(
impl
->
init
(
op
,
src_type
,
dst_type
,
max_width
,
max_height
,
kernel_type
,
kernel_data
,
kernel_step
,
kernel_width
,
kernel_height
,
anchor_x
,
anchor_y
,
borderType
,
borderValue
,
iterations
,
isSubmatrix
,
allowInplace
))
{
return
Ptr
<
Morph
>
(
impl
);
}
delete
impl
;
ONE_CASE
(
CV_8UC1
)
ONE_CASE
(
CV_8UC3
)
ONE_CASE
(
CV_8UC4
)
ONE_CASE
(
CV_32FC1
)
ONE_CASE
(
CV_32FC3
)
ONE_CASE
(
CV_32FC4
)
}
if
(
res
)
return
;
}
#undef ONE_CASE
#endif
{
OcvMorphImpl
*
impl
=
new
OcvMorphImpl
();
impl
->
init
(
op
,
src_type
,
dst_type
,
max_width
,
max_height
,
kernel_type
,
kernel_data
,
kernel_step
,
kernel_width
,
kernel_height
,
anchor_x
,
anchor_y
,
borderType
,
borderValue
,
iterations
,
isSubmatrix
,
allowInplace
);
return
Ptr
<
Morph
>
(
impl
);
}
ocvMorph
(
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
);
}
}
// cv::hal
...
...
@@ -1941,13 +1903,15 @@ static void morphOp( int op, InputArray _src, OutputArray _dst,
dst
.
locateROI
(
d_wsz
,
d_ofs
);
}
Ptr
<
hal
::
Morph
>
ctx
=
hal
::
Morph
::
create
(
op
,
src
.
type
(),
dst
.
type
(),
src
.
cols
,
src
.
rows
,
kernel
.
type
(),
kernel
.
data
,
kernel
.
step
,
kernel
.
cols
,
kernel
.
rows
,
anchor
.
x
,
anchor
.
y
,
borderType
,
borderValue
.
val
,
iterations
,
(
src
.
isSubmatrix
()
&&
!
isolated
),
src
.
data
==
dst
.
data
);
ctx
->
apply
(
src
.
data
,
src
.
step
,
dst
.
data
,
dst
.
step
,
src
.
cols
,
src
.
rows
,
hal
::
morph
(
op
,
src
.
type
(),
dst
.
type
(),
src
.
data
,
src
.
step
,
dst
.
data
,
dst
.
step
,
src
.
cols
,
src
.
rows
,
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