【问题标题】:Detection of rectangular bright area in a Image using OpenCv使用 OpenCv 检测图像中的矩形明亮区域
【发布时间】:2012-05-21 19:50:08
【问题描述】:

我之前问过一个问题Marking an interest point in an image using c++。我使用了相同的解决方案,并使用自适应阈值和Blob Detection Algorithm(Growing Regions) 获得了所需的点。我有原始源图,我想在其中检测中心的矩形区域

原图:

.但是在我使用算法之后,我得到了这样的东西(如果你在新标签中打开它,细节是可见的)

标记图像:

除了矩形区域外,还可以看到明亮的日光照射点。我使用了双边过滤,但仍然无法检测到矩形区域。但是该算法适用于背景更暗的夜间图像。

有人可以建议我是否可以使用相同的算法进行一些修改或任何其他有效的方法可用..

谢谢

【问题讨论】:

    标签: c++ algorithm image-processing opencv


    【解决方案1】:

    在上图中,我建议

    1. 正常的阈值操作应该可以很好地工作,或者

    2. 逐行链码“计算”或

    3. 在直方图中查找梯度。

    还有很多其他的解决方案。 如果这是一致的,我会考虑减去背景阴影。

    【讨论】:

      【解决方案2】:

      使用 blurthreshold 的简单组合我设法得到了这个结果(调整大小以供查看):

      之后,应用 erosionthe squares.cpp technique(来自 OpenCV 的示例)输出:

      这几乎是您正在寻找的结果:矩形的底部被成功检测到。您需要做的就是增加检测到的矩形(红色正方形)的高度以适合您感兴趣的区域。

      代码:

      Mat img = imread(argv[1]);
      
          // Blur
      Mat new_img = img.clone();
      medianBlur(new_img, new_img, 5);
      
      // Perform threshold
      double thres = 210;
      double color = 255;
      threshold(new_img, new_img, thres, color, CV_THRESH_BINARY);
      imwrite("thres.png", new_img);
      
      // Execute erosion to improve the detection
      int erosion_size = 4;   
      Mat element = getStructuringElement(MORPH_CROSS,
                                         Size(2 * erosion_size + 1, 2 * erosion_size + 1),
                                         Point(erosion_size, erosion_size) );
      erode(new_img, new_img, element);
      imwrite("erode.png", new_img);
      
      vector<vector<Point> > squares;
      find_squares(new_img, squares);
      std::cout << "squares: " << squares.size() << std::endl;
      
      draw_squares(img, squares);
      
      imwrite("area.png", img);
      

      编辑

      find_squares() 函数返回一个向量,其中包含图像中找到的所有正方形。因为它在图像的每个通道上进行迭代,所以在您的示例中,它成功检测到每个通道中的矩形区域,因此打印squares.size() 输出3

      正方形可以看成是 4 (X,Y) 坐标的向量,OpenCV 将这个概念表达为vector&lt;Point&gt;,允许您访问坐标的 X 和 Y 部分。

      现在,打印squares 表明这些点是在逆时针方向上检测到的:

      1st ------ 4th
       |          |
       |          |
       |          |
      2nd ------ 3rd
      

      按照这个例子,很明显,如果你需要增加矩形的高度,你需要改变第 1 点和第 4 点的 Y:

      for (int i = 0; i < squares.size(); i++)
      {
          for (int j = 0; j < squares[i].size(); j++)
          {
          //  std::cout << "# " << i << " " << squares[i][j].x << ","<< squares[i][j].y << std::endl;
              if (j == 0 || j == 3)
                  squares[i][j].y = 0;
          }
      }
      

      【讨论】:

      • @Karlphilip wow..那太好了..非常感谢您的帮助。我也得到了较暗图像的预期结果,但硬编码阈值说(大约 80)。如果它远离该地区。我找不到正方形。所以我使用了 Otsu 阈值,但我必须添加 30 才能获得满意的检测。检测更暗和更亮图像的任何其他方式
      • 这是我唯一能想到的。
      • @Karlphilip..使用这个算法我只想找到原始图中矩形区域中心的坐标。我可以提出的任何想法。
      • 好吧,既然你已经有了矩形边缘的坐标,一个简单的数学运算就会给你中心坐标,不是吗?让我们每个线程保留一个问题。如果您有更多问题,请随时在新线程中提问。
      • @lakshmikant 您不应该向向量添加更多点,只需更改您拥有的点。 cv::Point 存储 X,Y 坐标。您有兴趣在 2 点内将 Y 坐标更改为 0。请记住,一个正方形有 4 个点。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-14
      • 2013-03-23
      • 2017-06-01
      • 2023-03-03
      • 1970-01-01
      相关资源
      最近更新 更多