用校准的相机测量平面物体

这个例子展示了如何测量硬币直径在世界单位使用一个校准相机。

概述

这个例子展示了如何校准相机,然后用它来测量平面物体的大小,比如硬币。该方法的一个应用实例是测量传送带上的零件以进行质量控制。

校准相机

摄像机标定是对镜头和图像传感器的参数进行估计的过程。这些参数是测量相机捕捉到的物体所需要的。这个例子展示了如何以编程方式校准相机。或者,您可以校准相机使用Cameracalibrator应用程序。

为了校准相机,我们首先需要从不同角度采取多个校准模式的图像。典型的校准模式是不对称的棋盘,其中一侧包含黑白的偶数正方形,而另一侧包含奇数的正方形。

图案必须固定到平坦的表面上,并且它应该与相机的距离大致相同,因为您要测量的对象。必须在世界单位中测量正方形的大小,例如毫米,尽可能精确地。在此示例中,我们使用图案的9个图像,但实际上建议使用10到20个图像以精确校准。

准备校准映像

创建校准图像的文件名的单元格数组。

numImages = 9;= cell(1, numImages);为了i = 1:numImages files{i} = fullfile(matlabroot,“工具箱”'想象''VisionData'......“校准”“单反”sprintf (“图像% d.jpg”, 一世));结束%显示其中一个校准图像放大率= 25;i = imread(文件{1});图;imshow(我,'InitialMagnification',放大倍);标题('其中一个校准图像');

估计摄像机参数

%检测图像中的棋盘角。[imagePoints, boardSize] = detectCheckerboardPoints(files); / /检查文件中生成棋盘角的世界坐标%模式中心坐标系,左上角为(0,0)。squareSize = 29;%在毫米WorldPoints = GenerateCheckerboards(BoardSize,Squarize);%校准相机。图像zize = [size(i,1),size(i,2)];Cameraparams =估计估计(象育点,WorldPoints)......'图片尺寸', 图片尺寸);%评估校准精度。图;ShowreproizherErrors(Cameraparams);标题('重新注入错误');

条形图表明了校准的准确性。每个柱状图显示了对应校准图像的平均重投影误差。重投影误差是指图像中检测到的角点与投影到图像中的理想世界点之间的距离。

读取要测量的对象的图像

加载包含要测量的对象的图像。这个图像包含了校准模式,并且这个模式与你要测量的物体在同一个平面上。在这个例子中,图案和硬币都在同一个桌面上。

或者,您可以使用两个单独的图像:一个包含图案的图像,另一个包含要衡量的对象。同样,对象和模式必须在同一平面中。此外,必须从完全相同的视点捕获图像,这意味着相机必须固定到位。

imorig = imread(fullfile(matlabroot,“工具箱”'想象''VisionData'......“校准”“单反”“image9.jpg”));图;imshow (imOrig'InitialMagnification',放大倍);标题('输入图像');

贴上图像

使用CameraParameters对象从图像中删除镜头失真。这是准确测量所必需的。

由于镜头引入了小失真,使用“全”输出视图来说明%图像未被还原。如果我们使用默认的“相同”选项,那将会很困难%以注意与原始图像相比的任何差异。注意小的黑色边框。[IM,Neworigin] = undostortimage(imorig,cameraparams,“OutputView”'满的');图;imshow (im,'InitialMagnification',放大倍);标题(“无畸变的图像”);

请注意,此图像呈现很少的镜头失真。如果使用广角镜头或低端网络摄像头,则未变形步骤更为重要。

分部硬币

在这种情况下,硬币在白色背景上是色彩鲜艳的。使用图像的HSV表示的饱和分量分段为OUT。

%将图像转换为HSV颜色空间。IMHSV = RGB2HSV(IM);%获取饱和通道。饱和度= imHSV(:,:, 2);图像阈值t = graythresh(饱和);imCoin =(饱和度> t);图;imshow (imCoin'InitialMagnification',放大倍);标题(“分段硬币”);

检测硬币

我们可以假设分段图像中的两个最大连接的组件对应于硬币。

