各位用户为了找寻关于浅谈OpenCV中的新函数connectedComponentsWithStats用法的资料费劲了很多周折。这里教程网为您整理了关于浅谈OpenCV中的新函数connectedComponentsWithStats用法的相关资料,仅供查阅,以下为您介绍关于浅谈OpenCV中的新函数connectedComponentsWithStats用法的详细内容
主要内容:对比新旧函数,用于过滤原始图像中轮廓分析后较小的区域,留下较大区域。
关键字:connectedComponentsWithStats
在以前,常用的方法是”是先调用 cv::findContours() 函数(传入cv::RETR_CCOMP 标志),随后在得到的连通区域上循环调用 cv::drawContours() “
比如,我在GOCVHelper中这样进行了实现
? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33/
/
寻找最大的轮廓
VP FindBigestContour(Mat src){
int
imax
=
0
;
/
/
代表最大轮廓的序号
int
imaxcontour
=
-
1
;
/
/
代表最大轮廓的大小
std::vector<std::vector<Point>>contours;
findContours(src,contours,CV_RETR_LIST,CV_CHAIN_APPROX_SIMPLE);
for
(
int
i
=
0
;i<contours.size();i
+
+
){
int
itmp
=
contourArea(contours[i]);
/
/
这里采用的是轮廓大小
if
(imaxcontour < itmp ){
imax
=
i;
imaxcontour
=
itmp;
}
}
return
contours[imax];
}
/
/
寻找并绘制出彩色联通区域
vector<VP> connection2(Mat src,Mat& draw){
draw
=
Mat::zeros(src.rows,src.cols,CV_8UC3);
vector<VP>contours;
findContours(src.clone(),contours,CV_RETR_LIST,CV_CHAIN_APPROX_SIMPLE);
/
/
由于给大的区域着色会覆盖小的区域,所以首先进行排序操作
/
/
冒泡排序,由小到大排序
VP vptmp;
for
(
int
i
=
1
;i<contours.size();i
+
+
){
for
(
int
j
=
contours.size()
-
1
;j>
=
i;j
-
-
){
if
(contourArea(contours[j]) < contourArea(contours[j
-
1
]))
{
vptmp
=
contours[j
-
1
];
contours[j
-
1
]
=
contours[j];
contours[j]
=
vptmp;
}
}
}
在OpenCV3中有了新的专门的函数 cv::connectedComponents() 和函数 cv::connectedComponentsWithStats()
定义:
? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18int
cv::connectedComponents (
cv::InputArrayn image,
/
/
input
8
-
bit single
-
channel (binary)
cv::OutputArray labels,
/
/
output label
map
int
connectivity
=
8
,
/
/
4
-
or
8
-
connected components
int
ltype
=
CV_32S
/
/
Output label
type
(CV_32S
or
CV_16U)
);
int
cv::connectedComponentsWithStats (
cv::InputArrayn image,
/
/
input
8
-
bit single
-
channel (binary)
cv::OutputArray labels,
/
/
output label
map
cv::OutputArray stats,
/
/
Nx5 matrix (CV_32S) of statistics:
/
/
[x0, y0, width0, height0, area0;
/
/
... ; x(N
-
1
), y(N
-
1
), width(N
-
1
),
/
/
height(N
-
1
), area(N
-
1
)]
cv::OutputArray centroids,
/
/
Nx2 CV_64F matrix of centroids:
/
/
[ cx0, cy0; ... ; cx(N
-
1
), cy(N
-
1
)]
int
connectivity
=
8
,
/
/
4
-
or
8
-
connected components
int
ltype
=
CV_32S
/
/
Output label
type
(CV_32S
or
CV_16U)
);
其中,新出现的参数
stats:长这样
分别对应各个轮廓的x,y,width,height和面积。注意0的区域标识的是background
而centroids则对应的是中心点
而label则对应于表示是当前像素是第几个轮廓
例子:
对于图像
Mat img
=
cv::imread(
"e:/sandbox/rect.png"
,
0
);
cv::Mat img_edge, labels, img_color, stats,centroids;
cv::threshold(img, img_edge,
128
,
255
, cv::THRESH_BINARY);
bitwise_not(img_edge,img_edge);
cv::imshow(
"Image after threshold"
, img_edge);
int
i, nccomps
=
cv::connectedComponentsWithStats (
img_edge, labels,
stats, centroids
);
cout <<
"Total Connected Components Detected: "
<< nccomps << endl;
vector<cv::Vec3b> colors(nccomps
+
1
);
colors[
0
]
=
Vec3b(
0
,
0
,
0
);
/
/
background pixels remain black.
for
( i
=
1
; i < nccomps; i
+
+
) {
colors[i]
=
Vec3b(rand()
%
256
, rand()
%
256
, rand()
%
256
);
if
( stats.at<
int
>(i, cv::CC_STAT_AREA) <
200
)
colors[i]
=
Vec3b(
0
,
0
,
0
);
/
/
small regions are painted with black too.
}
img_color
=
Mat::zeros(img.size(), CV_8UC3);
for
(
int
y
=
0
; y < img_color.rows; y
+
+
)
for
(
int
x
=
0
; x < img_color.cols; x
+
+
)
{
int
label
=
labels.at<
int
>(y, x);
CV_Assert(
0
<
=
label && label <
=
nccomps);
img_color.at<cv::Vec3b>(y, x)
=
colors[label];
}
cv::imshow(
"Labeled map"
, img_color);
cv::waitKey();
注意:
1、对于OpenCV来说,白色代表有数据,黑色代表没有数据,所以图像输入之前要转换成”黑底白图“
2、看labels 和 stats,其中第1 2 6 个的面积小于200
而labels中
完全对的上号,结果为
以上这篇浅谈OpenCV中的新函数connectedComponentsWithStats用法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持服务器之家。
原文链接:https://www.cnblogs.com/jsxyhelu/p/7439655.html