【问题标题】:How do I find images inside an image?如何在图像中找到图像?
【发布时间】:2021-02-23 06:51:29
【问题描述】:

如何在图片中找到图片?

现在我正在使用 EmguCV,并根据本教程编写了以下代码: https://www.emgu.com/wiki/index.php/Shape_(Triangle,_Rectangle,_Circle,_Line)_Detection_in_CSharp

        using (UMat gray = new UMat())
        using (UMat cannyEdges = new UMat())
        {
            CvInvoke.CvtColor(img, gray, ColorConversion.Bgr2Gray);
            CvInvoke.GaussianBlur(gray, gray, new Size(3, 3), 2);
            CvInvoke.Canny(gray, cannyEdges, 0, 10, 3);

            LineSegment2D[] lines = CvInvoke.HoughLinesP(
                cannyEdges,
                1, //Distance resolution in pixel-related units
                Math.PI / 2, //Angle resolution measured in radians.
                0, //threshold
                40, //min Line width
                1); //gap between lines


            foreach (LineSegment2D line in lines)
            {
                CvInvoke.Line(img, line.P1, line.P2, new Bgr(Color.Red).MCvScalar, 1);
            }
        }

第 1 步 第2步 第 3 步

这是迄今为止我最好的结果,但它并不完美,因为我仍然需要一些边缘才能在图像周围创建所有边界框。

第 4 步

我想要的是找到图像中每个图像的所有边缘,这样我就可以像这样制作完美的边界框。

我是 EmguCV/OpenCV 的新手,但我仍然认为我最好的选择是使用这个库来解决这个问题。 我只需要找到正确的工具并正确使用它们,这就是我希望这里有人可以帮助我:)

【问题讨论】:

    标签: c# emgucv


    【解决方案1】:

    您可以这样做:

    • 加载图片
    • 反转 - img.Not()
    • 转换为灰度 - img.Convert<Gray,byte>()
    • 执行二进制阈值 - img.Convert<Gray, byte>().ThresholdBinary(new Gray(54), new Gray(255))

    会产生如下图,优化阈值以获得更好的效果:

    • 获取凸包和边界框。执行筛选,以便获得符合条件的对象。可以使用等高线面积、周长等。

      var Contours = new List<Contour<Point>>();
      for (Contour<Point> contours = _gray.FindContours(
         HAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, RETR_TYPE.CV_RETR_EXTERNAL); 
         contours != null; contours = contours.HNext)
      {
          Seq<Point> pts = contours.GetConvexHull(ORIENTATION.CV_CLOCKWISE);
          double diff = Math.Round(Math.Abs(pts.Area - contours.Area) / 
            pts.Area, 2);
      
          //additional constraint
          double q = contours.Area / contours.Perimeter;
      
          //bounding box of the counter
          Rectangle rect = contours.BoundingRectangle;
      
          //customize the value to suit your need
          if (contours.BoundingRectangle.Height > 5 && 
           contours.BoundingRectangle.Width > 5)
          {
              Contours.Add(contours);
          }
      } 
      
    • Contours 做你想做的事(例如填充并用作掩码以提取每个图像、绘制边界框等)

    【讨论】:

    • 谢谢!我根据您的示例制作了一个工作原型,效果很好。但是有一个问题,因为如果背景是黑色而不是像ibb.co/GxVgJ80 这样的白色,那么它将不再起作用。我发现我可以通过不反转它来解决它,但是我怎么知道我是否必须反转它?
    • 您可以统计黑色像素或白色像素的数量,设置阈值,然后选择是否反转图像。
    • 阈值可以是黑色像素的总数占整个图像的百分比,例如 20% 或 0.20。然后,如果满足此条件,您可以选择是否反转图像。
    猜你喜欢
    • 1970-01-01
    • 2011-01-29
    • 1970-01-01
    • 1970-01-01
    • 2015-12-19
    • 2023-03-21
    • 1970-01-01
    • 2023-03-22
    • 2018-01-05
    相关资源
    最近更新 更多