文章目录
函数介绍C++ 代码示例Python 代码示例
函数介绍
输入必须是单通道图像,最好是二值图
int cv
::connectedComponents
(
cv
::InputArrayn image
,
cv
::OutputArray labels
,
int connectivity
= 8,
int ltype
= CV_32S
);
int cv
::connectedComponentsWithStats
(
cv
::InputArrayn image
,
cv
::OutputArray labels
,
cv
::OutputArray stats
,
cv
::OutputArray centroids
,
int connectivity
= 8,
int ltype
= CV_32S
);
C++ 代码示例
参数类型:
num
int
labels
= Mat w × h CV_32S
stats
= Mat num ×
5 CV_32S
centroids
= Mat num ×
2 CV64F
获取随机色
vector
<cv
::Vec3b
> getColors(int num
)
{
int step
= 256 / num
;
vector
<int> px
;
for (int i
= 0; i
< 256; i
+= step
)
px
.push_back(i
);
vector
<cv
::Vec3b
> colors(num
);
for (int j
= 0; j
< 3; j
++)
{
random_shuffle(px
.begin(), px
.end());
for (int i
= 0; i
< num
; i
++)
{
colors
[i
][j
] = px
[i
];
}
}
return colors
;
}
给各个连通域上色: 只需要用到标签矩阵 labels
cv
::Mat labels
, stats
, centroids
;
num
= cv
::connectedComponentsWithStats(img
, labels
, stats
, centroids
);
auto colors
= getColors(num
);
cv
:: Mat drawing
= cv
::Mat(img
.size(), CV_8UC3
, cv
::Scalar(255, 255, 255));
for (int i
= 0; i
< img
.size().height
; i
++) {
for (int j
= 0; j
< img
.size().width
; j
++) {
index
= labels
.at
<int>(i
, j
);
drawing
.at
<cv
::Vec3b
>(i
, j
) = colors
[index
];
}
}
过滤连通域,获取目标区域的标签: 只需要用到状态矩阵 stats (和质心坐标矩阵 centroids)
cv
::Mat labels
, stats
, centroids
;
num
= cv
::connectedComponentsWithStats(img
, labels
, stats
, centroids
);
int x0
, y0
, x1
, y1
, w
, h
;
std
::cout
<< "符合规则的区域label: "<< std
::endl
;
for(int k
= 0; k
< num
; k
++){
x0
= centroids
.at
<double>(k
, 0);
y0
= centroids
.at
<double>(k
, 1);
x1
= stats
.at
<int>(k
, 0);
y1
= stats
.at
<int>(k
, 1);
w
= stats
.at
<int>(k
, 2);
h
= stats
.at
<int>(k
, 3);
printf("Comp -: (=×=) from (=,=) 质心(=,=)\n", k
, w
, h
, x1
, y1
, x0
, y0
);
if(条件
1 or 条件
2 or ...) continue;
std
::cout
<< k
<< ", ";
}
std
::cout
<< std
::endl
;
Python 代码示例
获取随机色
def getColors(n
):
colors
= np
.zeros
((n
, 3))
colors
[:, 0] = np
.random
.permutation
(np
.linspace
(0, 256, n
))
colors
[:, 1] = np
.random
.permutation
(colors
[:, 0])
colors
[:, 2] = np
.random
.permutation
(colors
[:, 1])
return colors
给各个连通域上色: 只需要用到标签矩阵 labels
ccNum
, labels
, stats
, centroids
= cv
.connectedComponentsWithStats
(img
)
colors
= getColors
(ccNum
)
dst
= np
.ones
((img
.shape
[0], img
.shape
[1], 3), dtype
=np
.uint8
) * 255
for i
in range(ccNum
):
dst
[labels
== i
] = colors
[i
]
过滤连通域,获取目标区域的标签: 只需要用到状态矩阵 stats (和质心坐标矩阵 centroids)
ccNum
, labels
, stats
, centroids
= cv
.connectedComponentsWithStats
(img
)
colors
= getColors
(ccNum
)
print("符合规则的区域label: ")
for i
in range(ccNum
):
x1
, y1
, width
, height
, count
= stats
[i
]
x0
, y0
= centroids
[i
]
if 条件
1 or 条件
2 or ...:
continue
print("符合规则的区域label: ")
dst
[labels
== i
] = colors
[i
]; // 可以随手上色
参考文章: jsxyhelu: OpenCV中的新函数connectedComponentsWithStats使用