OpenCV FindContours 找不到正确的矩形

OpenCV FindContours does not find the correct rectangle

使用 CvInvoke.CannyCvInvoke.FindContours 我试图找到包含项目名称的矩形(示意图:枫木桌)。这个矩形如下图所示:

我能找到很多矩形,但我找不到这个。为 Canny 尝试了很多不同的阈值,但没有效果。下图显示了我目前得到的所有矩形:

有什么解决办法吗?我是否需要使用其他阈值或其他方法?我已经尝试过使用灰度和模糊,但并没有得到更好的结果。我在下面添加了我当前的来源,我使用的原始图像是这样的:

public Mat ProcessImage(Mat img)
{
 UMat filter = new UMat();
 UMat cannyEdges = new UMat();
 Mat rectangleImage = new Mat(img.Size, DepthType.Cv8U, 3);

 //Convert the image to grayscale and filter out the noise
 //CvInvoke.CvtColor(img, filter, ColorConversion.Bgr2Gray);

 //Remove noise
 //CvInvoke.GaussianBlur(filter, filter, new System.Drawing.Size(3, 3), 1);

 // Canny and edge detection
 double cannyThreshold = 1.0; //180.0
 double cannyThresholdLinking = 1.0; //120.0
 //CvInvoke.Canny(filter, cannyEdges, cannyThreshold, cannyThresholdLinking);
 CvInvoke.Canny(img, cannyEdges, cannyThreshold, cannyThresholdLinking);

 // Find rectangles
 List<RotatedRect> rectangleList = new List<RotatedRect>();
 using (VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint())
 {
   CvInvoke.FindContours(cannyEdges, contours, null, RetrType.List, ChainApproxMethod.ChainApproxSimple);
   int count = contours.Size;
   for (int i = 0; i < count; i++)
   {
     using (VectorOfPoint contour = contours[i])
     using (VectorOfPoint approxContour = new VectorOfPoint())
     {
       CvInvoke.ApproxPolyDP(contour, approxContour, CvInvoke.ArcLength(contour, true) * 0.05, true);
       // Only consider contours with area greater than 250
       if (CvInvoke.ContourArea(approxContour, false) > 250)
       {
         // The contour has 4 vertices.
         if (approxContour.Size == 4)
         {
           // Determine if all the angles in the contour are within [80, 100] degree
           bool isRectangle = true;
           System.Drawing.Point[] pts = approxContour.ToArray();
           LineSegment2D[] edges = Emgu.CV.PointCollection.PolyLine(pts, true);

           for (int j = 0; j < edges.Length; j++)
           {
             double angle = Math.Abs(edges[(j + 1) % edges.Length].GetExteriorAngleDegree(edges[j]));
             if (angle < 80 || angle > 100)
             {
               isRectangle = false;
               break;
             }
           }

           if (isRectangle) rectangleList.Add(CvInvoke.MinAreaRect(approxContour));
         }
       }
     }
   }
 }

 // Draw rectangles
 foreach (RotatedRect rectangle in rectangleList)
 {
   CvInvoke.Polylines(rectangleImage, Array.ConvertAll(rectangle.GetVertices(), System.Drawing.Point.Round), true,
       new Bgr(Color.DarkOrange).MCvScalar, 2);
 }

 //Drawing a light gray frame around the image
 CvInvoke.Rectangle(rectangleImage,
     new Rectangle(System.Drawing.Point.Empty,
         new System.Drawing.Size(rectangleImage.Width - 1, rectangleImage.Height - 1)),
     new MCvScalar(120, 120, 120));
 //Draw the labels
 CvInvoke.PutText(rectangleImage, "Rectangles", new System.Drawing.Point(20, 20),
     FontFace.HersheyDuplex, 0.5, new MCvScalar(120, 120, 120));

 Mat result = new Mat();
 CvInvoke.VConcat(new Mat[] { img, rectangleImage }, result);
 return result;
}

编辑 1: 在使用以下 Canny

阈值进行更精细的调整后

并且对所有 ContourAreas 使用 10000 的最小尺寸,我可以获得以下结果:

编辑 2: 对于那些感兴趣的人,使用当前检测解决了问题,不需要任何更改。使用上面屏幕截图中的 2 个检测到的矩形来获取包含项目名称的缺失矩形的位置。

结果可以在这里找到: https://github.com/josdemmers/NewWorldCompanion

对于那些感兴趣的人,使用当前检测解决了问题,无需更改。使用上面屏幕截图中的 2 个检测到的矩形来获取包含项目名称的缺失矩形的位置。

可在此处找到结果:https://github.com/josdemmers/NewWorldCompanion