深度学习如何用于测量图像中的尺寸
深度学习如何用于测量图像中的尺寸
在数字图像处理领域,边缘检测与形态学是两项至关重要的技术。本文将结合简单的形态学算法,使用Matlab介绍一个测量目标尺寸的小项目。通过这个项目,读者可以深入了解如何利用像素与实际尺寸的比例关系,实现对图像中物体大小的精确测量。
图1 效果图
1. 测距原理
在数字图像处理中,每一张图片本质上都是一个庞大的矩阵。若不知道测距物体的距离,就无法对图像中物体进行大小的测量计算。因此,我们需要引入一个类似比例尺的概念:pixels per metric ratio(每度量单位的像素比率)。
在本篇文章中,我们将度量单位设定为英寸(inch)。具体来说,我们需要一个参考物,这个参考物需要满足两个重要性质:
- 参考物尺寸:我们应该知道物体的尺寸(包括测量的单位,如mm、英寸等)
- 易于识别:我们应该能够很容易地在图片中找到参照物体
在本篇文章中,我们将硬币作为我们的参考物,已知其尺寸大小为1 inch1 inch,并且为满足性质2,我们确保其始终置于*图像最左侧。
因此我们得到给定度量单位像素比例计算公式:
pixels per metric ratio = 硬币像素数/物体实际尺寸
已知硬币长宽均为1英寸,假设其在图像中像素宽为157px(基于其关联的检测框),得:
pixels per metric ratio = 157px/1.000in = 157px/in
通过使用这一比例,我们便可计算图像中其它物体的尺寸大小信息了。
2. 利用计算机视觉测量物体的大小
现在我们理解了pixels per metric ratio比率的含义,但我们还需要对目标进行检测进行检测框长宽的提取,这一步我们将用到诸如灰度图变换、边缘检测、形态学等算法。
首先我们定义硬币长宽,并且读取原始图像
coin_width
图3 原始图像
之后我们使用rgb2gray(image)函数进行灰度图转换,并且通过imfilter(f, w,boundary_options)函数对图像进行高斯滤波,其中w为滤波器,由fspecial(type,parameters,sigma)生成,其中将type设为"gaussian",sigma设为1,代码及效果如下
%转换为灰度图像
图4 高斯图像
对高斯滤波后的图像进行Canny边缘检测,使用edge(I,method,threshold),,其中I为输入图像,method为指定算法,文章中使用"canny"进行边缘检测,而threshold为阈值,通常设为0.1,具体想了解各边缘检测算法详解请看这篇文章
Rustle:数字图像图像处理:边缘检测(Edge detection)zhuanlan.zhihu.com
图5 Canny边缘检测图像
通过观察边缘图像可以发现各目标内部还具有较细的纹理,对后续八连通区域的检测造成较大干扰,因此我们可以通过孔洞填充操作去除内部纹理,其次提取孔洞填充图像外围边缘,最后使用形态学算法去除较小物体,具体代码如下:
% 孔洞填充
其中bwperim函数与传统的边缘检测概念不同,边缘检测为提取图像边缘特征图像,而bwperim只保留目标最外层边缘,bwareaopen(I4,150)意为去除图像中小于150px的八连通区域(至于为什么选择150,emmmm笔者是把它当成参数直接人为调的哈)
最后效果如下:
图6 孔洞填充图像
图7 提取外围边缘
图8 去除小物体
至此,我们便完成了对图像的处理阶段,接下来我们需要对物体进行标记,并且绘制相关的检测框图,其中我们使用 [labelpic,num] = bwlabel(I5,8)来对图像从左至右对目标进行标记,并配合find函数进行特定目标的操作,如接下来我们需要计算pixels per metric ratio,我们需要将最左边硬币目标提取出来,我们可以使用以下代码进行提取
[
其中r,c分别为目标对象(coin)的八连通行列坐标,然后我们使用函数minboundrect(c,r,'p')将得到的r,c进行最小外接矩形的计算,其中参数p表示按边长最小原则进行计算,最后使用minboxing()函数计算最小外接矩形的长宽,具体代码如下:
% 获取标记物体最小外接矩形坐标点
计算pixels per metric ratio:
% 单位英寸像素点比例计算
其中minboundrect与minboxing函数并不是Matlab官方函数,具体代码会在文末给出
我们使用同样的原理进行各目标最小外接矩形的计算,并使用line函数在图像中绘制出矩形框与中点连线
for
最后,我们根据pixels per metric ratio与最小外接矩形长宽计算目标实际尺寸,并通过text函数在图像中进行显示,代码如下:
line
好了现在我们完成了所有工作,最终的效果图便是这样啦
图9 效果图
最后在放两个动图让大家看看效果吧
图10 效果演示
图11 效果演示
如上图所示,我们已经成功的计算出图片中每个物体的尺寸
然而,并非所有的结果都是完美的,可能的原因:
- 拍摄的角度并非是一个完美的90°俯视。如果不是90°拍摄,物体的尺寸可能会出现扭曲
- 没有使用相机内在和外在参数来校准。当无法确定这些参数时,照片很容易发生径向和切向的透镜变形。执行额外的校准步骤来找到这些参数可以消除图片中的失真并得到更好的物体大小的近似值
参考
1.Measuring size of objects in an image with OpenCV
代码如下:
coin_width
minboundrect函数
function
minboxing函数
function