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
1eae455a
Commit
1eae455a
authored
Dec 15, 2012
by
Vadim Pisarevsky
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fixed build warnings from VS; hopefully, fixes Android build too
parent
2a42960f
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
57 additions
and
78 deletions
+57
-78
imgproc.hpp
modules/imgproc/include/opencv2/imgproc/imgproc.hpp
+11
-6
connectedcomponents.cpp
modules/imgproc/src/connectedcomponents.cpp
+46
-72
No files found.
modules/imgproc/include/opencv2/imgproc/imgproc.hpp
View file @
1eae455a
...
@@ -1104,12 +1104,17 @@ CV_EXPORTS_W void matchTemplate( InputArray image, InputArray templ,
...
@@ -1104,12 +1104,17 @@ CV_EXPORTS_W void matchTemplate( InputArray image, InputArray templ,
enum
{
CC_STAT_LEFT
=
0
,
CC_STAT_TOP
=
1
,
CC_STAT_WIDTH
=
2
,
CC_STAT_HEIGHT
=
3
,
CC_STAT_AREA
=
4
,
CC_STAT_MAX
=
5
};
enum
{
CC_STAT_LEFT
=
0
,
CC_STAT_TOP
=
1
,
CC_STAT_WIDTH
=
2
,
CC_STAT_HEIGHT
=
3
,
CC_STAT_AREA
=
4
,
CC_STAT_MAX
=
5
};
//! computes the connected components labeled image of boolean image I with 4 or 8 way connectivity - returns N, the total
// computes the connected components labeled image of boolean image I
//number of labels [0, N-1] where 0 represents the background label. L's value type determines the label type, an important
// with 4 or 8 way connectivity - returns N, the total
//consideration based on the total number of labels or alternatively the total number of pixels.
// number of labels [0, N-1] where 0 represents the background label.
CV_EXPORTS_W
int
connectedComponents
(
InputArray
image
,
OutputArray
labels
,
int
connectivity
=
8
,
int
ltype
=
CV_32S
);
// L's value type determines the label type, an important
CV_EXPORTS_W
int
connectedComponentsWithStats
(
InputArray
image
,
OutputArray
labels
,
OutputArray
stats
,
OutputArray
centroids
,
int
connectivity
=
8
,
int
ltype
=
CV_32S
);
// consideration based on the total number of labels or
// alternatively the total number of pixels.
CV_EXPORTS_W
int
connectedComponents
(
InputArray
image
,
OutputArray
labels
,
int
connectivity
=
8
,
int
ltype
=
CV_32S
);
CV_EXPORTS_W
int
connectedComponentsWithStats
(
InputArray
image
,
OutputArray
labels
,
OutputArray
stats
,
OutputArray
centroids
,
int
connectivity
=
8
,
int
ltype
=
CV_32S
);
//! mode of the contour retrieval algorithm
//! mode of the contour retrieval algorithm
enum
enum
...
...
modules/imgproc/src/connectedcomponents.cpp
View file @
1eae455a
...
@@ -43,22 +43,16 @@
...
@@ -43,22 +43,16 @@
#include "precomp.hpp"
#include "precomp.hpp"
#include <vector>
#include <vector>
#if defined _MSC_VER
#pragma warning(disable: 4127)
#endif
namespace
cv
{
namespace
cv
{
namespace
connectedcomponents
{
namespace
connectedcomponents
{
template
<
typename
LabelT
>
struct
NoOp
{
struct
NoOp
{
NoOp
(){
NoOp
(){
}
}
void
init
(
const
LabelT
labels
){
void
init
(
int
/*labels*/
){
(
void
)
labels
;
}
}
inline
inline
void
operator
()(
int
r
,
int
c
,
LabelT
l
){
void
operator
()(
int
r
,
int
c
,
int
l
){
(
void
)
r
;
(
void
)
r
;
(
void
)
c
;
(
void
)
c
;
(
void
)
l
;
(
void
)
l
;
...
@@ -69,38 +63,35 @@ namespace cv{
...
@@ -69,38 +63,35 @@ namespace cv{
uint64
x
,
y
;
uint64
x
,
y
;
Point2ui64
(
uint64
_x
,
uint64
_y
)
:
x
(
_x
),
y
(
_y
){}
Point2ui64
(
uint64
_x
,
uint64
_y
)
:
x
(
_x
),
y
(
_y
){}
};
};
template
<
typename
LabelT
>
struct
CCStatsOp
{
struct
CCStatsOp
{
OutputArray
_mstatsv
;
const
_OutputArray
*
_mstatsv
;
cv
::
Mat
statsv
;
cv
::
Mat
statsv
;
OutputArray
_mcentroidsv
;
const
_OutputArray
*
_mcentroidsv
;
cv
::
Mat
centroidsv
;
cv
::
Mat
centroidsv
;
std
::
vector
<
Point2ui64
>
integrals
;
std
::
vector
<
Point2ui64
>
integrals
;
CCStatsOp
(
OutputArray
_statsv
,
OutputArray
_centroidsv
)
:
_mstatsv
(
_statsv
),
_mcentroidsv
(
_centroidsv
){
CCStatsOp
(
OutputArray
_statsv
,
OutputArray
_centroidsv
)
:
_mstatsv
(
&
_statsv
),
_mcentroidsv
(
&
_centroidsv
){
}
}
inline
inline
void
init
(
const
LabelT
nlabels
){
void
init
(
int
nlabels
){
_mstatsv
.
create
(
cv
::
Size
(
nlabels
,
CC_STAT_MAX
),
cv
::
DataType
<
int
>::
type
);
_mstatsv
->
create
(
cv
::
Size
(
nlabels
,
CC_STAT_MAX
),
cv
::
DataType
<
int
>::
type
);
statsv
=
_mstatsv
.
getMat
();
statsv
=
_mstatsv
->
getMat
();
_mcentroidsv
.
create
(
cv
::
Size
(
nlabels
,
2
),
cv
::
DataType
<
double
>::
type
);
_mcentroidsv
->
create
(
cv
::
Size
(
nlabels
,
2
),
cv
::
DataType
<
double
>::
type
);
centroidsv
=
_mcentroidsv
.
getMat
();
centroidsv
=
_mcentroidsv
->
getMat
();
for
(
int
l
=
0
;
l
<
(
int
)
nlabels
;
++
l
){
for
(
int
l
=
0
;
l
<
(
int
)
nlabels
;
++
l
){
unsigned
int
*
row
=
(
unsigned
int
*
)
&
statsv
.
at
<
int
>
(
l
,
0
);
int
*
row
=
(
int
*
)
&
statsv
.
at
<
int
>
(
l
,
0
);
row
[
CC_STAT_LEFT
]
=
std
::
numeric_limits
<
LabelT
>::
max
();
row
[
CC_STAT_LEFT
]
=
INT_MAX
;
row
[
CC_STAT_TOP
]
=
std
::
numeric_limits
<
LabelT
>::
max
();
row
[
CC_STAT_TOP
]
=
INT_MAX
;
row
[
CC_STAT_WIDTH
]
=
std
::
numeric_limits
<
LabelT
>::
min
();
row
[
CC_STAT_WIDTH
]
=
INT_MIN
;
row
[
CC_STAT_HEIGHT
]
=
std
::
numeric_limits
<
LabelT
>::
min
();
row
[
CC_STAT_HEIGHT
]
=
INT_MIN
;
//row[CC_STAT_CX] = 0;
//row[CC_STAT_CY] = 0;
row
[
CC_STAT_AREA
]
=
0
;
row
[
CC_STAT_AREA
]
=
0
;
}
}
integrals
.
resize
(
nlabels
,
Point2ui64
(
0
,
0
));
integrals
.
resize
(
nlabels
,
Point2ui64
(
0
,
0
));
}
}
void
operator
()(
int
r
,
int
c
,
LabelT
l
){
void
operator
()(
int
r
,
int
c
,
int
l
){
int
*
row
=
&
statsv
.
at
<
int
>
(
l
,
0
);
int
*
row
=
&
statsv
.
at
<
int
>
(
l
,
0
);
unsigned
int
*
urow
=
(
unsigned
int
*
)
row
;
if
(
c
>
row
[
CC_STAT_WIDTH
]){
if
(
c
>
row
[
CC_STAT_WIDTH
]){
row
[
CC_STAT_WIDTH
]
=
c
;
row
[
CC_STAT_WIDTH
]
=
c
;
}
else
{
}
else
{
...
@@ -115,14 +106,14 @@ namespace cv{
...
@@ -115,14 +106,14 @@ namespace cv{
row
[
CC_STAT_TOP
]
=
r
;
row
[
CC_STAT_TOP
]
=
r
;
}
}
}
}
u
row
[
CC_STAT_AREA
]
++
;
row
[
CC_STAT_AREA
]
++
;
Point2ui64
&
integral
=
integrals
[
l
];
Point2ui64
&
integral
=
integrals
[
l
];
integral
.
x
+=
c
;
integral
.
x
+=
c
;
integral
.
y
+=
r
;
integral
.
y
+=
r
;
}
}
void
finish
(){
void
finish
(){
for
(
int
l
=
0
;
l
<
statsv
.
rows
;
++
l
){
for
(
int
l
=
0
;
l
<
statsv
.
rows
;
++
l
){
unsigned
int
*
row
=
(
unsigned
int
*
)
&
statsv
.
at
<
int
>
(
l
,
0
);
int
*
row
=
&
statsv
.
at
<
int
>
(
l
,
0
);
row
[
CC_STAT_LEFT
]
=
std
::
min
(
row
[
CC_STAT_LEFT
],
row
[
CC_STAT_WIDTH
]);
row
[
CC_STAT_LEFT
]
=
std
::
min
(
row
[
CC_STAT_LEFT
],
row
[
CC_STAT_WIDTH
]);
row
[
CC_STAT_WIDTH
]
=
row
[
CC_STAT_WIDTH
]
-
row
[
CC_STAT_LEFT
]
+
1
;
row
[
CC_STAT_WIDTH
]
=
row
[
CC_STAT_WIDTH
]
-
row
[
CC_STAT_LEFT
]
+
1
;
row
[
CC_STAT_TOP
]
=
std
::
min
(
row
[
CC_STAT_TOP
],
row
[
CC_STAT_HEIGHT
]);
row
[
CC_STAT_TOP
]
=
std
::
min
(
row
[
CC_STAT_TOP
],
row
[
CC_STAT_HEIGHT
]);
...
@@ -130,8 +121,9 @@ namespace cv{
...
@@ -130,8 +121,9 @@ namespace cv{
Point2ui64
&
integral
=
integrals
[
l
];
Point2ui64
&
integral
=
integrals
[
l
];
double
*
centroid
=
&
centroidsv
.
at
<
double
>
(
l
,
0
);
double
*
centroid
=
&
centroidsv
.
at
<
double
>
(
l
,
0
);
centroid
[
0
]
=
double
(
integral
.
x
)
/
row
[
CC_STAT_AREA
];
double
area
=
((
unsigned
*
)
row
)[
CC_STAT_AREA
];
centroid
[
1
]
=
double
(
integral
.
y
)
/
row
[
CC_STAT_AREA
];
centroid
[
0
]
=
double
(
integral
.
x
)
/
area
;
centroid
[
1
]
=
double
(
integral
.
y
)
/
area
;
}
}
}
}
};
};
...
@@ -207,11 +199,12 @@ namespace cv{
...
@@ -207,11 +199,12 @@ namespace cv{
const
int
G4
[
2
][
2
]
=
{{
1
,
0
},
{
0
,
-
1
}};
//b, d neighborhoods
const
int
G4
[
2
][
2
]
=
{{
1
,
0
},
{
0
,
-
1
}};
//b, d neighborhoods
//reference for 8-way: {{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}};//a, b, c, d neighborhoods
//reference for 8-way: {{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}};//a, b, c, d neighborhoods
const
int
G8
[
4
][
2
]
=
{{
1
,
-
1
},
{
1
,
0
},
{
1
,
1
},
{
0
,
-
1
}};
//a, b, c, d neighborhoods
const
int
G8
[
4
][
2
]
=
{{
1
,
-
1
},
{
1
,
0
},
{
1
,
1
},
{
0
,
-
1
}};
//a, b, c, d neighborhoods
template
<
typename
LabelT
,
typename
PixelT
,
typename
StatsOp
=
NoOp
<
LabelT
>
,
int
connectivity
=
8
>
template
<
typename
LabelT
,
typename
PixelT
,
typename
StatsOp
=
NoOp
>
struct
LabelingImpl
{
struct
LabelingImpl
{
LabelT
operator
()(
const
cv
::
Mat
&
I
,
cv
::
Mat
&
L
,
StatsOp
&
sop
){
LabelT
operator
()(
const
cv
::
Mat
&
I
,
cv
::
Mat
&
L
,
int
connectivity
,
StatsOp
&
sop
){
CV_Assert
(
L
.
rows
==
I
.
rows
);
CV_Assert
(
L
.
rows
==
I
.
rows
);
CV_Assert
(
L
.
cols
==
I
.
cols
);
CV_Assert
(
L
.
cols
==
I
.
cols
);
CV_Assert
(
connectivity
==
8
||
connectivity
==
4
);
const
int
rows
=
L
.
rows
;
const
int
rows
=
L
.
rows
;
const
int
cols
=
L
.
cols
;
const
int
cols
=
L
.
cols
;
size_t
Plength
=
(
size_t
(
rows
+
3
-
1
)
/
3
)
*
(
size_t
(
cols
+
3
-
1
)
/
3
);
size_t
Plength
=
(
size_t
(
rows
+
3
-
1
)
/
3
)
*
(
size_t
(
cols
+
3
-
1
)
/
3
);
...
@@ -295,7 +288,6 @@ namespace cv{
...
@@ -295,7 +288,6 @@ namespace cv{
}
}
}
else
{
}
else
{
//B & D only
//B & D only
assert
(
connectivity
==
4
);
const
int
b
=
0
;
const
int
b
=
0
;
const
int
d
=
1
;
const
int
d
=
1
;
const
bool
T_b_r
=
(
r_i
-
G4
[
b
][
0
])
>=
0
;
const
bool
T_b_r
=
(
r_i
-
G4
[
b
][
0
])
>=
0
;
...
@@ -368,70 +360,52 @@ int connectedComponents_sub1(const cv::Mat &I, cv::Mat &L, int connectivity, Sta
...
@@ -368,70 +360,52 @@ int connectedComponents_sub1(const cv::Mat &I, cv::Mat &L, int connectivity, Sta
using
connectedcomponents
::
LabelingImpl
;
using
connectedcomponents
::
LabelingImpl
;
//warn if L's depth is not sufficient?
//warn if L's depth is not sufficient?
CV_Assert
(
iDepth
==
CV_8U
||
iDepth
==
CV_8S
);
if
(
lDepth
==
CV_8U
){
if
(
lDepth
==
CV_8U
){
if
(
iDepth
==
CV_8U
||
iDepth
==
CV_8S
){
return
(
int
)
LabelingImpl
<
uchar
,
uchar
,
StatsOp
>
()(
I
,
L
,
connectivity
,
sop
);
if
(
connectivity
==
4
){
return
(
int
)
LabelingImpl
<
uchar
,
uchar
,
StatsOp
,
4
>
()(
I
,
L
,
sop
);
}
else
{
return
(
int
)
LabelingImpl
<
uchar
,
uchar
,
StatsOp
,
8
>
()(
I
,
L
,
sop
);
}
}
else
{
CV_Assert
(
false
);
}
}
else
if
(
lDepth
==
CV_16U
){
}
else
if
(
lDepth
==
CV_16U
){
if
(
iDepth
==
CV_8U
||
iDepth
==
CV_8S
){
return
(
int
)
LabelingImpl
<
ushort
,
uchar
,
StatsOp
>
()(
I
,
L
,
connectivity
,
sop
);
if
(
connectivity
==
4
){
return
(
int
)
LabelingImpl
<
ushort
,
uchar
,
StatsOp
,
4
>
()(
I
,
L
,
sop
);
}
else
{
return
(
int
)
LabelingImpl
<
ushort
,
uchar
,
StatsOp
,
8
>
()(
I
,
L
,
sop
);
}
}
else
{
CV_Assert
(
false
);
}
}
else
if
(
lDepth
==
CV_32S
){
}
else
if
(
lDepth
==
CV_32S
){
//note that signed types don't really make sense here and not being able to use unsigned matters for scientific projects
//note that signed types don't really make sense here and not being able to use unsigned matters for scientific projects
//OpenCV: how should we proceed? .at<T> typechecks in debug mode
//OpenCV: how should we proceed? .at<T> typechecks in debug mode
if
(
iDepth
==
CV_8U
||
iDepth
==
CV_8S
){
return
(
int
)
LabelingImpl
<
int
,
uchar
,
StatsOp
>
()(
I
,
L
,
connectivity
,
sop
);
if
(
connectivity
==
4
){
return
(
int
)
LabelingImpl
<
int
,
uchar
,
StatsOp
,
4
>
()(
I
,
L
,
sop
);
}
else
{
return
(
int
)
LabelingImpl
<
int
,
uchar
,
StatsOp
,
8
>
()(
I
,
L
,
sop
);
}
}
else
{
CV_Assert
(
false
);
}
}
}
CV_Error
(
CV_StsUnsupportedFormat
,
"unsupported label/image type"
);
CV_Error
(
CV_StsUnsupportedFormat
,
"unsupported label/image type"
);
return
-
1
;
return
-
1
;
}
}
int
connectedComponents
(
InputArray
_I
,
OutputArray
_L
,
int
connectivity
,
int
ltype
){
}
int
cv
::
connectedComponents
(
InputArray
_I
,
OutputArray
_L
,
int
connectivity
,
int
ltype
){
const
cv
::
Mat
I
=
_I
.
getMat
();
const
cv
::
Mat
I
=
_I
.
getMat
();
_L
.
create
(
I
.
size
(),
CV_MAT_
TYPE
(
ltype
));
_L
.
create
(
I
.
size
(),
CV_MAT_
DEPTH
(
ltype
));
cv
::
Mat
L
=
_L
.
getMat
();
cv
::
Mat
L
=
_L
.
getMat
();
connectedcomponents
::
NoOp
sop
;
if
(
ltype
==
CV_16U
){
if
(
ltype
==
CV_16U
){
connectedcomponents
::
NoOp
<
ushort
>
sop
;
return
connectedComponents_sub1
(
I
,
L
,
connectivity
,
sop
);
return
connectedComponents_sub1
(
I
,
L
,
connectivity
,
sop
);
}
else
if
(
ltype
==
CV_32S
){
}
else
if
(
ltype
==
CV_32S
){
connectedcomponents
::
NoOp
<
unsigned
>
sop
;
return
connectedComponents_sub1
(
I
,
L
,
connectivity
,
sop
);
return
connectedComponents_sub1
(
I
,
L
,
connectivity
,
sop
);
}
else
{
}
else
{
CV_
Assert
(
false
);
CV_
Error
(
CV_StsUnsupportedFormat
,
"the type of labels must be 16u or 32s"
);
return
0
;
return
0
;
}
}
}
}
int
connectedComponentsWithStats
(
InputArray
_I
,
OutputArray
_L
,
OutputArray
statsv
,
OutputArray
centroids
,
int
connectivity
,
int
ltype
){
int
cv
::
connectedComponentsWithStats
(
InputArray
_I
,
OutputArray
_L
,
OutputArray
statsv
,
OutputArray
centroids
,
int
connectivity
,
int
ltype
)
{
const
cv
::
Mat
I
=
_I
.
getMat
();
const
cv
::
Mat
I
=
_I
.
getMat
();
_L
.
create
(
I
.
size
(),
CV_MAT_
TYPE
(
ltype
));
_L
.
create
(
I
.
size
(),
CV_MAT_
DEPTH
(
ltype
));
cv
::
Mat
L
=
_L
.
getMat
();
cv
::
Mat
L
=
_L
.
getMat
();
connectedcomponents
::
CCStatsOp
sop
(
statsv
,
centroids
);
if
(
ltype
==
CV_16U
){
if
(
ltype
==
CV_16U
){
connectedcomponents
::
CCStatsOp
<
ushort
>
sop
(
statsv
,
centroids
);
return
connectedComponents_sub1
(
I
,
L
,
connectivity
,
sop
);
return
connectedComponents_sub1
(
I
,
L
,
connectivity
,
sop
);
}
else
if
(
ltype
==
CV_32S
){
}
else
if
(
ltype
==
CV_32S
){
connectedcomponents
::
CCStatsOp
<
unsigned
>
sop
(
statsv
,
centroids
);
return
connectedComponents_sub1
(
I
,
L
,
connectivity
,
sop
);
return
connectedComponents_sub1
(
I
,
L
,
connectivity
,
sop
);
}
else
{
}
else
{
CV_
Assert
(
false
);
CV_
Error
(
CV_StsUnsupportedFormat
,
"the type of labels must be 16u or 32s"
);
return
0
;
return
0
;
}
}
}
}
}
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