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
0b234b7a
Commit
0b234b7a
authored
Mar 29, 2012
by
Vadim Pisarevsky
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
rewritten floodfill in generic style; added CV_32S flavor (ticket #1482)
parent
554e0051
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
190 additions
and
703 deletions
+190
-703
floodfill.cpp
modules/imgproc/src/floodfill.cpp
+183
-685
test_floodfill.cpp
modules/imgproc/test/test_floodfill.cpp
+7
-18
No files found.
modules/imgproc/src/floodfill.cpp
View file @
0b234b7a
...
@@ -80,190 +80,34 @@ CvFFillSegment;
...
@@ -80,190 +80,34 @@ CvFFillSegment;
head = buffer; \
head = buffer; \
}
}
#define ICV_EQ_C3( p1, p2 ) \
((p1)[0] == (p2)[0] && (p1)[1] == (p2)[1] && (p1)[2] == (p2)[2])
#define ICV_SET_C3( p, q ) \
((p)[0] = (q)[0], (p)[1] = (q)[1], (p)[2] = (q)[2])
/****************************************************************************************\
/****************************************************************************************\
* Simple Floodfill (repainting single-color connected component) *
* Simple Floodfill (repainting single-color connected component) *
\****************************************************************************************/
\****************************************************************************************/
template
<
typename
_Tp
>
static
void
static
void
icvFloodFill_8u_CnIR
(
uchar
*
pImage
,
int
step
,
CvSize
roi
,
CvPoint
seed
,
icvFloodFill_CnIR
(
uchar
*
pImage
,
int
step
,
CvSize
roi
,
CvPoint
seed
,
uchar
*
_newVal
,
CvConnectedComp
*
region
,
int
flags
,
_Tp
newVal
,
CvConnectedComp
*
region
,
int
flags
,
CvFFillSegment
*
buffer
,
int
buffer_size
,
int
cn
)
CvFFillSegment
*
buffer
,
int
buffer_size
)
{
uchar
*
img
=
pImage
+
step
*
seed
.
y
;
int
i
,
L
,
R
;
int
area
=
0
;
int
val0
[]
=
{
0
,
0
,
0
};
uchar
newVal
[]
=
{
0
,
0
,
0
};
int
XMin
,
XMax
,
YMin
=
seed
.
y
,
YMax
=
seed
.
y
;
int
_8_connectivity
=
(
flags
&
255
)
==
8
;
CvFFillSegment
*
buffer_end
=
buffer
+
buffer_size
,
*
head
=
buffer
,
*
tail
=
buffer
;
L
=
R
=
XMin
=
XMax
=
seed
.
x
;
if
(
cn
==
1
)
{
val0
[
0
]
=
img
[
L
];
newVal
[
0
]
=
_newVal
[
0
];
img
[
L
]
=
newVal
[
0
];
while
(
++
R
<
roi
.
width
&&
img
[
R
]
==
val0
[
0
]
)
img
[
R
]
=
newVal
[
0
];
while
(
--
L
>=
0
&&
img
[
L
]
==
val0
[
0
]
)
img
[
L
]
=
newVal
[
0
];
}
else
{
assert
(
cn
==
3
);
ICV_SET_C3
(
val0
,
img
+
L
*
3
);
ICV_SET_C3
(
newVal
,
_newVal
);
ICV_SET_C3
(
img
+
L
*
3
,
newVal
);
while
(
--
L
>=
0
&&
ICV_EQ_C3
(
img
+
L
*
3
,
val0
))
ICV_SET_C3
(
img
+
L
*
3
,
newVal
);
while
(
++
R
<
roi
.
width
&&
ICV_EQ_C3
(
img
+
R
*
3
,
val0
))
ICV_SET_C3
(
img
+
R
*
3
,
newVal
);
}
XMax
=
--
R
;
XMin
=
++
L
;
ICV_PUSH
(
seed
.
y
,
L
,
R
,
R
+
1
,
R
,
UP
);
while
(
head
!=
tail
)
{
int
k
,
YC
,
PL
,
PR
,
dir
;
ICV_POP
(
YC
,
L
,
R
,
PL
,
PR
,
dir
);
int
data
[][
3
]
=
{
{
-
dir
,
L
-
_8_connectivity
,
R
+
_8_connectivity
},
{
dir
,
L
-
_8_connectivity
,
PL
-
1
},
{
dir
,
PR
+
1
,
R
+
_8_connectivity
}
};
if
(
region
)
{
area
+=
R
-
L
+
1
;
if
(
XMax
<
R
)
XMax
=
R
;
if
(
XMin
>
L
)
XMin
=
L
;
if
(
YMax
<
YC
)
YMax
=
YC
;
if
(
YMin
>
YC
)
YMin
=
YC
;
}
for
(
k
=
0
/*(unsigned)(YC - dir) >= (unsigned)roi.height*/
;
k
<
3
;
k
++
)
{
dir
=
data
[
k
][
0
];
img
=
pImage
+
(
YC
+
dir
)
*
step
;
int
left
=
data
[
k
][
1
];
int
right
=
data
[
k
][
2
];
if
(
(
unsigned
)(
YC
+
dir
)
>=
(
unsigned
)
roi
.
height
)
continue
;
if
(
cn
==
1
)
for
(
i
=
left
;
i
<=
right
;
i
++
)
{
if
(
(
unsigned
)
i
<
(
unsigned
)
roi
.
width
&&
img
[
i
]
==
val0
[
0
]
)
{
int
j
=
i
;
img
[
i
]
=
newVal
[
0
];
while
(
--
j
>=
0
&&
img
[
j
]
==
val0
[
0
]
)
img
[
j
]
=
newVal
[
0
];
while
(
++
i
<
roi
.
width
&&
img
[
i
]
==
val0
[
0
]
)
img
[
i
]
=
newVal
[
0
];
ICV_PUSH
(
YC
+
dir
,
j
+
1
,
i
-
1
,
L
,
R
,
-
dir
);
}
}
else
for
(
i
=
left
;
i
<=
right
;
i
++
)
{
if
(
(
unsigned
)
i
<
(
unsigned
)
roi
.
width
&&
ICV_EQ_C3
(
img
+
i
*
3
,
val0
))
{
int
j
=
i
;
ICV_SET_C3
(
img
+
i
*
3
,
newVal
);
while
(
--
j
>=
0
&&
ICV_EQ_C3
(
img
+
j
*
3
,
val0
))
ICV_SET_C3
(
img
+
j
*
3
,
newVal
);
while
(
++
i
<
roi
.
width
&&
ICV_EQ_C3
(
img
+
i
*
3
,
val0
))
ICV_SET_C3
(
img
+
i
*
3
,
newVal
);
ICV_PUSH
(
YC
+
dir
,
j
+
1
,
i
-
1
,
L
,
R
,
-
dir
);
}
}
}
}
if
(
region
)
{
region
->
area
=
area
;
region
->
rect
.
x
=
XMin
;
region
->
rect
.
y
=
YMin
;
region
->
rect
.
width
=
XMax
-
XMin
+
1
;
region
->
rect
.
height
=
YMax
-
YMin
+
1
;
region
->
value
=
cvScalar
(
newVal
[
0
],
newVal
[
1
],
newVal
[
2
],
0
);
}
}
/* because all the operations on floats that are done during non-gradient floodfill
are just copying and comparison on equality,
we can do the whole op on 32-bit integers instead */
static
void
icvFloodFill_32f_CnIR
(
int
*
pImage
,
int
step
,
CvSize
roi
,
CvPoint
seed
,
int
*
_newVal
,
CvConnectedComp
*
region
,
int
flags
,
CvFFillSegment
*
buffer
,
int
buffer_size
,
int
cn
)
{
{
int
*
img
=
pImage
+
(
step
/=
sizeof
(
pImage
[
0
]))
*
seed
.
y
;
typedef
typename
cv
::
DataType
<
_Tp
>::
channel_type
_CTp
;
_Tp
*
img
=
(
_Tp
*
)(
pImage
+
step
*
seed
.
y
);
int
i
,
L
,
R
;
int
i
,
L
,
R
;
int
area
=
0
;
int
area
=
0
;
int
val0
[]
=
{
0
,
0
,
0
};
int
newVal
[]
=
{
0
,
0
,
0
};
int
XMin
,
XMax
,
YMin
=
seed
.
y
,
YMax
=
seed
.
y
;
int
XMin
,
XMax
,
YMin
=
seed
.
y
,
YMax
=
seed
.
y
;
int
_8_connectivity
=
(
flags
&
255
)
==
8
;
int
_8_connectivity
=
(
flags
&
255
)
==
8
;
CvFFillSegment
*
buffer_end
=
buffer
+
buffer_size
,
*
head
=
buffer
,
*
tail
=
buffer
;
CvFFillSegment
*
buffer_end
=
buffer
+
buffer_size
,
*
head
=
buffer
,
*
tail
=
buffer
;
L
=
R
=
XMin
=
XMax
=
seed
.
x
;
L
=
R
=
XMin
=
XMax
=
seed
.
x
;
if
(
cn
==
1
)
_Tp
val0
=
img
[
L
];
{
img
[
L
]
=
newVal
;
val0
[
0
]
=
img
[
L
];
newVal
[
0
]
=
_newVal
[
0
];
img
[
L
]
=
newVal
[
0
];
while
(
++
R
<
roi
.
width
&&
img
[
R
]
==
val0
[
0
]
)
img
[
R
]
=
newVal
[
0
];
while
(
--
L
>=
0
&&
img
[
L
]
==
val0
[
0
]
)
img
[
L
]
=
newVal
[
0
];
}
else
{
assert
(
cn
==
3
);
ICV_SET_C3
(
val0
,
img
+
L
*
3
);
ICV_SET_C3
(
newVal
,
_newVal
);
ICV_SET_C3
(
img
+
L
*
3
,
newVal
);
while
(
--
L
>=
0
&&
ICV_EQ_C3
(
img
+
L
*
3
,
val0
)
)
while
(
++
R
<
roi
.
width
&&
img
[
R
]
==
val0
)
ICV_SET_C3
(
img
+
L
*
3
,
newVal
)
;
img
[
R
]
=
newVal
;
while
(
++
R
<
roi
.
width
&&
ICV_EQ_C3
(
img
+
R
*
3
,
val0
))
while
(
--
L
>=
0
&&
img
[
L
]
==
val0
)
ICV_SET_C3
(
img
+
R
*
3
,
newVal
);
img
[
L
]
=
newVal
;
}
XMax
=
--
R
;
XMax
=
--
R
;
XMin
=
++
L
;
XMin
=
++
L
;
...
@@ -291,44 +135,27 @@ icvFloodFill_32f_CnIR( int* pImage, int step, CvSize roi, CvPoint seed,
...
@@ -291,44 +135,27 @@ icvFloodFill_32f_CnIR( int* pImage, int step, CvSize roi, CvPoint seed,
if
(
YMin
>
YC
)
YMin
=
YC
;
if
(
YMin
>
YC
)
YMin
=
YC
;
}
}
for
(
k
=
0
/*(unsigned)(YC - dir) >= (unsigned)roi.height*/
;
k
<
3
;
k
++
)
for
(
k
=
0
;
k
<
3
;
k
++
)
{
{
dir
=
data
[
k
][
0
];
dir
=
data
[
k
][
0
];
img
=
pImage
+
(
YC
+
dir
)
*
step
;
img
=
(
_Tp
*
)(
pImage
+
(
YC
+
dir
)
*
step
)
;
int
left
=
data
[
k
][
1
];
int
left
=
data
[
k
][
1
];
int
right
=
data
[
k
][
2
];
int
right
=
data
[
k
][
2
];
if
(
(
unsigned
)(
YC
+
dir
)
>=
(
unsigned
)
roi
.
height
)
if
(
(
unsigned
)(
YC
+
dir
)
>=
(
unsigned
)
roi
.
height
)
continue
;
continue
;
if
(
cn
==
1
)
for
(
i
=
left
;
i
<=
right
;
i
++
)
{
if
(
(
unsigned
)
i
<
(
unsigned
)
roi
.
width
&&
img
[
i
]
==
val0
[
0
]
)
{
int
j
=
i
;
img
[
i
]
=
newVal
[
0
];
while
(
--
j
>=
0
&&
img
[
j
]
==
val0
[
0
]
)
img
[
j
]
=
newVal
[
0
];
while
(
++
i
<
roi
.
width
&&
img
[
i
]
==
val0
[
0
]
)
img
[
i
]
=
newVal
[
0
];
ICV_PUSH
(
YC
+
dir
,
j
+
1
,
i
-
1
,
L
,
R
,
-
dir
);
}
}
else
for
(
i
=
left
;
i
<=
right
;
i
++
)
for
(
i
=
left
;
i
<=
right
;
i
++
)
{
{
if
(
(
unsigned
)
i
<
(
unsigned
)
roi
.
width
&&
ICV_EQ_C3
(
img
+
i
*
3
,
val0
)
)
if
(
(
unsigned
)
i
<
(
unsigned
)
roi
.
width
&&
img
[
i
]
==
val0
)
{
{
int
j
=
i
;
int
j
=
i
;
ICV_SET_C3
(
img
+
i
*
3
,
newVal
)
;
img
[
i
]
=
newVal
;
while
(
--
j
>=
0
&&
ICV_EQ_C3
(
img
+
j
*
3
,
val0
)
)
while
(
--
j
>=
0
&&
img
[
j
]
==
val0
)
ICV_SET_C3
(
img
+
j
*
3
,
newVal
)
;
img
[
j
]
=
newVal
;
while
(
++
i
<
roi
.
width
&&
ICV_EQ_C3
(
img
+
i
*
3
,
val0
)
)
while
(
++
i
<
roi
.
width
&&
img
[
i
]
==
val0
)
ICV_SET_C3
(
img
+
i
*
3
,
newVal
)
;
img
[
i
]
=
newVal
;
ICV_PUSH
(
YC
+
dir
,
j
+
1
,
i
-
1
,
L
,
R
,
-
dir
);
ICV_PUSH
(
YC
+
dir
,
j
+
1
,
i
-
1
,
L
,
R
,
-
dir
);
}
}
...
@@ -338,14 +165,12 @@ icvFloodFill_32f_CnIR( int* pImage, int step, CvSize roi, CvPoint seed,
...
@@ -338,14 +165,12 @@ icvFloodFill_32f_CnIR( int* pImage, int step, CvSize roi, CvPoint seed,
if
(
region
)
if
(
region
)
{
{
Cv32suf
v0
,
v1
,
v2
;
region
->
area
=
area
;
region
->
area
=
area
;
region
->
rect
.
x
=
XMin
;
region
->
rect
.
x
=
XMin
;
region
->
rect
.
y
=
YMin
;
region
->
rect
.
y
=
YMin
;
region
->
rect
.
width
=
XMax
-
XMin
+
1
;
region
->
rect
.
width
=
XMax
-
XMin
+
1
;
region
->
rect
.
height
=
YMax
-
YMin
+
1
;
region
->
rect
.
height
=
YMax
-
YMin
+
1
;
v0
.
i
=
newVal
[
0
];
v1
.
i
=
newVal
[
1
];
v2
.
i
=
newVal
[
2
];
region
->
value
=
cv
::
Scalar
(
newVal
);
region
->
value
=
cvScalar
(
v0
.
f
,
v1
.
f
,
v2
.
f
);
}
}
}
}
...
@@ -353,336 +178,82 @@ icvFloodFill_32f_CnIR( int* pImage, int step, CvSize roi, CvPoint seed,
...
@@ -353,336 +178,82 @@ icvFloodFill_32f_CnIR( int* pImage, int step, CvSize roi, CvPoint seed,
* Gradient Floodfill *
* Gradient Floodfill *
\****************************************************************************************/
\****************************************************************************************/
#define DIFF_INT_C1(p1,p2) ((unsigned)((p1)[0] - (p2)[0] + d_lw[0]) <= interval[0])
struct
Diff8uC1
#define DIFF_INT_C3(p1,p2) ((unsigned)((p1)[0] - (p2)[0] + d_lw[0])<= interval[0] && \
(unsigned)((p1)[1] - (p2)[1] + d_lw[1])<= interval[1] && \
(unsigned)((p1)[2] - (p2)[2] + d_lw[2])<= interval[2])
#define DIFF_FLT_C1(p1,p2) (fabs((p1)[0] - (p2)[0] + d_lw[0]) <= interval[0])
#define DIFF_FLT_C3(p1,p2) (fabs((p1)[0] - (p2)[0] + d_lw[0]) <= interval[0] && \
fabs((p1)[1] - (p2)[1] + d_lw[1]) <= interval[1] && \
fabs((p1)[2] - (p2)[2] + d_lw[2]) <= interval[2])
static
void
icvFloodFillGrad_8u_CnIR
(
uchar
*
pImage
,
int
step
,
uchar
*
pMask
,
int
maskStep
,
CvSize
/*roi*/
,
CvPoint
seed
,
uchar
*
_newVal
,
uchar
*
_d_lw
,
uchar
*
_d_up
,
CvConnectedComp
*
region
,
int
flags
,
CvFFillSegment
*
buffer
,
int
buffer_size
,
int
cn
)
{
{
uchar
*
img
=
pImage
+
step
*
seed
.
y
;
Diff8uC1
(
uchar
_lo
,
uchar
_up
)
:
lo
(
_lo
),
interval
(
_lo
+
_up
)
{}
uchar
*
mask
=
(
pMask
+=
maskStep
+
1
)
+
maskStep
*
seed
.
y
;
bool
operator
()(
const
uchar
*
a
,
const
uchar
*
b
)
const
int
i
,
L
,
R
;
{
return
(
unsigned
)(
a
[
0
]
-
b
[
0
]
+
lo
)
<=
interval
;
}
int
area
=
0
;
unsigned
lo
,
interval
;
int
sum
[]
=
{
0
,
0
,
0
},
val0
[]
=
{
0
,
0
,
0
};
};
uchar
newVal
[]
=
{
0
,
0
,
0
};
int
d_lw
[]
=
{
0
,
0
,
0
};
unsigned
interval
[]
=
{
0
,
0
,
0
};
int
XMin
,
XMax
,
YMin
=
seed
.
y
,
YMax
=
seed
.
y
;
int
_8_connectivity
=
(
flags
&
255
)
==
8
;
int
fixedRange
=
flags
&
CV_FLOODFILL_FIXED_RANGE
;
int
fillImage
=
(
flags
&
CV_FLOODFILL_MASK_ONLY
)
==
0
;
uchar
newMaskVal
=
(
uchar
)(
flags
&
0xff00
?
flags
>>
8
:
1
);
CvFFillSegment
*
buffer_end
=
buffer
+
buffer_size
,
*
head
=
buffer
,
*
tail
=
buffer
;
L
=
R
=
seed
.
x
;
if
(
mask
[
L
]
)
return
;
mask
[
L
]
=
newMaskVal
;
for
(
i
=
0
;
i
<
cn
;
i
++
)
{
newVal
[
i
]
=
_newVal
[
i
];
d_lw
[
i
]
=
_d_lw
[
i
];
interval
[
i
]
=
(
unsigned
)(
_d_up
[
i
]
+
_d_lw
[
i
]);
if
(
fixedRange
)
val0
[
i
]
=
img
[
L
*
cn
+
i
];
}
if
(
cn
==
1
)
{
if
(
fixedRange
)
{
while
(
!
mask
[
R
+
1
]
&&
DIFF_INT_C1
(
img
+
(
R
+
1
),
val0
))
mask
[
++
R
]
=
newMaskVal
;
while
(
!
mask
[
L
-
1
]
&&
DIFF_INT_C1
(
img
+
(
L
-
1
),
val0
))
mask
[
--
L
]
=
newMaskVal
;
}
else
{
while
(
!
mask
[
R
+
1
]
&&
DIFF_INT_C1
(
img
+
(
R
+
1
),
img
+
R
))
mask
[
++
R
]
=
newMaskVal
;
while
(
!
mask
[
L
-
1
]
&&
DIFF_INT_C1
(
img
+
(
L
-
1
),
img
+
L
))
mask
[
--
L
]
=
newMaskVal
;
}
}
else
{
if
(
fixedRange
)
{
while
(
!
mask
[
R
+
1
]
&&
DIFF_INT_C3
(
img
+
(
R
+
1
)
*
3
,
val0
))
mask
[
++
R
]
=
newMaskVal
;
while
(
!
mask
[
L
-
1
]
&&
DIFF_INT_C3
(
img
+
(
L
-
1
)
*
3
,
val0
))
mask
[
--
L
]
=
newMaskVal
;
}
else
{
while
(
!
mask
[
R
+
1
]
&&
DIFF_INT_C3
(
img
+
(
R
+
1
)
*
3
,
img
+
R
*
3
))
mask
[
++
R
]
=
newMaskVal
;
while
(
!
mask
[
L
-
1
]
&&
DIFF_INT_C3
(
img
+
(
L
-
1
)
*
3
,
img
+
L
*
3
))
mask
[
--
L
]
=
newMaskVal
;
}
}
XMax
=
R
;
XMin
=
L
;
ICV_PUSH
(
seed
.
y
,
L
,
R
,
R
+
1
,
R
,
UP
);
while
(
head
!=
tail
)
{
int
k
,
YC
,
PL
,
PR
,
dir
,
curstep
;
ICV_POP
(
YC
,
L
,
R
,
PL
,
PR
,
dir
);
int
data
[][
3
]
=
{
{
-
dir
,
L
-
_8_connectivity
,
R
+
_8_connectivity
},
{
dir
,
L
-
_8_connectivity
,
PL
-
1
},
{
dir
,
PR
+
1
,
R
+
_8_connectivity
}
};
unsigned
length
=
(
unsigned
)(
R
-
L
);
if
(
region
)
{
area
+=
(
int
)
length
+
1
;
if
(
XMax
<
R
)
XMax
=
R
;
if
(
XMin
>
L
)
XMin
=
L
;
if
(
YMax
<
YC
)
YMax
=
YC
;
if
(
YMin
>
YC
)
YMin
=
YC
;
}
if
(
cn
==
1
)
{
for
(
k
=
0
;
k
<
3
;
k
++
)
{
dir
=
data
[
k
][
0
];
curstep
=
dir
*
step
;
img
=
pImage
+
(
YC
+
dir
)
*
step
;
mask
=
pMask
+
(
YC
+
dir
)
*
maskStep
;
int
left
=
data
[
k
][
1
];
int
right
=
data
[
k
][
2
];
if
(
fixedRange
)
for
(
i
=
left
;
i
<=
right
;
i
++
)
{
if
(
!
mask
[
i
]
&&
DIFF_INT_C1
(
img
+
i
,
val0
))
{
int
j
=
i
;
mask
[
i
]
=
newMaskVal
;
while
(
!
mask
[
--
j
]
&&
DIFF_INT_C1
(
img
+
j
,
val0
))
mask
[
j
]
=
newMaskVal
;
while
(
!
mask
[
++
i
]
&&
DIFF_INT_C1
(
img
+
i
,
val0
))
mask
[
i
]
=
newMaskVal
;
ICV_PUSH
(
YC
+
dir
,
j
+
1
,
i
-
1
,
L
,
R
,
-
dir
);
}
}
else
if
(
!
_8_connectivity
)
for
(
i
=
left
;
i
<=
right
;
i
++
)
{
if
(
!
mask
[
i
]
&&
DIFF_INT_C1
(
img
+
i
,
img
-
curstep
+
i
))
{
int
j
=
i
;
mask
[
i
]
=
newMaskVal
;
while
(
!
mask
[
--
j
]
&&
DIFF_INT_C1
(
img
+
j
,
img
+
(
j
+
1
)
))
mask
[
j
]
=
newMaskVal
;
while
(
!
mask
[
++
i
]
&&
struct
Diff8uC3
(
DIFF_INT_C1
(
img
+
i
,
img
+
(
i
-
1
)
)
||
{
(
DIFF_INT_C1
(
img
+
i
,
img
+
i
-
curstep
)
&&
i
<=
R
)))
Diff8uC3
(
cv
::
Vec3b
_lo
,
cv
::
Vec3b
_up
)
mask
[
i
]
=
newMaskVal
;
ICV_PUSH
(
YC
+
dir
,
j
+
1
,
i
-
1
,
L
,
R
,
-
dir
);
}
}
else
for
(
i
=
left
;
i
<=
right
;
i
++
)
{
int
idx
,
val
[
1
];
if
(
!
mask
[
i
]
&&
(((
val
[
0
]
=
img
[
i
],
(
unsigned
)(
idx
=
i
-
L
-
1
)
<=
length
)
&&
DIFF_INT_C1
(
val
,
img
-
curstep
+
(
i
-
1
)))
||
((
unsigned
)(
++
idx
)
<=
length
&&
DIFF_INT_C1
(
val
,
img
-
curstep
+
i
))
||
((
unsigned
)(
++
idx
)
<=
length
&&
DIFF_INT_C1
(
val
,
img
-
curstep
+
(
i
+
1
)
))))
{
{
int
j
=
i
;
for
(
int
k
=
0
;
k
<
3
;
k
++
)
mask
[
i
]
=
newMaskVal
;
lo
[
k
]
=
_lo
[
k
],
interval
[
k
]
=
_lo
[
k
]
+
_up
[
k
];
while
(
!
mask
[
--
j
]
&&
DIFF_INT_C1
(
img
+
j
,
img
+
(
j
+
1
)
))
mask
[
j
]
=
newMaskVal
;
while
(
!
mask
[
++
i
]
&&
((
val
[
0
]
=
img
[
i
],
DIFF_INT_C1
(
val
,
img
+
(
i
-
1
)
))
||
(((
unsigned
)(
idx
=
i
-
L
-
1
)
<=
length
&&
DIFF_INT_C1
(
val
,
img
-
curstep
+
(
i
-
1
)
)))
||
((
unsigned
)(
++
idx
)
<=
length
&&
DIFF_INT_C1
(
val
,
img
-
curstep
+
i
))
||
((
unsigned
)(
++
idx
)
<=
length
&&
DIFF_INT_C1
(
val
,
img
-
curstep
+
(
i
+
1
)
))))
mask
[
i
]
=
newMaskVal
;
ICV_PUSH
(
YC
+
dir
,
j
+
1
,
i
-
1
,
L
,
R
,
-
dir
);
}
}
}
}
bool
operator
()(
const
cv
::
Vec3b
*
a
,
const
cv
::
Vec3b
*
b
)
const
img
=
pImage
+
YC
*
step
;
if
(
fillImage
)
for
(
i
=
L
;
i
<=
R
;
i
++
)
img
[
i
]
=
newVal
[
0
];
else
if
(
region
)
for
(
i
=
L
;
i
<=
R
;
i
++
)
sum
[
0
]
+=
img
[
i
];
}
else
{
for
(
k
=
0
;
k
<
3
;
k
++
)
{
dir
=
data
[
k
][
0
];
curstep
=
dir
*
step
;
img
=
pImage
+
(
YC
+
dir
)
*
step
;
mask
=
pMask
+
(
YC
+
dir
)
*
maskStep
;
int
left
=
data
[
k
][
1
];
int
right
=
data
[
k
][
2
];
if
(
fixedRange
)
for
(
i
=
left
;
i
<=
right
;
i
++
)
{
if
(
!
mask
[
i
]
&&
DIFF_INT_C3
(
img
+
i
*
3
,
val0
))
{
{
int
j
=
i
;
return
(
unsigned
)(
a
[
0
][
0
]
-
b
[
0
][
0
]
+
lo
[
0
])
<=
interval
[
0
]
&&
mask
[
i
]
=
newMaskVal
;
(
unsigned
)(
a
[
0
][
1
]
-
b
[
0
][
1
]
+
lo
[
1
])
<=
interval
[
1
]
&&
while
(
!
mask
[
--
j
]
&&
DIFF_INT_C3
(
img
+
j
*
3
,
val0
))
(
unsigned
)(
a
[
0
][
2
]
-
b
[
0
][
2
]
+
lo
[
2
])
<=
interval
[
2
];
mask
[
j
]
=
newMaskVal
;
while
(
!
mask
[
++
i
]
&&
DIFF_INT_C3
(
img
+
i
*
3
,
val0
))
mask
[
i
]
=
newMaskVal
;
ICV_PUSH
(
YC
+
dir
,
j
+
1
,
i
-
1
,
L
,
R
,
-
dir
);
}
}
}
unsigned
lo
[
3
],
interval
[
3
];
else
if
(
!
_8_connectivity
)
};
for
(
i
=
left
;
i
<=
right
;
i
++
)
{
if
(
!
mask
[
i
]
&&
DIFF_INT_C3
(
img
+
i
*
3
,
img
-
curstep
+
i
*
3
))
{
int
j
=
i
;
mask
[
i
]
=
newMaskVal
;
while
(
!
mask
[
--
j
]
&&
DIFF_INT_C3
(
img
+
j
*
3
,
img
+
(
j
+
1
)
*
3
))
mask
[
j
]
=
newMaskVal
;
while
(
!
mask
[
++
i
]
&&
(
DIFF_INT_C3
(
img
+
i
*
3
,
img
+
(
i
-
1
)
*
3
)
||
(
DIFF_INT_C3
(
img
+
i
*
3
,
img
+
i
*
3
-
curstep
)
&&
i
<=
R
)))
mask
[
i
]
=
newMaskVal
;
ICV_PUSH
(
YC
+
dir
,
j
+
1
,
i
-
1
,
L
,
R
,
-
dir
);
}
}
else
for
(
i
=
left
;
i
<=
right
;
i
++
)
{
int
idx
,
val
[
3
];
if
(
!
mask
[
i
]
&&
template
<
typename
_Tp
>
(((
ICV_SET_C3
(
val
,
img
+
i
*
3
),
struct
DiffC1
(
unsigned
)(
idx
=
i
-
L
-
1
)
<=
length
)
&&
{
DIFF_INT_C3
(
val
,
img
-
curstep
+
(
i
-
1
)
*
3
))
||
DiffC1
(
_Tp
_lo
,
_Tp
_up
)
:
lo
(
-
_lo
),
up
(
_up
)
{}
((
unsigned
)(
++
idx
)
<=
length
&&
bool
operator
()(
const
_Tp
*
a
,
const
_Tp
*
b
)
const
DIFF_INT_C3
(
val
,
img
-
curstep
+
i
*
3
))
||
((
unsigned
)(
++
idx
)
<=
length
&&
DIFF_INT_C3
(
val
,
img
-
curstep
+
(
i
+
1
)
*
3
))))
{
{
int
j
=
i
;
_Tp
d
=
a
[
0
]
-
b
[
0
];
mask
[
i
]
=
newMaskVal
;
return
lo
<=
d
&&
d
<=
up
;
while
(
!
mask
[
--
j
]
&&
DIFF_INT_C3
(
img
+
j
*
3
,
img
+
(
j
+
1
)
*
3
))
mask
[
j
]
=
newMaskVal
;
while
(
!
mask
[
++
i
]
&&
((
ICV_SET_C3
(
val
,
img
+
i
*
3
),
DIFF_INT_C3
(
val
,
img
+
(
i
-
1
)
*
3
))
||
(((
unsigned
)(
idx
=
i
-
L
-
1
)
<=
length
&&
DIFF_INT_C3
(
val
,
img
-
curstep
+
(
i
-
1
)
*
3
)))
||
((
unsigned
)(
++
idx
)
<=
length
&&
DIFF_INT_C3
(
val
,
img
-
curstep
+
i
*
3
))
||
((
unsigned
)(
++
idx
)
<=
length
&&
DIFF_INT_C3
(
val
,
img
-
curstep
+
(
i
+
1
)
*
3
))))
mask
[
i
]
=
newMaskVal
;
ICV_PUSH
(
YC
+
dir
,
j
+
1
,
i
-
1
,
L
,
R
,
-
dir
);
}
}
}
}
_Tp
lo
,
up
;
};
img
=
pImage
+
YC
*
step
;
template
<
typename
_Tp
>
if
(
fillImage
)
struct
DiffC3
for
(
i
=
L
;
i
<=
R
;
i
++
)
{
ICV_SET_C3
(
img
+
i
*
3
,
newVal
);
DiffC3
(
_Tp
_lo
,
_Tp
_up
)
:
lo
(
-
_lo
),
up
(
_up
)
{}
else
if
(
region
)
bool
operator
()(
const
_Tp
*
a
,
const
_Tp
*
b
)
const
for
(
i
=
L
;
i
<=
R
;
i
++
)
{
{
sum
[
0
]
+=
img
[
i
*
3
];
_Tp
d
=
*
a
-
*
b
;
sum
[
1
]
+=
img
[
i
*
3
+
1
];
return
lo
[
0
]
<=
d
[
0
]
&&
d
[
0
]
<=
up
[
0
]
&&
sum
[
2
]
+=
img
[
i
*
3
+
2
];
lo
[
1
]
<=
d
[
1
]
&&
d
[
1
]
<=
up
[
1
]
&&
}
lo
[
2
]
<=
d
[
2
]
&&
d
[
2
]
<=
up
[
2
];
}
}
}
_Tp
lo
,
up
;
};
if
(
region
)
typedef
DiffC1
<
int
>
Diff32sC1
;
{
typedef
DiffC3
<
cv
::
Vec3i
>
Diff32sC3
;
region
->
area
=
area
;
typedef
DiffC1
<
float
>
Diff32fC1
;
region
->
rect
.
x
=
XMin
;
typedef
DiffC3
<
cv
::
Vec3f
>
Diff32fC3
;
region
->
rect
.
y
=
YMin
;
region
->
rect
.
width
=
XMax
-
XMin
+
1
;
region
->
rect
.
height
=
YMax
-
YMin
+
1
;
if
(
fillImage
)
cv
::
Vec3i
&
operator
+=
(
cv
::
Vec3i
&
a
,
const
cv
::
Vec3b
&
b
)
region
->
value
=
cvScalar
(
newVal
[
0
],
newVal
[
1
],
newVal
[
2
]);
{
else
a
[
0
]
+=
b
[
0
];
{
a
[
1
]
+=
b
[
1
];
double
iarea
=
area
?
1.
/
area
:
0
;
a
[
2
]
+=
b
[
2
];
region
->
value
=
cvScalar
(
sum
[
0
]
*
iarea
,
sum
[
1
]
*
iarea
,
sum
[
2
]
*
iarea
);
return
a
;
}
}
}
}
template
<
typename
_Tp
,
typename
_WTp
,
class
Diff
>
static
void
static
void
icvFloodFillGrad_
32f_CnIR
(
float
*
pImage
,
int
step
,
uchar
*
pMask
,
int
maskStep
,
icvFloodFillGrad_
CnIR
(
uchar
*
pImage
,
int
step
,
uchar
*
pMask
,
int
maskStep
,
CvSize
/*roi*/
,
CvPoint
seed
,
float
*
_newVal
,
float
*
_d_lw
,
CvSize
/*roi*/
,
CvPoint
seed
,
_Tp
newVal
,
Diff
diff
,
float
*
_d_up
,
CvConnectedComp
*
region
,
int
flags
,
CvConnectedComp
*
region
,
int
flags
,
CvFFillSegment
*
buffer
,
int
buffer_size
,
int
cn
)
CvFFillSegment
*
buffer
,
int
buffer_size
)
{
{
float
*
img
=
pImage
+
(
step
/=
sizeof
(
float
))
*
seed
.
y
;
typedef
typename
cv
::
DataType
<
_Tp
>::
channel_type
_CTp
;
_Tp
*
img
=
(
_Tp
*
)(
pImage
+
step
*
seed
.
y
);
uchar
*
mask
=
(
pMask
+=
maskStep
+
1
)
+
maskStep
*
seed
.
y
;
uchar
*
mask
=
(
pMask
+=
maskStep
+
1
)
+
maskStep
*
seed
.
y
;
int
i
,
L
,
R
;
int
i
,
L
,
R
;
int
area
=
0
;
int
area
=
0
;
double
sum
[]
=
{
0
,
0
,
0
},
val0
[]
=
{
0
,
0
,
0
};
_WTp
sum
=
_WTp
((
typename
cv
::
DataType
<
_Tp
>::
channel_type
)
0
);
float
newVal
[]
=
{
0
,
0
,
0
};
float
d_lw
[]
=
{
0
,
0
,
0
};
float
interval
[]
=
{
0
,
0
,
0
};
int
XMin
,
XMax
,
YMin
=
seed
.
y
,
YMax
=
seed
.
y
;
int
XMin
,
XMax
,
YMin
=
seed
.
y
,
YMax
=
seed
.
y
;
int
_8_connectivity
=
(
flags
&
255
)
==
8
;
int
_8_connectivity
=
(
flags
&
255
)
==
8
;
int
fixedRange
=
flags
&
CV_FLOODFILL_FIXED_RANGE
;
int
fixedRange
=
flags
&
CV_FLOODFILL_FIXED_RANGE
;
...
@@ -695,54 +266,24 @@ icvFloodFillGrad_32f_CnIR( float* pImage, int step, uchar* pMask, int maskStep,
...
@@ -695,54 +266,24 @@ icvFloodFillGrad_32f_CnIR( float* pImage, int step, uchar* pMask, int maskStep,
return
;
return
;
mask
[
L
]
=
newMaskVal
;
mask
[
L
]
=
newMaskVal
;
_Tp
val0
=
img
[
L
];
for
(
i
=
0
;
i
<
cn
;
i
++
)
{
newVal
[
i
]
=
_newVal
[
i
];
d_lw
[
i
]
=
0.5
f
*
(
_d_lw
[
i
]
-
_d_up
[
i
]);
interval
[
i
]
=
0.5
f
*
(
_d_lw
[
i
]
+
_d_up
[
i
]);
if
(
fixedRange
)
val0
[
i
]
=
img
[
L
*
cn
+
i
];
}
if
(
cn
==
1
)
{
if
(
fixedRange
)
{
while
(
!
mask
[
R
+
1
]
&&
DIFF_FLT_C1
(
img
+
(
R
+
1
),
val0
))
mask
[
++
R
]
=
newMaskVal
;
while
(
!
mask
[
L
-
1
]
&&
DIFF_FLT_C1
(
img
+
(
L
-
1
),
val0
))
mask
[
--
L
]
=
newMaskVal
;
}
else
{
while
(
!
mask
[
R
+
1
]
&&
DIFF_FLT_C1
(
img
+
(
R
+
1
),
img
+
R
))
mask
[
++
R
]
=
newMaskVal
;
while
(
!
mask
[
L
-
1
]
&&
DIFF_FLT_C1
(
img
+
(
L
-
1
),
img
+
L
))
mask
[
--
L
]
=
newMaskVal
;
}
}
else
{
if
(
fixedRange
)
if
(
fixedRange
)
{
{
while
(
!
mask
[
R
+
1
]
&&
DIFF_FLT_C3
(
img
+
(
R
+
1
)
*
3
,
val0
))
while
(
!
mask
[
R
+
1
]
&&
diff
(
img
+
(
R
+
1
),
&
val0
))
mask
[
++
R
]
=
newMaskVal
;
mask
[
++
R
]
=
newMaskVal
;
while
(
!
mask
[
L
-
1
]
&&
DIFF_FLT_C3
(
img
+
(
L
-
1
)
*
3
,
val0
))
while
(
!
mask
[
L
-
1
]
&&
diff
(
img
+
(
L
-
1
),
&
val0
))
mask
[
--
L
]
=
newMaskVal
;
mask
[
--
L
]
=
newMaskVal
;
}
}
else
else
{
{
while
(
!
mask
[
R
+
1
]
&&
DIFF_FLT_C3
(
img
+
(
R
+
1
)
*
3
,
img
+
R
*
3
))
while
(
!
mask
[
R
+
1
]
&&
diff
(
img
+
(
R
+
1
),
img
+
R
))
mask
[
++
R
]
=
newMaskVal
;
mask
[
++
R
]
=
newMaskVal
;
while
(
!
mask
[
L
-
1
]
&&
DIFF_FLT_C3
(
img
+
(
L
-
1
)
*
3
,
img
+
L
*
3
))
while
(
!
mask
[
L
-
1
]
&&
diff
(
img
+
(
L
-
1
),
img
+
L
))
mask
[
--
L
]
=
newMaskVal
;
mask
[
--
L
]
=
newMaskVal
;
}
}
}
XMax
=
R
;
XMax
=
R
;
XMin
=
L
;
XMin
=
L
;
...
@@ -750,7 +291,7 @@ icvFloodFillGrad_32f_CnIR( float* pImage, int step, uchar* pMask, int maskStep,
...
@@ -750,7 +291,7 @@ icvFloodFillGrad_32f_CnIR( float* pImage, int step, uchar* pMask, int maskStep,
while
(
head
!=
tail
)
while
(
head
!=
tail
)
{
{
int
k
,
YC
,
PL
,
PR
,
dir
,
curstep
;
int
k
,
YC
,
PL
,
PR
,
dir
;
ICV_POP
(
YC
,
L
,
R
,
PL
,
PR
,
dir
);
ICV_POP
(
YC
,
L
,
R
,
PL
,
PR
,
dir
);
int
data
[][
3
]
=
int
data
[][
3
]
=
...
@@ -772,13 +313,11 @@ icvFloodFillGrad_32f_CnIR( float* pImage, int step, uchar* pMask, int maskStep,
...
@@ -772,13 +313,11 @@ icvFloodFillGrad_32f_CnIR( float* pImage, int step, uchar* pMask, int maskStep,
if
(
YMin
>
YC
)
YMin
=
YC
;
if
(
YMin
>
YC
)
YMin
=
YC
;
}
}
if
(
cn
==
1
)
{
for
(
k
=
0
;
k
<
3
;
k
++
)
for
(
k
=
0
;
k
<
3
;
k
++
)
{
{
dir
=
data
[
k
][
0
];
dir
=
data
[
k
][
0
];
curstep
=
dir
*
step
;
img
=
(
_Tp
*
)(
pImage
+
(
YC
+
dir
)
*
step
)
;
img
=
pImage
+
(
YC
+
dir
)
*
step
;
_Tp
*
img1
=
(
_Tp
*
)(
pImage
+
YC
*
step
)
;
mask
=
pMask
+
(
YC
+
dir
)
*
maskStep
;
mask
=
pMask
+
(
YC
+
dir
)
*
maskStep
;
int
left
=
data
[
k
][
1
];
int
left
=
data
[
k
][
1
];
int
right
=
data
[
k
][
2
];
int
right
=
data
[
k
][
2
];
...
@@ -786,14 +325,14 @@ icvFloodFillGrad_32f_CnIR( float* pImage, int step, uchar* pMask, int maskStep,
...
@@ -786,14 +325,14 @@ icvFloodFillGrad_32f_CnIR( float* pImage, int step, uchar* pMask, int maskStep,
if
(
fixedRange
)
if
(
fixedRange
)
for
(
i
=
left
;
i
<=
right
;
i
++
)
for
(
i
=
left
;
i
<=
right
;
i
++
)
{
{
if
(
!
mask
[
i
]
&&
DIFF_FLT_C1
(
img
+
i
,
val0
))
if
(
!
mask
[
i
]
&&
diff
(
img
+
i
,
&
val0
))
{
{
int
j
=
i
;
int
j
=
i
;
mask
[
i
]
=
newMaskVal
;
mask
[
i
]
=
newMaskVal
;
while
(
!
mask
[
--
j
]
&&
DIFF_FLT_C1
(
img
+
j
,
val0
))
while
(
!
mask
[
--
j
]
&&
diff
(
img
+
j
,
&
val0
))
mask
[
j
]
=
newMaskVal
;
mask
[
j
]
=
newMaskVal
;
while
(
!
mask
[
++
i
]
&&
DIFF_FLT_C1
(
img
+
i
,
val0
))
while
(
!
mask
[
++
i
]
&&
diff
(
img
+
i
,
&
val0
))
mask
[
i
]
=
newMaskVal
;
mask
[
i
]
=
newMaskVal
;
ICV_PUSH
(
YC
+
dir
,
j
+
1
,
i
-
1
,
L
,
R
,
-
dir
);
ICV_PUSH
(
YC
+
dir
,
j
+
1
,
i
-
1
,
L
,
R
,
-
dir
);
...
@@ -802,16 +341,16 @@ icvFloodFillGrad_32f_CnIR( float* pImage, int step, uchar* pMask, int maskStep,
...
@@ -802,16 +341,16 @@ icvFloodFillGrad_32f_CnIR( float* pImage, int step, uchar* pMask, int maskStep,
else
if
(
!
_8_connectivity
)
else
if
(
!
_8_connectivity
)
for
(
i
=
left
;
i
<=
right
;
i
++
)
for
(
i
=
left
;
i
<=
right
;
i
++
)
{
{
if
(
!
mask
[
i
]
&&
DIFF_FLT_C1
(
img
+
i
,
img
-
curstep
+
i
))
if
(
!
mask
[
i
]
&&
diff
(
img
+
i
,
img1
+
i
))
{
{
int
j
=
i
;
int
j
=
i
;
mask
[
i
]
=
newMaskVal
;
mask
[
i
]
=
newMaskVal
;
while
(
!
mask
[
--
j
]
&&
DIFF_FLT_C1
(
img
+
j
,
img
+
(
j
+
1
)
))
while
(
!
mask
[
--
j
]
&&
diff
(
img
+
j
,
img
+
(
j
+
1
)
))
mask
[
j
]
=
newMaskVal
;
mask
[
j
]
=
newMaskVal
;
while
(
!
mask
[
++
i
]
&&
while
(
!
mask
[
++
i
]
&&
(
DIFF_FLT_C1
(
img
+
i
,
img
+
(
i
-
1
)
)
||
(
diff
(
img
+
i
,
img
+
(
i
-
1
)
)
||
(
DIFF_FLT_C1
(
img
+
i
,
img
+
i
-
curstep
)
&&
i
<=
R
)))
(
diff
(
img
+
i
,
img1
+
i
)
&&
i
<=
R
)))
mask
[
i
]
=
newMaskVal
;
mask
[
i
]
=
newMaskVal
;
ICV_PUSH
(
YC
+
dir
,
j
+
1
,
i
-
1
,
L
,
R
,
-
dir
);
ICV_PUSH
(
YC
+
dir
,
j
+
1
,
i
-
1
,
L
,
R
,
-
dir
);
...
@@ -821,31 +360,31 @@ icvFloodFillGrad_32f_CnIR( float* pImage, int step, uchar* pMask, int maskStep,
...
@@ -821,31 +360,31 @@ icvFloodFillGrad_32f_CnIR( float* pImage, int step, uchar* pMask, int maskStep,
for
(
i
=
left
;
i
<=
right
;
i
++
)
for
(
i
=
left
;
i
<=
right
;
i
++
)
{
{
int
idx
;
int
idx
;
float
val
[
1
]
;
_Tp
val
;
if
(
!
mask
[
i
]
&&
if
(
!
mask
[
i
]
&&
(((
val
[
0
]
=
img
[
i
],
(((
val
=
img
[
i
],
(
unsigned
)(
idx
=
i
-
L
-
1
)
<=
length
)
&&
(
unsigned
)(
idx
=
i
-
L
-
1
)
<=
length
)
&&
DIFF_FLT_C1
(
val
,
img
-
curstep
+
(
i
-
1
)
))
||
diff
(
&
val
,
img1
+
(
i
-
1
)
))
||
((
unsigned
)(
++
idx
)
<=
length
&&
((
unsigned
)(
++
idx
)
<=
length
&&
DIFF_FLT_C1
(
val
,
img
-
curstep
+
i
))
||
diff
(
&
val
,
img1
+
i
))
||
((
unsigned
)(
++
idx
)
<=
length
&&
((
unsigned
)(
++
idx
)
<=
length
&&
DIFF_FLT_C1
(
val
,
img
-
curstep
+
(
i
+
1
)
))))
diff
(
&
val
,
img1
+
(
i
+
1
)
))))
{
{
int
j
=
i
;
int
j
=
i
;
mask
[
i
]
=
newMaskVal
;
mask
[
i
]
=
newMaskVal
;
while
(
!
mask
[
--
j
]
&&
DIFF_FLT_C1
(
img
+
j
,
img
+
(
j
+
1
)
))
while
(
!
mask
[
--
j
]
&&
diff
(
img
+
j
,
img
+
(
j
+
1
)
))
mask
[
j
]
=
newMaskVal
;
mask
[
j
]
=
newMaskVal
;
while
(
!
mask
[
++
i
]
&&
while
(
!
mask
[
++
i
]
&&
((
val
[
0
]
=
img
[
i
],
((
val
=
img
[
i
],
DIFF_FLT_C1
(
val
,
img
+
(
i
-
1
)
))
||
diff
(
&
val
,
img
+
(
i
-
1
)
))
||
(((
unsigned
)(
idx
=
i
-
L
-
1
)
<=
length
&&
(((
unsigned
)(
idx
=
i
-
L
-
1
)
<=
length
&&
DIFF_FLT_C1
(
val
,
img
-
curstep
+
(
i
-
1
)
)))
||
diff
(
&
val
,
img1
+
(
i
-
1
)
)))
||
((
unsigned
)(
++
idx
)
<=
length
&&
((
unsigned
)(
++
idx
)
<=
length
&&
DIFF_FLT_C1
(
val
,
img
-
curstep
+
i
))
||
diff
(
&
val
,
img1
+
i
))
||
((
unsigned
)(
++
idx
)
<=
length
&&
((
unsigned
)(
++
idx
)
<=
length
&&
DIFF_FLT_C1
(
val
,
img
-
curstep
+
(
i
+
1
)
))))
diff
(
&
val
,
img1
+
(
i
+
1
)
))))
mask
[
i
]
=
newMaskVal
;
mask
[
i
]
=
newMaskVal
;
ICV_PUSH
(
YC
+
dir
,
j
+
1
,
i
-
1
,
L
,
R
,
-
dir
);
ICV_PUSH
(
YC
+
dir
,
j
+
1
,
i
-
1
,
L
,
R
,
-
dir
);
...
@@ -853,107 +392,13 @@ icvFloodFillGrad_32f_CnIR( float* pImage, int step, uchar* pMask, int maskStep,
...
@@ -853,107 +392,13 @@ icvFloodFillGrad_32f_CnIR( float* pImage, int step, uchar* pMask, int maskStep,
}
}
}
}
img
=
pImage
+
YC
*
step
;
img
=
(
_Tp
*
)(
pImage
+
YC
*
step
)
;
if
(
fillImage
)
if
(
fillImage
)
for
(
i
=
L
;
i
<=
R
;
i
++
)
for
(
i
=
L
;
i
<=
R
;
i
++
)
img
[
i
]
=
newVal
[
0
]
;
img
[
i
]
=
newVal
;
else
if
(
region
)
else
if
(
region
)
for
(
i
=
L
;
i
<=
R
;
i
++
)
for
(
i
=
L
;
i
<=
R
;
i
++
)
sum
[
0
]
+=
img
[
i
];
sum
+=
img
[
i
];
}
else
{
for
(
k
=
0
;
k
<
3
;
k
++
)
{
dir
=
data
[
k
][
0
];
curstep
=
dir
*
step
;
img
=
pImage
+
(
YC
+
dir
)
*
step
;
mask
=
pMask
+
(
YC
+
dir
)
*
maskStep
;
int
left
=
data
[
k
][
1
];
int
right
=
data
[
k
][
2
];
if
(
fixedRange
)
for
(
i
=
left
;
i
<=
right
;
i
++
)
{
if
(
!
mask
[
i
]
&&
DIFF_FLT_C3
(
img
+
i
*
3
,
val0
))
{
int
j
=
i
;
mask
[
i
]
=
newMaskVal
;
while
(
!
mask
[
--
j
]
&&
DIFF_FLT_C3
(
img
+
j
*
3
,
val0
))
mask
[
j
]
=
newMaskVal
;
while
(
!
mask
[
++
i
]
&&
DIFF_FLT_C3
(
img
+
i
*
3
,
val0
))
mask
[
i
]
=
newMaskVal
;
ICV_PUSH
(
YC
+
dir
,
j
+
1
,
i
-
1
,
L
,
R
,
-
dir
);
}
}
else
if
(
!
_8_connectivity
)
for
(
i
=
left
;
i
<=
right
;
i
++
)
{
if
(
!
mask
[
i
]
&&
DIFF_FLT_C3
(
img
+
i
*
3
,
img
-
curstep
+
i
*
3
))
{
int
j
=
i
;
mask
[
i
]
=
newMaskVal
;
while
(
!
mask
[
--
j
]
&&
DIFF_FLT_C3
(
img
+
j
*
3
,
img
+
(
j
+
1
)
*
3
))
mask
[
j
]
=
newMaskVal
;
while
(
!
mask
[
++
i
]
&&
(
DIFF_FLT_C3
(
img
+
i
*
3
,
img
+
(
i
-
1
)
*
3
)
||
(
DIFF_FLT_C3
(
img
+
i
*
3
,
img
+
i
*
3
-
curstep
)
&&
i
<=
R
)))
mask
[
i
]
=
newMaskVal
;
ICV_PUSH
(
YC
+
dir
,
j
+
1
,
i
-
1
,
L
,
R
,
-
dir
);
}
}
else
for
(
i
=
left
;
i
<=
right
;
i
++
)
{
int
idx
;
float
val
[
3
];
if
(
!
mask
[
i
]
&&
(((
ICV_SET_C3
(
val
,
img
+
i
*
3
),
(
unsigned
)(
idx
=
i
-
L
-
1
)
<=
length
)
&&
DIFF_FLT_C3
(
val
,
img
-
curstep
+
(
i
-
1
)
*
3
))
||
((
unsigned
)(
++
idx
)
<=
length
&&
DIFF_FLT_C3
(
val
,
img
-
curstep
+
i
*
3
))
||
((
unsigned
)(
++
idx
)
<=
length
&&
DIFF_FLT_C3
(
val
,
img
-
curstep
+
(
i
+
1
)
*
3
))))
{
int
j
=
i
;
mask
[
i
]
=
newMaskVal
;
while
(
!
mask
[
--
j
]
&&
DIFF_FLT_C3
(
img
+
j
*
3
,
img
+
(
j
+
1
)
*
3
))
mask
[
j
]
=
newMaskVal
;
while
(
!
mask
[
++
i
]
&&
((
ICV_SET_C3
(
val
,
img
+
i
*
3
),
DIFF_FLT_C3
(
val
,
img
+
(
i
-
1
)
*
3
))
||
(((
unsigned
)(
idx
=
i
-
L
-
1
)
<=
length
&&
DIFF_FLT_C3
(
val
,
img
-
curstep
+
(
i
-
1
)
*
3
)))
||
((
unsigned
)(
++
idx
)
<=
length
&&
DIFF_FLT_C3
(
val
,
img
-
curstep
+
i
*
3
))
||
((
unsigned
)(
++
idx
)
<=
length
&&
DIFF_FLT_C3
(
val
,
img
-
curstep
+
(
i
+
1
)
*
3
))))
mask
[
i
]
=
newMaskVal
;
ICV_PUSH
(
YC
+
dir
,
j
+
1
,
i
-
1
,
L
,
R
,
-
dir
);
}
}
}
img
=
pImage
+
YC
*
step
;
if
(
fillImage
)
for
(
i
=
L
;
i
<=
R
;
i
++
)
ICV_SET_C3
(
img
+
i
*
3
,
newVal
);
else
if
(
region
)
for
(
i
=
L
;
i
<=
R
;
i
++
)
{
sum
[
0
]
+=
img
[
i
*
3
];
sum
[
1
]
+=
img
[
i
*
3
+
1
];
sum
[
2
]
+=
img
[
i
*
3
+
2
];
}
}
}
}
if
(
region
)
if
(
region
)
...
@@ -965,11 +410,11 @@ icvFloodFillGrad_32f_CnIR( float* pImage, int step, uchar* pMask, int maskStep,
...
@@ -965,11 +410,11 @@ icvFloodFillGrad_32f_CnIR( float* pImage, int step, uchar* pMask, int maskStep,
region
->
rect
.
height
=
YMax
-
YMin
+
1
;
region
->
rect
.
height
=
YMax
-
YMin
+
1
;
if
(
fillImage
)
if
(
fillImage
)
region
->
value
=
cv
Scalar
(
newVal
[
0
],
newVal
[
1
],
newVal
[
2
]
);
region
->
value
=
cv
::
Scalar
(
newVal
);
else
else
{
{
double
iarea
=
area
?
1.
/
area
:
0
;
double
iarea
=
area
?
1.
/
area
:
0
;
region
->
value
=
cv
Scalar
(
sum
[
0
]
*
iarea
,
sum
[
1
]
*
iarea
,
sum
[
2
]
*
iarea
);
region
->
value
=
cv
::
Scalar
(
sum
*
iarea
);
}
}
}
}
}
}
...
@@ -1002,7 +447,7 @@ cvFloodFill( CvArr* arr, CvPoint seed_point,
...
@@ -1002,7 +447,7 @@ cvFloodFill( CvArr* arr, CvPoint seed_point,
int
i
,
type
,
depth
,
cn
,
is_simple
;
int
i
,
type
,
depth
,
cn
,
is_simple
;
int
buffer_size
,
connectivity
=
flags
&
255
;
int
buffer_size
,
connectivity
=
flags
&
255
;
double
nv_buf
[
4
]
=
{
0
,
0
,
0
,
0
};
double
nv_buf
[
4
]
=
{
0
,
0
,
0
,
0
};
union
{
uchar
b
[
4
];
float
f
[
4
]
;
}
ld_buf
,
ud_buf
;
struct
{
cv
::
Vec3b
b
;
cv
::
Vec3i
i
;
cv
::
Vec3f
f
;
}
ld_buf
,
ud_buf
;
CvMat
stub
,
*
img
=
cvGetMat
(
arr
,
&
stub
);
CvMat
stub
,
*
img
=
cvGetMat
(
arr
,
&
stub
);
CvMat
maskstub
,
*
mask
=
(
CvMat
*
)
maskarr
;
CvMat
maskstub
,
*
mask
=
(
CvMat
*
)
maskarr
;
CvSize
size
;
CvSize
size
;
...
@@ -1037,32 +482,40 @@ cvFloodFill( CvArr* arr, CvPoint seed_point,
...
@@ -1037,32 +482,40 @@ cvFloodFill( CvArr* arr, CvPoint seed_point,
if
(
is_simple
)
if
(
is_simple
)
{
{
int
elem_size
=
CV_ELEM_SIZE
(
type
);
/*
int elem_size = CV_ELEM_SIZE(type);
const uchar* seed_ptr = img->data.ptr + img->step*seed_point.y + elem_size*seed_point.x;
const uchar* seed_ptr = img->data.ptr + img->step*seed_point.y + elem_size*seed_point.x;
CvFloodFillFunc
func
=
type
==
CV_8UC1
||
type
==
CV_8UC3
?
(
CvFloodFillFunc
)
icvFloodFill_8u_CnIR
:
type
==
CV_32FC1
||
type
==
CV_32FC3
?
(
CvFloodFillFunc
)
icvFloodFill_32f_CnIR
:
0
;
if
(
!
func
)
CV_Error
(
CV_StsUnsupportedFormat
,
""
);
// check if the new value is different from the current value at the seed point.
// check if the new value is different from the current value at the seed point.
// if they are exactly the same, use the generic version with mask to avoid infinite loops.
// if they are exactly the same, use the generic version with mask to avoid infinite loops.
for( i = 0; i < elem_size; i++ )
for( i = 0; i < elem_size; i++ )
if( seed_ptr[i] != ((uchar*)nv_buf)[i] )
if( seed_ptr[i] != ((uchar*)nv_buf)[i] )
break;
break;
if
(
i
<
elem_size
)
{
func
(
img
->
data
.
ptr
,
img
->
step
,
size
,
seed_point
,
&
nv_buf
,
comp
,
flags
,
buffer
,
buffer_size
,
cn
);
return
;
}
}
CvFloodFillGradFunc
func
=
if( i == elem_size )
type
==
CV_8UC1
||
type
==
CV_8UC3
?
(
CvFloodFillGradFunc
)
icvFloodFillGrad_8u_CnIR
:
return;*/
type
==
CV_32FC1
||
type
==
CV_32FC3
?
(
CvFloodFillGradFunc
)
icvFloodFillGrad_32f_CnIR
:
0
;
if
(
!
func
)
if
(
type
==
CV_8UC1
)
icvFloodFill_CnIR
(
img
->
data
.
ptr
,
img
->
step
,
size
,
seed_point
,
((
uchar
*
)
nv_buf
)[
0
],
comp
,
flags
,
buffer
,
buffer_size
);
else
if
(
type
==
CV_8UC3
)
icvFloodFill_CnIR
(
img
->
data
.
ptr
,
img
->
step
,
size
,
seed_point
,
((
cv
::
Vec3b
*
)
nv_buf
)[
0
],
comp
,
flags
,
buffer
,
buffer_size
);
else
if
(
type
==
CV_32SC1
)
icvFloodFill_CnIR
(
img
->
data
.
ptr
,
img
->
step
,
size
,
seed_point
,
((
int
*
)
nv_buf
)[
0
],
comp
,
flags
,
buffer
,
buffer_size
);
else
if
(
type
==
CV_32FC1
)
icvFloodFill_CnIR
(
img
->
data
.
ptr
,
img
->
step
,
size
,
seed_point
,
((
float
*
)
nv_buf
)[
0
],
comp
,
flags
,
buffer
,
buffer_size
);
else
if
(
type
==
CV_32SC3
)
icvFloodFill_CnIR
(
img
->
data
.
ptr
,
img
->
step
,
size
,
seed_point
,
((
cv
::
Vec3i
*
)
nv_buf
)[
0
],
comp
,
flags
,
buffer
,
buffer_size
);
else
if
(
type
==
CV_32FC3
)
icvFloodFill_CnIR
(
img
->
data
.
ptr
,
img
->
step
,
size
,
seed_point
,
((
cv
::
Vec3f
*
)
nv_buf
)[
0
],
comp
,
flags
,
buffer
,
buffer_size
);
else
CV_Error
(
CV_StsUnsupportedFormat
,
""
);
CV_Error
(
CV_StsUnsupportedFormat
,
""
);
return
;
}
if
(
!
mask
)
if
(
!
mask
)
{
{
...
@@ -1101,16 +554,61 @@ cvFloodFill( CvArr* arr, CvPoint seed_point,
...
@@ -1101,16 +554,61 @@ cvFloodFill( CvArr* arr, CvPoint seed_point,
t
=
cvFloor
(
up_diff
.
val
[
i
]);
t
=
cvFloor
(
up_diff
.
val
[
i
]);
ud_buf
.
b
[
i
]
=
CV_CAST_8U
(
t
);
ud_buf
.
b
[
i
]
=
CV_CAST_8U
(
t
);
}
}
else
else
if
(
depth
==
CV_32S
)
for
(
i
=
0
;
i
<
cn
;
i
++
)
{
int
t
=
cvFloor
(
lo_diff
.
val
[
i
]);
ld_buf
.
i
[
i
]
=
t
;
t
=
cvFloor
(
up_diff
.
val
[
i
]);
ud_buf
.
i
[
i
]
=
t
;
}
else
if
(
depth
==
CV_32F
)
for
(
i
=
0
;
i
<
cn
;
i
++
)
for
(
i
=
0
;
i
<
cn
;
i
++
)
{
{
ld_buf
.
f
[
i
]
=
(
float
)
lo_diff
.
val
[
i
];
ld_buf
.
f
[
i
]
=
(
float
)
lo_diff
.
val
[
i
];
ud_buf
.
f
[
i
]
=
(
float
)
up_diff
.
val
[
i
];
ud_buf
.
f
[
i
]
=
(
float
)
up_diff
.
val
[
i
];
}
}
else
CV_Error
(
CV_StsUnsupportedFormat
,
""
);
func
(
img
->
data
.
ptr
,
img
->
step
,
mask
->
data
.
ptr
,
mask
->
step
,
if
(
type
==
CV_8UC1
)
size
,
seed_point
,
&
nv_buf
,
ld_buf
.
f
,
ud_buf
.
f
,
icvFloodFillGrad_CnIR
<
uchar
,
int
,
Diff8uC1
>
(
comp
,
flags
,
buffer
,
buffer_size
,
cn
);
img
->
data
.
ptr
,
img
->
step
,
mask
->
data
.
ptr
,
mask
->
step
,
size
,
seed_point
,
((
uchar
*
)
nv_buf
)[
0
],
Diff8uC1
(
ld_buf
.
b
[
0
],
ud_buf
.
b
[
0
]),
comp
,
flags
,
buffer
,
buffer_size
);
else
if
(
type
==
CV_8UC3
)
icvFloodFillGrad_CnIR
<
cv
::
Vec3b
,
cv
::
Vec3i
,
Diff8uC3
>
(
img
->
data
.
ptr
,
img
->
step
,
mask
->
data
.
ptr
,
mask
->
step
,
size
,
seed_point
,
((
cv
::
Vec3b
*
)
nv_buf
)[
0
],
Diff8uC3
(
ld_buf
.
b
,
ud_buf
.
b
),
comp
,
flags
,
buffer
,
buffer_size
);
else
if
(
type
==
CV_32SC1
)
icvFloodFillGrad_CnIR
<
int
,
int
,
Diff32sC1
>
(
img
->
data
.
ptr
,
img
->
step
,
mask
->
data
.
ptr
,
mask
->
step
,
size
,
seed_point
,
((
int
*
)
nv_buf
)[
0
],
Diff32sC1
(
ld_buf
.
i
[
0
],
ud_buf
.
i
[
0
]),
comp
,
flags
,
buffer
,
buffer_size
);
else
if
(
type
==
CV_32SC3
)
icvFloodFillGrad_CnIR
<
cv
::
Vec3i
,
cv
::
Vec3i
,
Diff32sC3
>
(
img
->
data
.
ptr
,
img
->
step
,
mask
->
data
.
ptr
,
mask
->
step
,
size
,
seed_point
,
((
cv
::
Vec3i
*
)
nv_buf
)[
0
],
Diff32sC3
(
ld_buf
.
i
,
ud_buf
.
i
),
comp
,
flags
,
buffer
,
buffer_size
);
else
if
(
type
==
CV_32FC1
)
icvFloodFillGrad_CnIR
<
float
,
float
,
Diff32fC1
>
(
img
->
data
.
ptr
,
img
->
step
,
mask
->
data
.
ptr
,
mask
->
step
,
size
,
seed_point
,
((
float
*
)
nv_buf
)[
0
],
Diff32fC1
(
ld_buf
.
f
[
0
],
ud_buf
.
f
[
0
]),
comp
,
flags
,
buffer
,
buffer_size
);
else
if
(
type
==
CV_32FC3
)
icvFloodFillGrad_CnIR
<
cv
::
Vec3f
,
cv
::
Vec3f
,
Diff32fC3
>
(
img
->
data
.
ptr
,
img
->
step
,
mask
->
data
.
ptr
,
mask
->
step
,
size
,
seed_point
,
((
cv
::
Vec3f
*
)
nv_buf
)[
0
],
Diff32fC3
(
ld_buf
.
f
,
ud_buf
.
f
),
comp
,
flags
,
buffer
,
buffer_size
);
else
CV_Error
(
CV_StsUnsupportedFormat
,
""
);
}
}
...
...
modules/imgproc/test/test_floodfill.cpp
View file @
0b234b7a
...
@@ -97,8 +97,8 @@ void CV_FloodFillTest::get_test_array_types_and_sizes( int test_case_idx,
...
@@ -97,8 +97,8 @@ void CV_FloodFillTest::get_test_array_types_and_sizes( int test_case_idx,
double
buf
[
8
];
double
buf
[
8
];
cvtest
::
ArrayTest
::
get_test_array_types_and_sizes
(
test_case_idx
,
sizes
,
types
);
cvtest
::
ArrayTest
::
get_test_array_types_and_sizes
(
test_case_idx
,
sizes
,
types
);
depth
=
cvtest
::
randInt
(
rng
)
%
2
;
depth
=
cvtest
::
randInt
(
rng
)
%
3
;
depth
=
depth
==
0
?
CV_8U
:
CV_32F
;
depth
=
depth
==
0
?
CV_8U
:
depth
==
1
?
CV_32S
:
CV_32F
;
cn
=
cvtest
::
randInt
(
rng
)
&
1
?
3
:
1
;
cn
=
cvtest
::
randInt
(
rng
)
&
1
?
3
:
1
;
use_mask
=
(
cvtest
::
randInt
(
rng
)
&
1
)
!=
0
;
use_mask
=
(
cvtest
::
randInt
(
rng
)
&
1
)
!=
0
;
...
@@ -256,7 +256,7 @@ cvTsFloodFill( CvMat* _img, CvPoint seed_pt, CvScalar new_val,
...
@@ -256,7 +256,7 @@ cvTsFloodFill( CvMat* _img, CvPoint seed_pt, CvScalar new_val,
int
u0
=
0
,
u1
=
0
,
u2
=
0
;
int
u0
=
0
,
u1
=
0
,
u2
=
0
;
double
s0
=
0
,
s1
=
0
,
s2
=
0
;
double
s0
=
0
,
s1
=
0
,
s2
=
0
;
if
(
CV_MAT_DEPTH
(
_img
->
type
)
==
CV_8U
)
if
(
CV_MAT_DEPTH
(
_img
->
type
)
==
CV_8U
||
CV_MAT_DEPTH
(
_img
->
type
)
==
CV_32S
)
{
{
tmp
=
cvCreateMat
(
rows
,
cols
,
CV_MAKETYPE
(
CV_32F
,
CV_MAT_CN
(
_img
->
type
))
);
tmp
=
cvCreateMat
(
rows
,
cols
,
CV_MAKETYPE
(
CV_32F
,
CV_MAT_CN
(
_img
->
type
))
);
cvTsConvert
(
_img
,
tmp
);
cvTsConvert
(
_img
,
tmp
);
...
@@ -428,7 +428,6 @@ cvTsFloodFill( CvMat* _img, CvPoint seed_pt, CvScalar new_val,
...
@@ -428,7 +428,6 @@ cvTsFloodFill( CvMat* _img, CvPoint seed_pt, CvScalar new_val,
float
*
ptr
=
img
+
i
*
step
;
float
*
ptr
=
img
+
i
*
step
;
ushort
*
mptr
=
m
+
i
*
mstep
;
ushort
*
mptr
=
m
+
i
*
mstep
;
uchar
*
dmptr
=
_mask
?
_mask
->
data
.
ptr
+
(
i
+
1
)
*
_mask
->
step
+
1
:
0
;
uchar
*
dmptr
=
_mask
?
_mask
->
data
.
ptr
+
(
i
+
1
)
*
_mask
->
step
+
1
:
0
;
uchar
*
dptr
=
tmp
!=
_img
?
_img
->
data
.
ptr
+
i
*
_img
->
step
:
0
;
double
area0
=
area
;
double
area0
=
area
;
for
(
j
=
0
;
j
<
cols
;
j
++
)
for
(
j
=
0
;
j
<
cols
;
j
++
)
...
@@ -440,20 +439,7 @@ cvTsFloodFill( CvMat* _img, CvPoint seed_pt, CvScalar new_val,
...
@@ -440,20 +439,7 @@ cvTsFloodFill( CvMat* _img, CvPoint seed_pt, CvScalar new_val,
if
(
!
mask_only
)
if
(
!
mask_only
)
{
{
if
(
cn
==
1
)
if
(
cn
==
1
)
{
if
(
dptr
)
dptr
[
j
]
=
(
uchar
)
u0
;
else
ptr
[
j
]
=
(
float
)
s0
;
ptr
[
j
]
=
(
float
)
s0
;
}
else
{
if
(
dptr
)
{
dptr
[
j
*
3
]
=
(
uchar
)
u0
;
dptr
[
j
*
3
+
1
]
=
(
uchar
)
u1
;
dptr
[
j
*
3
+
2
]
=
(
uchar
)
u2
;
}
else
else
{
{
ptr
[
j
*
3
]
=
(
float
)
s0
;
ptr
[
j
*
3
]
=
(
float
)
s0
;
...
@@ -461,7 +447,6 @@ cvTsFloodFill( CvMat* _img, CvPoint seed_pt, CvScalar new_val,
...
@@ -461,7 +447,6 @@ cvTsFloodFill( CvMat* _img, CvPoint seed_pt, CvScalar new_val,
ptr
[
j
*
3
+
2
]
=
(
float
)
s2
;
ptr
[
j
*
3
+
2
]
=
(
float
)
s2
;
}
}
}
}
}
else
else
{
{
if
(
cn
==
1
)
if
(
cn
==
1
)
...
@@ -494,7 +479,11 @@ cvTsFloodFill( CvMat* _img, CvPoint seed_pt, CvScalar new_val,
...
@@ -494,7 +479,11 @@ cvTsFloodFill( CvMat* _img, CvPoint seed_pt, CvScalar new_val,
_exit_:
_exit_:
cvReleaseMat
(
&
mask
);
cvReleaseMat
(
&
mask
);
if
(
tmp
!=
_img
)
if
(
tmp
!=
_img
)
{
if
(
!
mask_only
)
cvTsConvert
(
tmp
,
_img
);
cvReleaseMat
(
&
tmp
);
cvReleaseMat
(
&
tmp
);
}
comp
[
0
]
=
area
;
comp
[
0
]
=
area
;
comp
[
1
]
=
r
.
x
;
comp
[
1
]
=
r
.
x
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment