Emgu CV 绘制旋转矩形
Posted
技术标签:
【中文标题】Emgu CV 绘制旋转矩形【英文标题】:Emgu CV draw rotated rectangle 【发布时间】:2015-06-18 13:00:15 【问题描述】:我正在寻找几天在图像框架上绘制矩形的解决方案。基本上我使用CvInvoke.cvRectangle
方法在图像上绘制矩形,因为我需要抗锯齿矩形。
但问题是当我需要为给定角度旋转给定形状时。我找不到任何好的解决方案。
我试图在单独的框架上绘制矩形,然后旋转孔框架并将这个新图像应用到我的基础框架之上。但在这个解决方案中,抗锯齿存在问题。它不工作。
我正在开发一个简单的应用程序,它应该允许绘制几种形状,调整它们的大小并旋转给定的角度。
知道如何实现这一目标吗?
【问题讨论】:
【参考方案1】:我发现在轮廓上绘制最小封闭矩形的最佳方法是使用Polylines() 函数,该函数使用从MinAreaRect() 函数返回的顶点。当然还有其他方法可以做到这一点。下面是代码:
// Find contours
var contours = new Emgu.CV.Util.VectorOfVectorOfPoint();
Mat hierarchy = new Mat();
CvInvoke.FindContours(image, contours, hierarchy, RetrType.Tree, ChainApproxMethod.ChainApproxSimple);
// According to your metric, get an index of the contour you want to find the min enclosing rectangle for
int index = 2; // Say, 2nd index works for you.
var rectangle = CvInvoke.MinAreaRect(contours[index]);
Point[] vertices = Array.ConvertAll(rectangle.GetVertices(), Point.Round);
CvInvoke.Polylines(image, vertices, true, new MCvScalar(0, 0, 255), 5);
结果可以在下图中可视化,红色是最小的封闭矩形。
【讨论】:
【参考方案2】:我使用 C# 和 EMGU.CV(4.1),我认为这段代码移植到任何平台都不会困难。
在你的助手中添加函数:
public static Mat DrawRect(Mat input, RotatedRect rect, MCvScalar color = default(MCvScalar),
int thickness = 1, LineType lineType = LineType.EightConnected, int shift = 0)
var v = rect.GetVertices();
var prevPoint = v[0];
var firstPoint = prevPoint;
var nextPoint = prevPoint;
var lastPoint = nextPoint;
for (var i = 1; i < v.Length; i++)
nextPoint = v[i];
CvInvoke.Line(input, Point.Round(prevPoint), Point.Round(nextPoint), color, thickness, lineType, shift);
prevPoint = nextPoint;
lastPoint = prevPoint;
CvInvoke.Line(input, Point.Round(lastPoint), Point.Round(firstPoint), color, thickness, lineType, shift);
return input;
这会按点绘制旋转矩形。这里通过方法 Point.Round
使用舍入点,因为 RotatedRect
在浮点坐标中有点,CvInvoke.Line
将点作为整数。
用途:
var mat = Mat.Zeros(200, 200, DepthType.Cv8U, 3);
mat.GetValueRange();
var rRect = new RotatedRect(new PointF(100, 100), new SizeF(100, 50), 30);
DrawRect(mat, rRect,new MCvScalar(255,0,0));
var brect = CvInvoke.BoundingRectangle(new VectorOfPointF(rRect.GetVertices()));
CvInvoke.Rectangle(mat, brect, new MCvScalar(0,255,0), 1, LineType.EightConnected, 0);
结果:
【讨论】:
【参考方案3】:您应该阅读OpenCV documentation。
有一个RotatedRectangle
类可用于您的任务。您可以指定矩形旋转的角度。
这是一个用于绘制旋转矩形的示例代码(取自文档):
Mat image(200, 200, CV_8UC3, Scalar(0));
RotatedRect rRect = RotatedRect(Point2f(100,100), Size2f(100,50), 30);
Point2f vertices[4];
rRect.points(vertices);
for (int i = 0; i < 4; i++)
line(image, vertices[i], vertices[(i+1)%4], Scalar(0,255,0));
Rect brect = rRect.boundingRect();
rectangle(image, brect, Scalar(255,0,0));
imshow("rectangles", image);
waitKey(0);
结果如下:
【讨论】:
Point2f 不是 CvInvoke.Line() 的正确类型。因此答案是错误的。以上是关于Emgu CV 绘制旋转矩形的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 C# 中的 Emgu CV 库在图像上绘制矩形。举个例子
OpenCV-最小包围旋转矩形边框cv::minAreaRect