使用OpenCV测量图像中物体的大小

2018.11.22 17:32
2126 0 0

      图像目标尺寸检测类似于计算从我们的相机到一个物体的距离——在这两种情况下,我们都需要事先定义一个比率来测量每个给定度量单位的像素数(pixels_per_metric)。为了确定图像中物体的大小,我们首先需要使用一个参照物作为“校准”点。我们的参照物应该有两个重要的属性:
       1、我们应该知道这个物体的真实尺寸(在宽度或高度上的毫米或英寸等值的大小)。
       2、我们应该能够轻松地在图片中找到这个参照物,要么基于参照物的位置(如,参照物可以是一副图像中左上角的物体)或基于参照物的外表(例如参照物可以是图片中具有独特的颜色或独一无二的形状,不同于所有其他的物体)。一句话而言:在任何一种情况下,我们的参照物都应该是以某种方式进行唯一可识别的The One。

参照物对比图.png

图1:我们将使用一个美分硬币作为我们的参照物,并确保它总是被放置在图像中左边,这使得我们可以通过对它们位置的轮廓大小进行排序,进一步来提取信息。

  通过保证这个美分硬币是左边的物体后,我们可以从左到右对我们的物体等高线区域进行排列,抓住这个硬币(它将始终对应于排序列表中的第一个等高线区域),并使用它来定义我们的pixels_per_metric比率,我们将其定义为:

pixels_per_metric =物体像素宽 / 物体真实宽

  美分硬币的真实宽度是0.955英寸。现在,假设我们图像中硬币的像素宽为150像素(基于它的相关边界框)。那么这种情况下pixels_per_metric这样计算:
pixels_per_metric = 150px / 0.955in = 157px
因此,在我们这幅图像中,每英寸大约有157个像素。有了这个比率,我们可以计算图像中其他物体的大小了。
利用计算机视觉测量物体大小

  既然我们已经理解了pixels_per_metric,我们就可以实现用于测量图像中对象大小的Python程序脚本了。
打开一个新的py文件,插入以下代码:

py文件中插入代码.png

第2-8行用来导入我们所需的Python包。在本例中,我们将大量使用imutils包,因此,如果您没有安装它,请确保在使用之前安装它:

安装imutils包.png

另外如果你已经安装过这个imutils包,也请确保它为新版本,在我这里所使用新的版本是0.3.6。

新版本代码.png

第10行和第11行定义了一个midpoint函数,顾名思义,它用于计算两个(x,y)坐标之间的中点。

  然后我们在第14-19行中解析我们的命令行参数。我们需要两个参数,–image,它是我们输入图像的路径,其中包含我们想要测量的对象,–width,也就是我们的参照物的宽度(英寸),–image路径图像中所认定的那个左边的物体。

  我们现在可以加载我们的图像并对其进行预处理:
图像预处理代码.png

       第22-24行从磁盘加载我们的图像,将其转换为灰度,然后使用高斯过滤器平滑它。然后我们执行边缘检测和扩张+磨平,以消除边缘图中边缘之间的任何间隙(第28-30行)。

  第33-35行找到等高线,也就是我们边缘图中物体相对应的轮廓线。

  然后,这些等高线区域从左到右(使得我们可以提取到参照物)在第39行中进行排列。然后我们在第40行时,对pixelsPerMetric值进行初始化。

  下一步是对每一个等高线区域值大小进行检查校验。
等高线区域值大小校验代码.png

    在第43行,我们开始对每个单独的轮廓值进行循环。如果等高线区域大小不够大,我们就会丢弃该区域,认为它是边缘检测过程遗留下来的噪音(第45和46行)。
  如果等高线区域足够大,我们就会在第50-52行计算图像的旋转边界框,特别注意:cv2.cv.BoxPoints函数是针对于opencv2.4版本,而cv2.BoxPoints函数是针对于OpenCV 3版本。
  然后我们将旋转的边界框坐标按顺序排列在左上角,右上角,右下角,左下角,正如上周的博客文章(第58行)所讨论的。
  后,第59-63行用绿色画出物体的轮廓,然后将边界框矩形的顶点画在小的红色圆圈中。现在我们已经有了边界框,接下来就可以计算出一系列的中点:

计算中点代码图.png

    第68-70行将我们前面所得的有序边界框各个值拆分出来,然后计算左上角和右上角之间的中点,然后是计算左下角和右下角之间的中点。
  此外,我们还分别计算左上角与左下角,右上角和右下角的中点(第74和75行)。
  第78-81行在我们的图像上画出蓝色的中点,然后将各中间点用紫色线连接起来。
  接下来,我们需要通过查看我们的参照物来初始化pixelsPerMetric变量:
初始化pixelsPerMetric变量.png

首先,我们计算中间点集之间的欧几里得距离(第90行和第91行)。
dA变量将包含高度距离(以像素为单位),而dB将保持我们的宽度距离。
然后,我们在第96行进行检查,看看我们的pixelsPerMetric变量是否已经被初始化了,如果没有,我们将dB除以我们提供的宽度,从而得到每英寸的(近似)像素。
现在我们已经定义了pixelsPerMetric变量,我们可以测量图像中各物体的大小:

测量图像中各物体大小代码图.png

第100行和第101行计算物体的尺寸(英寸),方法是通过pixelsper度量值划分各自的欧几里得距离(参见上面的“pixels_per_metric ”一节,以获得关于这个比率如何工作的更多信息)。 第104-109行在我们的图像上画出物体的尺寸,而第112和113行显示输出结果。

标签: OpenCV
投诉文章 ©著作权归作者所有
喜欢  |  0
0/200字
没有更多评论了~
悬赏问题
给科研问题设置一定金额,将更容易获得关注与回答哦~
  • 1元
  • 3元
  • 5元
  • 8元
  • 18元
  • 自定义
选择支付方式
  • 微信支付
  • 支付宝支付
  • 余额支付
Copyright © 2014-2019 晟斯医学 All Rights Reserved. 备案号:苏ICP备11037034号-5 版权所有:南京孜文信息咨询有限公司