有三种常见的边界框:矩形、圆形、椭圆。
(1)矩形:在图像处理系统中提供了一种叫Rectangle的矩形,不过它只能表达边垂直或水平的特例;OpenCv中还有一种叫Box的矩形,它跟数学上的矩形一致,只要4个角是直角即可。
如果要获取轮廓的Rectangle,可以使用Contour<Point>.BoundingRectangle属性或者 cvBoundingRect函数。
如果要获取轮廓的Box,可以使用Contour<Point>.GetMinAreaRect方法或者cvMinAreaRect2函数。
(2)圆形
如果要获取轮廓的圆形边界框,可以使用cvMinEnclosingCircle函数。
(3)椭圆
如果要获取轮廓的椭圆边界框,可以使用cvFitEllipse2函数。
下列代码演示了如何获取轮廓的各种边界框:
- //得到边界框信息
- private void GetEdgeInfo(Contour<Point> contour, string edge, ref StringBuilder sbContour, ref Image<Bgr, Byte> imageResult, Bgr edgeColor)
- {
- if (edge == "Rect")
- //矩形
- imageResult.Draw(contour.BoundingRectangle, edgeColor, 2);
- else if (edge == "MinAreaRect")
- {
- //最小矩形
- MCvBox2D box = CvInvoke.cvMinAreaRect2(contour.Ptr, IntPtr.Zero);
- PointF[] points = box.GetVertices();
- Point[] ps = new Point[points.Length];
- for (int i = 0; i < points.Length; i++)
- ps = new Point((int)points.X, (int)points.Y);
- imageResult.DrawPolyline(ps, true, edgeColor, 2);
- }
- else if (edge == "Circle")
- {
- //圆形
- PointF center;
- float radius;
- CvInvoke.cvMinEnclosingCircle(contour.Ptr, out center, out radius);
- imageResult.Draw(new CircleF(center, radius), edgeColor, 2);
- }
- else
- {
- //椭圆
- if (contour.Total >= 6)
- {
- MCvBox2D box = CvInvoke.cvFitEllipse2(contour.Ptr);
- imageResult.Draw(new Ellipse(box), edgeColor, 2);
- }
- else
- sbContour.Append("轮廓点数小于6,不能创建外围椭圆。/r/n");
- }
- }
我们可以使用Contour<Point>.GetMoments方法或者cvMoments函数方便的得到轮廓的矩集,然后再相应的方法或函数获取各种矩。
特定的矩:MCvMoments.GetSpatialMoment方法、cvGetSpatialMoment函数
中心矩:MCvMoments.GetCentralMoment方法、cvGetCentralMoment函数
归一化中心矩:MCvMoments.GetNormalizedCentralMoment方法、 cvGetNormalizedCentralMoment函数
Hu矩:MCvMoments.GetHuMoment方法、McvHuMoments.hu1~hu7字段、cvGetHuMoments函数
以下代码演示了如何获取轮廓的矩:
- //得到各种矩的信息
- private void GetMomentsInfo(Contour<Point> contour, ref StringBuilder sbContour)
- {
- //矩
- MCvMoments moments = contour.GetMoments();
- //遍历各种情况下的矩、中心矩及归一化矩,必须满足条件:xOrder>=0; yOrder>=0; xOrder+yOrder<=3;
- for (int xOrder = 0; xOrder <= 3; xOrder++)
- {
- for (int yOrder = 0; yOrder <= 3; yOrder++)
- {
- if (xOrder + yOrder <= 3)
- {
- double spatialMoment = moments.GetSpatialMoment(xOrder, yOrder);
- double centralMoment = moments.GetCentralMoment(xOrder, yOrder);
- double normalizedCentralMoment = moments.GetNormalizedCentralMoment(xOrder, yOrder);
- sbContour.AppendFormat("矩(xOrder:{0},yOrder:{1}),矩:{2:F09},中心矩:{3:F09},归一化矩:{4:F09}/r/n", xOrder, yOrder, spatialMoment, centralMoment, normalizedCentralMoment);
- }
- }
- }
- //Hu矩
- MCvHuMoments huMonents = moments.GetHuMoment();
- sbContour.AppendFormat("Hu矩 h1:{0:F09},h2:{1:F09},h3:{2:F09},h4:{3:F09},h5:{4:F09},h6:{5:F09},h7:{6:F09}/r/n", huMonents.hu1, huMonents.hu2, huMonents.hu3, huMonents.hu4, huMonents.hu5, huMonents.hu6, huMonents.hu7);
- }