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
f4136679
Commit
f4136679
authored
Sep 18, 2017
by
Vadim Pisarevsky
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #9551 from ChristofKaufmann:MultiChannelMask
parents
3358b891
7ec59fc0
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
61 additions
and
28 deletions
+61
-28
mat.hpp
modules/core/include/opencv2/core/mat.hpp
+4
-3
copy.cpp
modules/core/src/copy.cpp
+8
-5
test_arithm.cpp
modules/core/test/test_arithm.cpp
+12
-7
ts_func.cpp
modules/ts/src/ts_func.cpp
+37
-13
No files found.
modules/core/include/opencv2/core/mat.hpp
View file @
f4136679
...
...
@@ -1192,8 +1192,8 @@ public:
/** @overload
@param m Destination matrix. If it does not have a proper size or type before the operation, it is
reallocated.
@param mask Operation mask
. Its non-zero elements indicate which matrix elements need to be copied.
The mask has to be of type CV_8U and can have 1 or multiple channels.
@param mask Operation mask
of the same size as \*this. Its non-zero elements indicate which matrix
elements need to be copied.
The mask has to be of type CV_8U and can have 1 or multiple channels.
*/
void
copyTo
(
OutputArray
m
,
InputArray
mask
)
const
;
...
...
@@ -1229,7 +1229,8 @@ public:
This is an advanced variant of the Mat::operator=(const Scalar& s) operator.
@param value Assigned scalar converted to the actual array type.
@param mask Operation mask of the same size as \*this.
@param mask Operation mask of the same size as \*this. Its non-zero elements indicate which matrix
elements need to be copied. The mask has to be of type CV_8U and can have 1 or multiple channels
*/
Mat
&
setTo
(
InputArray
value
,
InputArray
mask
=
noArray
());
...
...
modules/core/src/copy.cpp
View file @
f4136679
...
...
@@ -336,7 +336,7 @@ static bool ipp_copyTo(const Mat &src, Mat &dst, const Mat &mask)
#ifdef HAVE_IPP_IW
CV_INSTRUMENT_REGION_IPP
()
if
(
mask
.
channels
()
>
1
&&
mask
.
depth
()
!=
CV_8U
)
if
(
mask
.
channels
()
>
1
||
mask
.
depth
()
!=
CV_8U
)
return
false
;
if
(
src
.
dims
<=
2
)
...
...
@@ -512,20 +512,23 @@ Mat& Mat::setTo(InputArray _value, InputArray _mask)
Mat
value
=
_value
.
getMat
(),
mask
=
_mask
.
getMat
();
CV_Assert
(
checkScalar
(
value
,
type
(),
_value
.
kind
(),
_InputArray
::
MAT
));
CV_Assert
(
mask
.
empty
()
||
(
mask
.
type
()
==
CV_8U
&&
size
==
mask
.
size
)
);
int
cn
=
channels
(),
mcn
=
mask
.
channels
();
CV_Assert
(
mask
.
empty
()
||
(
mask
.
depth
()
==
CV_8U
&&
(
mcn
==
1
||
mcn
==
cn
)
&&
size
==
mask
.
size
)
);
CV_IPP_RUN_FAST
(
ipp_Mat_setTo_Mat
(
*
this
,
value
,
mask
),
*
this
)
size_t
esz
=
elemSize
();
size_t
esz
=
mcn
>
1
?
elemSize1
()
:
elemSize
();
BinaryFunc
copymask
=
getCopyMaskFunc
(
esz
);
const
Mat
*
arrays
[]
=
{
this
,
!
mask
.
empty
()
?
&
mask
:
0
,
0
};
uchar
*
ptrs
[
2
]
=
{
0
,
0
};
NAryMatIterator
it
(
arrays
,
ptrs
);
int
totalsz
=
(
int
)
it
.
size
,
blockSize0
=
std
::
min
(
totalsz
,
(
int
)((
BLOCK_SIZE
+
esz
-
1
)
/
esz
));
int
totalsz
=
(
int
)
it
.
size
*
mcn
;
int
blockSize0
=
std
::
min
(
totalsz
,
(
int
)((
BLOCK_SIZE
+
esz
-
1
)
/
esz
));
blockSize0
-=
blockSize0
%
mcn
;
// must be divisible without remainder for unrolling and advancing
AutoBuffer
<
uchar
>
_scbuf
(
blockSize0
*
esz
+
32
);
uchar
*
scbuf
=
alignPtr
((
uchar
*
)
_scbuf
,
(
int
)
sizeof
(
double
));
convertAndUnrollScalar
(
value
,
type
(),
scbuf
,
blockSize0
);
convertAndUnrollScalar
(
value
,
type
(),
scbuf
,
blockSize0
/
mcn
);
for
(
size_t
i
=
0
;
i
<
it
.
nplanes
;
i
++
,
++
it
)
{
...
...
modules/core/test/test_arithm.cpp
View file @
f4136679
#include "test_precomp.hpp"
#
include
"test_precomp.hpp"
#include <cmath>
using
namespace
cv
;
...
...
@@ -15,7 +15,7 @@ const int ARITHM_MAX_SIZE_LOG = 10;
struct
BaseElemWiseOp
{
enum
{
FIX_ALPHA
=
1
,
FIX_BETA
=
2
,
FIX_GAMMA
=
4
,
REAL_GAMMA
=
8
,
SUPPORT_MASK
=
16
,
SCALAR_OUTPUT
=
32
};
enum
{
FIX_ALPHA
=
1
,
FIX_BETA
=
2
,
FIX_GAMMA
=
4
,
REAL_GAMMA
=
8
,
SUPPORT_MASK
=
16
,
SCALAR_OUTPUT
=
32
,
SUPPORT_MULTICHANNELMASK
=
64
};
BaseElemWiseOp
(
int
_ninputs
,
int
_flags
,
double
_alpha
,
double
_beta
,
Scalar
_gamma
=
Scalar
::
all
(
0
),
int
_context
=
1
)
:
ninputs
(
_ninputs
),
flags
(
_flags
),
alpha
(
_alpha
),
beta
(
_beta
),
gamma
(
_gamma
),
context
(
_context
)
{}
...
...
@@ -467,7 +467,7 @@ struct CmpSOp : public BaseElemWiseOp
struct
CopyOp
:
public
BaseElemWiseOp
{
CopyOp
()
:
BaseElemWiseOp
(
1
,
FIX_ALPHA
+
FIX_BETA
+
FIX_GAMMA
+
SUPPORT_MASK
,
1
,
1
,
Scalar
::
all
(
0
))
{
}
CopyOp
()
:
BaseElemWiseOp
(
1
,
FIX_ALPHA
+
FIX_BETA
+
FIX_GAMMA
+
SUPPORT_MASK
+
SUPPORT_MULTICHANNELMASK
,
1
,
1
,
Scalar
::
all
(
0
))
{
}
void
op
(
const
vector
<
Mat
>&
src
,
Mat
&
dst
,
const
Mat
&
mask
)
{
src
[
0
].
copyTo
(
dst
,
mask
);
...
...
@@ -489,7 +489,7 @@ struct CopyOp : public BaseElemWiseOp
struct
SetOp
:
public
BaseElemWiseOp
{
SetOp
()
:
BaseElemWiseOp
(
0
,
FIX_ALPHA
+
FIX_BETA
+
SUPPORT_MASK
,
1
,
1
,
Scalar
::
all
(
0
))
{}
SetOp
()
:
BaseElemWiseOp
(
0
,
FIX_ALPHA
+
FIX_BETA
+
SUPPORT_MASK
+
SUPPORT_MULTICHANNELMASK
,
1
,
1
,
Scalar
::
all
(
0
))
{}
void
op
(
const
vector
<
Mat
>&
,
Mat
&
dst
,
const
Mat
&
mask
)
{
dst
.
setTo
(
gamma
,
mask
);
...
...
@@ -1394,7 +1394,8 @@ TEST_P(ElemWiseTest, accuracy)
op
->
getRandomSize
(
rng
,
size
);
int
type
=
op
->
getRandomType
(
rng
);
int
depth
=
CV_MAT_DEPTH
(
type
);
bool
haveMask
=
(
op
->
flags
&
cvtest
::
BaseElemWiseOp
::
SUPPORT_MASK
)
!=
0
&&
rng
.
uniform
(
0
,
4
)
==
0
;
bool
haveMask
=
((
op
->
flags
&
cvtest
::
BaseElemWiseOp
::
SUPPORT_MASK
)
!=
0
||
(
op
->
flags
&
cvtest
::
BaseElemWiseOp
::
SUPPORT_MULTICHANNELMASK
)
!=
0
)
&&
rng
.
uniform
(
0
,
4
)
==
0
;
double
minval
=
0
,
maxval
=
0
;
op
->
getValueRange
(
depth
,
minval
,
maxval
);
...
...
@@ -1403,8 +1404,12 @@ TEST_P(ElemWiseTest, accuracy)
for
(
i
=
0
;
i
<
ninputs
;
i
++
)
src
[
i
]
=
cvtest
::
randomMat
(
rng
,
size
,
type
,
minval
,
maxval
,
true
);
Mat
dst0
,
dst
,
mask
;
if
(
haveMask
)
mask
=
cvtest
::
randomMat
(
rng
,
size
,
CV_8U
,
0
,
2
,
true
);
if
(
haveMask
)
{
bool
multiChannelMask
=
(
op
->
flags
&
cvtest
::
BaseElemWiseOp
::
SUPPORT_MULTICHANNELMASK
)
!=
0
&&
rng
.
uniform
(
0
,
2
)
==
0
;
int
masktype
=
CV_8UC
(
multiChannelMask
?
CV_MAT_CN
(
type
)
:
1
);
mask
=
cvtest
::
randomMat
(
rng
,
size
,
masktype
,
0
,
2
,
true
);
}
if
(
(
haveMask
||
ninputs
==
0
)
&&
!
(
op
->
flags
&
cvtest
::
BaseElemWiseOp
::
SCALAR_OUTPUT
))
{
...
...
modules/ts/src/ts_func.cpp
View file @
f4136679
...
...
@@ -353,26 +353,38 @@ void copy(const Mat& src, Mat& dst, const Mat& mask, bool invertMask)
return
;
}
CV_Assert
(
src
.
size
==
mask
.
size
&&
mask
.
type
()
==
CV_8U
);
int
mcn
=
mask
.
channels
();
CV_Assert
(
src
.
size
==
mask
.
size
&&
mask
.
depth
()
==
CV_8U
&&
(
mcn
==
1
||
mcn
==
src
.
channels
())
);
const
Mat
*
arrays
[]
=
{
&
src
,
&
dst
,
&
mask
,
0
};
Mat
planes
[
3
];
NAryMatIterator
it
(
arrays
,
planes
);
size_t
j
,
k
,
elemSize
=
src
.
elemSize
(),
total
=
planes
[
0
].
total
();
size_t
j
,
k
,
elemSize
=
src
.
elemSize
(),
maskElemSize
=
mask
.
elemSize
(),
total
=
planes
[
0
].
total
();
size_t
i
,
nplanes
=
it
.
nplanes
;
size_t
elemSize1
=
src
.
elemSize1
();
for
(
i
=
0
;
i
<
nplanes
;
i
++
,
++
it
)
{
const
uchar
*
sptr
=
planes
[
0
].
ptr
();
uchar
*
dptr
=
planes
[
1
].
ptr
();
const
uchar
*
mptr
=
planes
[
2
].
ptr
();
for
(
j
=
0
;
j
<
total
;
j
++
,
sptr
+=
elemSize
,
dptr
+=
elemSize
)
for
(
j
=
0
;
j
<
total
;
j
++
,
sptr
+=
elemSize
,
dptr
+=
elemSize
,
mptr
+=
maskElemSize
)
{
if
(
(
mptr
[
j
]
!=
0
)
^
invertMask
)
for
(
k
=
0
;
k
<
elemSize
;
k
++
)
dptr
[
k
]
=
sptr
[
k
];
if
(
mcn
==
1
)
{
if
(
(
mptr
[
0
]
!=
0
)
^
invertMask
)
for
(
k
=
0
;
k
<
elemSize
;
k
++
)
dptr
[
k
]
=
sptr
[
k
];
}
else
{
for
(
int
c
=
0
;
c
<
mcn
;
c
++
)
if
(
(
mptr
[
c
]
!=
0
)
^
invertMask
)
for
(
k
=
0
;
k
<
elemSize1
;
k
++
)
dptr
[
k
+
c
*
elemSize1
]
=
sptr
[
k
+
c
*
elemSize1
];
}
}
}
}
...
...
@@ -414,25 +426,37 @@ void set(Mat& dst, const Scalar& gamma, const Mat& mask)
return
;
}
CV_Assert
(
dst
.
size
==
mask
.
size
&&
mask
.
type
()
==
CV_8U
);
int
cn
=
dst
.
channels
(),
mcn
=
mask
.
channels
();
CV_Assert
(
dst
.
size
==
mask
.
size
&&
(
mcn
==
1
||
mcn
==
cn
)
);
const
Mat
*
arrays
[]
=
{
&
dst
,
&
mask
,
0
};
Mat
planes
[
2
];
NAryMatIterator
it
(
arrays
,
planes
);
size_t
j
,
k
,
elemSize
=
dst
.
elemSize
(),
total
=
planes
[
0
].
total
();
size_t
j
,
k
,
elemSize
=
dst
.
elemSize
(),
maskElemSize
=
mask
.
elemSize
(),
total
=
planes
[
0
].
total
();
size_t
i
,
nplanes
=
it
.
nplanes
;
size_t
elemSize1
=
dst
.
elemSize1
();
for
(
i
=
0
;
i
<
nplanes
;
i
++
,
++
it
)
{
uchar
*
dptr
=
planes
[
0
].
ptr
();
const
uchar
*
mptr
=
planes
[
1
].
ptr
();
for
(
j
=
0
;
j
<
total
;
j
++
,
dptr
+=
elemSize
)
for
(
j
=
0
;
j
<
total
;
j
++
,
dptr
+=
elemSize
,
mptr
+=
maskElemSize
)
{
if
(
mptr
[
j
]
)
for
(
k
=
0
;
k
<
elemSize
;
k
++
)
dptr
[
k
]
=
gptr
[
k
];
if
(
mcn
==
1
)
{
if
(
mptr
[
0
]
)
for
(
k
=
0
;
k
<
elemSize
;
k
++
)
dptr
[
k
]
=
gptr
[
k
];
}
else
{
for
(
int
c
=
0
;
c
<
mcn
;
c
++
)
if
(
mptr
[
c
]
)
for
(
k
=
0
;
k
<
elemSize1
;
k
++
)
dptr
[
k
+
c
*
elemSize1
]
=
gptr
[
k
+
c
*
elemSize1
];
}
}
}
}
...
...
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