C# 查找矩形时忽略外部点
我有一些像这样的图像,我需要找到中心矩形 我使用EmguCV示例的一个变体来查找矩形,并附带了此示例C# 查找矩形时忽略外部点,c#,opencv,computer-vision,emgucv,C#,Opencv,Computer Vision,Emgucv,我有一些像这样的图像,我需要找到中心矩形 我使用EmguCV示例的一个变体来查找矩形,并附带了此示例 using (MemStorage storage = new MemStorage()) { //allocate storage for contour approximation //Contour<Point> contours = gray.FindContours() Contour<Point> contours = gray.FindC
using (MemStorage storage = new MemStorage())
{ //allocate storage for contour approximation
//Contour<Point> contours = gray.FindContours()
Contour<Point> contours = gray.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE,
Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST,
storage);
for (; contours != null; contours = contours.HNext)
{
Contour<Point> currentContour = contours.ApproxPoly(contours.Perimeter * 0.05, storage);
//Seq<Point> currentContour = contours.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);
if (contours.Area > MinRectangleArea) //only consider contours with area greater than 20000
{
if (currentContour.Total == 4) //The contour has 4 vertices.
{
bool isRectangle = true;
Point[] pts = currentContour.ToArray();
LineSegment2D[] edges = PointCollection.PolyLine(pts, true);
for (int i = 0; i < edges.Length; i++)
{
double angle = Math.Abs(edges[(i + 1) % edges.Length].GetExteriorAngleDegree(edges[i]));
if (angle < 90 - RectangleAngleMargin || angle > RectangleAngleMargin + 90)
{
isRectangle = false;
break;
}
}
if (isRectangle)
{
boxList.Add(currentContour.GetMinAreaRect());
}
}
}
}
使用(MemStorage=newmemstorage())
{//为轮廓近似分配存储空间
//等高线=灰色。FindContours()
等高线=灰色。FindContours(Emgu.CV.CvEnum.CHAIN_近似法。CV_CHAIN_近似法),
Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST,
储存);
对于(;轮廓!=null;轮廓=轮廓.HNext)
{
轮廓电流轮廓=轮廓.近似多边形(轮廓.周长*0.05,存储);
//Seq currentContour=等高线.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_顺时针);
如果(Couth.Stand>MinRectangleArea)/只考虑大于20000的区域的等高线
{
如果(currentContour.Total==4)//轮廓有4个顶点。
{
布尔isRectangle=真;
点[]pts=currentContour.ToArray();
LineSegment2D[]边=点集合.多段线(pts,true);
对于(int i=0;i矩形边距+90)
{
isRectangle=false;
打破
}
}
如果(isRectangle)
{
Add(currentContour.getMinareact());
}
}
}
}
}
在这些图像上执行的结果有时会发现这两个矩形:
橙色的长方形可以,这就是我需要的。但是我不要蓝色的。有时四个顶点位于图像的边界内,通常其中一个在外
将FindContours函数的RETR_类型更改为CV_RETR_EXTERNAL,我只得到了蓝色矩形,因此我想知道是否有一个不获取带有外部点的轮廓的选项
真实的图像实际上可以在橙色内有更小的矩形(或者一条线将矩形分割),因此在这之后,我选择了更大的矩形作为我想要的矩形,但不能用蓝色的矩形来实现。查看示例图像,我会选择另一种方法 与传统的轮廓检测不同,如果执行Hough线检测,然后形成找到的线的交点,您将准确地找到正在搜索的矩形的四个顶点
如果您在编码方面需要帮助,请告诉我,我将编辑我的答案。谢谢您的回答。输入图像实际上是霍夫线检测的结果。实际图像的矩形内可能有一些“嘈杂”的线条(例如:)。有这么多线,我需要做一系列的检查,检查交点和点的位置,最终得到一个有点容易出错的代码。此时,我正在使用CV_RETR_EXTERNAL和CV_RETR_SIMPLE方法搜索轮廓,并从另一组中删除外部轮廓,但我认为解决方案更好您的场景现在更清晰了。如果您使用CV_RETR_EXTERNAL,它会给出“外部”轮廓,因此您的蓝色轮廓(包围橙色)将是您得到的轮廓。如果您想更好地了解轮廓在opencv中的组织方式,这里有一个有用的链接:好的,我误解了该参数的含义,我现在知道了。在我的例子中,findContentours函数似乎不是最好的选择,但仍然不知道为什么它会找到蓝色矩形。无论如何,我会通过手动检查交叉点来完成。