主要内容

用校准相机测量平面物体

此示例显示如何使用单个校准相机测量世界单位中的硬币直径。

概述

此示例显示如何校准相机,然后使用它来测量平面对象的大小,例如硬币。这种方法的示例应用是测量输送带上的用于质量控制的部件。

校准相机

相机校准是估计镜头和图像传感器的参数的过程。需要这些参数来测量相机捕获的对象。此示例显示如何以编程方式校准相机。或者,您可以使用使用的相机校准相机cameraCalibrator应用程序。

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

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

准备校准图片

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

numimages = 9;files = cell(1,NumImages);为了i = 1:Numimages文件{i} = fullfile(matlabroot,'工具箱'“愿景”“visiondata”...'校准''SLR',Sprintf('图像%d.jpg',我));结尾%显示一个校准图像放大率= 25;i = imread(文件{1});图;imshow(我,'InitialMagnification'、放大);标题(“其中一张校准图像”);

图中包含一个轴。标题为“One of The Calibration Images”的轴包含一个图像类型的对象。

估计相机参数

%检测图像中的棋盘角落。[ImagePoints,BoardSize] =侦探校验erboardPoints(文件);%生成棋盘角落的世界坐标%以图案为中心的坐标系,左上角(0,0)。Squaresize = 29;%以毫米worldPoints = generateCheckerboardPoints(boardSize, squareSize);校准相机。imageSize = [size(I, 1), size(I, 2)];cameraParams = estimatecamerparameters (imagePoints, worldPoints,...'图片大小', 图片大小);%评估校准精度。图;showReprojectionErrors (cameraParams);标题(“Reprojection错误”);

图中包含一个轴。具有标题重新注入误差的轴包含3个类型的栏杆,线路。此对象表示总体均值误差:0.90像素。

条形图表示校准的准确性。每个条形显示相应校准图像的平均刻录误差。重注错误是图像中检测到的角点之间的距离,并投影到图像中的相应理想世界点。

阅读被测量物体的图像

加载包含要测量的对象的图像。此图像包括校准模式,模式与您要测量的对象在同一平面中。在该示例中,图案和硬币都在同一台上。

或者,您可以使用两个独立的图像:一个包含模式,另一个包含要测量的对象。同样,物体和图案必须在同一个平面上。此外,图像必须从完全相同的视角捕获,这意味着相机必须固定在适当的位置。

imOrig = imread (fullfile (matlabroot'工具箱'“愿景”“visiondata”...'校准''SLR''image9.jpg'));图;imshow(imorig,'InitialMagnification'、放大);标题('输入图像');

图中包含一个轴。具有标题输入图像的轴包含类型图像的对象。

Undistort图像

使用cameraParameters对象从图像中去除镜头失真。这对精确测量是必要的。

%镜头引入了很小的失真,使用“完整”输出视图来说明%图像未分解。如果我们使用默认的“相同”选项,那将是困难的与原始图像相比,%要注意任何差异。注意小黑边界。[im, newOrigin] = un畸变图像(imOrig, camerparams)'OutputView''满的');图;imshow(我,'InitialMagnification'、放大);标题('不朽的形象');

图中包含一个轴。标题为undistortion Image的轴包含一个Image类型的对象。

请注意,此图像显示很少的透镜畸变。如果你使用的是广角镜头或低端网络摄像头,保持镜头不失真这一步就重要得多。

分部硬币

在这种情况下,硬币是彩色的白色背景。利用图像HSV表示的饱和分量来分割它们。

%将图像转换为HSV颜色空间。imHSV = rgb2hsv (im);%获取饱和通道。饱和= imhsv(:,:,2);%阈值图像t =曲线(饱和度);imcoin =(饱和> t);图;imshow(imcoin,'InitialMagnification'、放大);标题('分段硬币');

图中包含一个轴。标题为“分段硬币”的轴包含一个类型为图像的对象。

检测硬币

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

%查找连接组件。Blobanalysis = Vision.Blobanalysis('AreaOutputport', 真的,...'centroidoutputport', 错误的,...'bandingboxoutputport', 真的,...'MiniplingBlobarea',200,“ExcludeBorderBlobs”,真正的);[areas, boxes] = step(blobAnalysis, imCoin);%按区域降序排列连接组件[〜,IDX] =排序(区域,“下降”);得到两个最大的组件。Boxes = double(框(idx(1:2),:));%缩小图像的大小以供显示。秤=放大/ 100;IMDetectedCoins = Imresize(IM,Scale);%插入硬币标签。IMDetectedCoins = InsertObjectAnnotation(IMDetectedCoins,'长方形'...规模*盒子,'一分钱');图;imshow(imdetectedcoins);标题(“发现硬币”);

图中包含一个轴。标题为“已检测硬币”的轴包含一个类型为图像的对象。

计算外在内饰

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

%检测棋盘。[ImagePoints,BoardSize] =侦探校验erboardPoints(IM);%调整imagePoints,以便它们在坐标系统中表示%在原始图像中使用,在未置换之前。这个调整%使其与为原始图像计算的CameraParameters对象兼容。imagePoints = imagePoints + neworigin;%添加newororigin到imagePoints的每一行%计算旋转和相机翻译。[R, t] = extrinsics(imagePoints, worldPoints, cameraParams);

测量第一个硬币

为了测量第一枚硬币,我们将边界框的左上角和右上角转换为世界坐标。然后计算它们之间的欧几里德距离,单位是毫米。请注意,一美元硬币的实际直径是19.05毫米。

%调整边界框的左上角以进行坐标系统的移动%由未置换显图像引起的“完整”输出视图。这不是%需要输出'相同'。调整使得点兼容含有原始图像的Cameraparameters。盒子=盒子+ [neworigin,0,0];为Widht和Height添加%零填充%得到左上角和右上角。Box1 = double(boxes(1,:));imagePoints1 = [box1 (1:2);...BOX1(1)+ BOX1(3),BOX1(2)];%得到了角落的世界坐标worldPoints1 = pointsToWorld(camerparams, R, t, imagePoints1);%计算硬币的直径为毫米。d = worldPoints1(2,:)  -  WorldPoints1(1,:);直径百分比=半径(D(1),D(2));fprintf('一便士的测量直径= %0.2f毫米\n',直径尺);
测量直径为一分钱= 19.00毫米

测量第二枚硬币

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

%得到左上角和右上角。Box2 = double(boxes(2,:));imagePoints2 = [box2 (1:2);...BOX2(1)+ BOX2(3),BOX2(2)];%应用图像到世界的逆变换worldPoints2 = pointsToWorld(camerparams, R, t, imagePoints2);%计算硬币的直径为毫米。d = worldPoints2(2,:)  -  WorldPoints2(1,:);直径百分比=半径(D(1),D(2));fprintf('另一枚硬币的测量直径= %0.2f mm\n',直径尺);
另一枚硬币的测量直径= 18.85毫米

测量第一枚硬币的距离

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

%计算图像中第一个硬币的中心。Center1_Image = Box1(1:2)+ Box1(3:4)/ 2;%转换为世界坐标。center1_world = pointsToWorld(camerparams, R, t, center1_image);%记住添加0 z坐标。Center1_world = [Center1_world 0];%计算到相机的距离。[〜,核心系列] = utInsicstocamerapose(R,T);distancetocamera = norm(Center1_world  - 亚美陆热带);fprintf('从相机到第一个PENNY =%0.2F mm \ n'的距离...distanceToCamera);
距离相机到第一笔= 719.52 mm的距离

概括

这个例子展示了如何使用一个校准的相机来测量平面物体。注意,测量精度在0.2毫米以内。

参考

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