%查找已连接组件。blobAnalysis =愿景。BlobAnalysis (“AreaOutputPort”,真的,......“CentroidOutputPort”, 错误的,......“BoundingBoxOutputPort”,真的,......'MiniplingBlobarea',200,'comotrudeborderblobs', 真的);[区域,盒子] =步骤(二手分析,imcoin);%按区域下降顺序排序连接的组件[~, idx] = sort(区域,“下”);%获得两个最大的组件。Boxes = double(框(idx(1:2),:));%缩小图像的大小以供显示。秤=放大/ 100;IMDetectedCoins = Imresize(IM,Scale);%为硬币插入标签。imDetectedCoins = insertObjectAnnotation (imDetectedCoins,“矩形”......刻度*盒子,“一分钱”);图;imshow (imDetectedCoins);标题('检测到的硬币');

计算外在

将图像中的点映射到世界坐标中的点,我们需要计算相机相对于校准模式的旋转和平移。请注意外在功能假设没有镜头失真。在这种情况下,在已经不变的图像中检测到映像点undostortimage.

%检测棋盘。[imagePoints,BoardSize] =侦探校验erboardPoints(IM);%调整图像点,使它们在坐标系中表示%用于原始图像,在它未被扭曲之前。这种调整%使它与为原始图像计算的camerarameters对象兼容。imagePoints = imagePoints + neworigin;%将Neworigin添加到每行图像点%计算旋转和相机翻译。[r,t] =外在物质(图像点,WorldPoints,Cameraparams);

测量第一枚硬币

要测量第一个硬币,我们将边缘框的左上角和右上角转换为世界坐标。然后我们计算它们之间以毫米之间的欧几里德距离。请注意,美国便士的实际直径为19.05毫米。

%调整边界框的左上角以进行坐标系换档%由未置换显图像引起的“完整”输出视图。这不是%需要输出'相同'。调整使得点兼容%与相机参数的原始图像。盒子=盒子+ [neworigin,0,0];宽度和高度添加了% 0填充%获取左上角和右上角。box1 = double(框(1,:));imagePoints1 = [box1(1:2);......Box1 (1) + Box1 (3), Box1 (2)];%得到了角落的世界坐标worldpoints1 = pointstoworld(Cameraparams,r,t,imagepoints1);用毫米计算硬币的直径。d = worldPoints1(2,:) - worldPoints1(1,:);直径in毫米= hypot(d(1), d(2));流('测量直径为一分钱=%0.2f mm \ n',直径尺);
测量直径一便士= 19.00毫米

测量第二枚硬币

以与第一个硬币相同的方式测量第二枚硬币。

%获取左上角和右上角。box2 = double(框(2,:));imagePoints2 = [box2(1:2);......Box2 (1) + Box2 (3), Box2 (2)];%从图像到世界应用逆变换worldpoints2 = pointstoworld(cameraparams,r,t,imagepoints2);用毫米计算硬币的直径。d = worldPoints2(2,:) - worldPoints2(1,:);直径in毫米= hypot(d(1), d(2));流('测量的直径,另一种便士=%0.2f mm \ n',直径尺);
测量的直径另一分钱= 18.85毫米

测量与第一个硬币的距离

除了测量硬币的尺寸外,我们还可以测量它来自相机的距离。

%计算图像中第一枚硬币的中心。Center1_Image = Box1(1:2)+ Box1(3:4)/ 2;%转换为世界坐标。Center1_World = Pointstoworld(Cameraparams,R,T,Center1_Image);%记得添加0 z坐标。Center1_world = [Center1_world 0];%计算到摄像机的距离。[〜,核心系列] = utInsicstocamerapose(R,T);distancetocamera = norm(Center1_world  - 亚美陆热带);流('从相机到第一便士的距离= %0.2f mm\n'......distancetocamera);
从相机到第一便士的距离= 719.52毫米

概括

此示例显示了如何使用校准相机来测量平面对象。请注意,测量值精确到0.2毫米。

参考

[1] Z.张。一种灵活的相机校准技术。图案分析和机器智能的IEEE交易,22(11):1330-1334,2000。