带有统计信息的API:
int cv::connectedComponentsWithStats(
InputArray image, // 输入二值图像
OutputArray labels, // 输出的标记图像,背景index=0
OutputArray stats, // 统计信息,包括每个组件的位置、宽、高与面积
OutputArray centroids, // 每个组件的中心位置坐标cx, cy
int connectivity, // 连通域,默认是8连通
int ltype, // 输出的labels类型,默认是CV_32S
int ccltype // 连通组件算法
)
其中stats包括以下类型数据信息:
0 组件的左上角点像素点坐标的X位置
1 组件的左上角点像素点坐标的Y位置
2 组件外接矩形的宽度
3 组件外接矩形的高度
4 当前连通组件的面积(像素单位)
private void creat_rect()
{
Mat source = new Mat(@file_openImg[0], ImreadModes.Grayscale); //读入模式,灰度图
Mat labels = new Mat(); //像素点信息
Mat xywh = new Mat(); //minx,miny,width,heigth
Mat c_xy = new Mat(); //中心点坐标 x,y
//int num_labels = Cv2.ConnectedComponents(source, labels, PixelConnectivity.Connectivity4);
int num_labels = Cv2.ConnectedComponentsWithStats(source, labels, xywh, c_xy); //返回连通区域数量+1(其中1是背景图尺寸)
for (int i = 0; i < num_labels; i++)
{
box_site[i, 0] = xywh.At<int>(i, 0);
box_site[i, 1] = xywh.At<int>(i, 1);
box_site[i, 2] = xywh.At<int>(i, 2);
box_site[i, 3] = xywh.At<int>(i, 3);
if (box_site[i, 0] == 0) continue; //box_site[0,...] 为背景图大小。
Cv2.Rectangle(source, new OpenCvSharp.Point(box_site[i, 0], box_site[i, 1]), new OpenCvSharp.Point(box_site[i, 0] + box_site[i, 2], box_site[i, 1] + box_site[i, 3]), Scalar.White, 1); //box_site中存放框的数据(全局变量)
}
Cv2.ImShow("biaoji", source);
Cv2.WaitKey(0);
source.Dispose();
labels.Dispose();
xywh.Dispose();
c_xy.Dispose();
}
将 box_site 中的坐标值画出来,结果如上图所示。显示差异是因为 opencv 和 win 的大小差异。
不带统计信息的API:
int cv::connectedComponents(
InputArray image, // 输入二值图像
OutputArray labels, // 输出的标记图像,背景index=0
int connectivity = 8, // 连通域,默认是8连通
int ltype = CV_32S // 输出的labels类型,默认是CV_32S
)
private void button1_Click(object sender, EventArgs e)
{
Mat source = new Mat(@file_openImg[0], ImreadModes.Grayscale); //读入模式,灰度图
Mat labels = new Mat();
Mat xywh = new Mat();
Mat c_xy = new Mat();
int num_labels = Cv2.ConnectedComponents(source, labels, PixelConnectivity.Connectivity4);
Cv2.ImWrite(@file_openImg[0], source);
OpenCvSharp.Point[][] contours;
HierarchyIndex[] hierarchly;
Cv2.FindContours(source, out contours, out hierarchly, RetrievalModes.Tree, ContourApproximationModes.ApproxSimple, new OpenCvSharp.Point(0, 0));
//将结果画出并返回结果
Mat dst_Image = Mat.Zeros(source.Size(), source.Type());
Random rnd = new Random();
for (int i = 0; i < contours.Length; i++)
{
Scalar color = new Scalar(255, 255, 255);//白色
//Cv2.DrawContours(dst_Image, contours, i, color, 1, LineTypes.Link8, hierarchly);
}
//查找指定
Point2f pt = new Point2f(1, 40);
var ret = Cv2.PointPolygonTest(contours[0], pt, false);
RotatedRect rect = Cv2.MinAreaRect(contours[0]);
Point2f[] P = rect.Points();
for (int j = 0; j <= 3; j++)
{
Cv2.Line(dst_Image, (OpenCvSharp.Point)P[j], (OpenCvSharp.Point)P[(j + 1) % 4], new Scalar(255, 0, 0), 1);
}
Cv2.ImShow("dst_Image:", dst_Image);
Cv2.WaitKey(0);
}
结果如上图所示,贴合白色区域的最小矩形。显示差异是因为opencv和win的大小差异。