0

我正在尝试在 qt 中开发盒子排序应用程序并使用 opencv。我想测量盒子的宽度和长度。

输入图像

如上图所示,我只想检测最外面的线(即盒子边缘),这将给我盒子的宽度和长度,不管盒子里面印了什么。

我尝试了什么:

  1. 首先,我尝试使用Findcontours()并选择具有最大面积的轮廓,但外边缘的轮廓没有被封闭(在精明的输出中某处被破坏)多次,因此没有被检测为轮廓。

  2. 霍夫线变换给了我太多的线,我不知道如何只得到四行感兴趣。

  3. 我尝试了我的算法,

    将图像转换为灰度。

    取一列图像,将每个像素与该列的下一个连续像素进行比较,如果该值的差异大于某个阈值(例如 100)该像素属于边缘,则将其存储在数组中。对所有列执行此操作,它将给出平行于 x 轴的框的上线。

    遵循相同的程序,但从最后一列和最后一行(即从下到上),它将给出平行于 x 轴的下线。

    同样找到平行于 y 轴的线。现在我有四个点数组,每边一个。

现在,如果盒子的放置方式使其侧面与 X 和 Y 轴完全平行,这会给我带来很好的结果。如果将盒子放置在某个方向上,甚至稍微朝向某个方向,它就会给我对角线,如下图所示。

错误的输出

如下图所示,我从所有四个点数组(负责绘制对角线)中删除了前 10 个和最后 10 个点并绘制了线,当盒子倾斜更多时,这将不起作用,并且测量也会出错.

在此处输入图像描述

现在我的问题是,

在opencv中是否有任何更简单的方法来获取盒子的外边缘(矩形)并获得尺寸,忽略盒子上印刷的任何东西并朝向任何方向?

我不一定要求纠正/改进我的算法,但也欢迎对此提出任何建议。抱歉发了这么大的帖子。

4

2 回答 2

2

我建议采取以下步骤:

1:使用cv::inRange()文档)选择背景颜色制作蒙版图像。然后使用cv::not()反转此蒙版。这只会给你盒子。

2:如果您不担心阴影、深度影响会使您的测量不准确,您可以立即尝试cv::findContours()再次使用。您选择最大的轮廓并将其存储为cv::rotatedRect.

3:这cv::rotatedRect将为您提供一个旋转的Rect.size,它定义了框的宽度和高度(以像素为单位)

于 2014-08-01T14:28:46.863 回答
0

由于盒子放置在对比鲜明的背景中,您应该能够使用 Otsu 阈值。

  • 阈值图像(使用 Otsu 方法)
  • 过滤掉框区域外的任何杂散像素(希望您不会得到很多这样的像素,并且可以使用中值或形态过滤器轻松去除它们)
  • 寻找轮廓
  • 组合所有轮廓点并获得它们的凸包(这里的想法是找到在框区域中限制所有这些轮廓的凸区域,而不管它们的连通性如何)
  • 对这个凸包应用多边形近似 (approxPolyDP) 并检查是否得到四边形
  • 如果没有透视变形,你应该得到一个矩形,否则你必须纠正它
  • 如果你得到一个矩形,你就有它的尺寸。您还可以找到凸包的最小面积矩形 (minAreaRect),它应该直接给您一个 RotatedRect
于 2014-08-04T07:42:29.820 回答