用标定相机测量平面物体
这个例子展示了如何使用单一校准相机测量世界单位的硬币直径。
概述
这个例子展示了如何校准一个相机,然后使用它来测量平面物体的大小,例如硬币。该方法的一个应用示例是测量输送带上的部件以进行质量控制。
校准相机
摄像机标定是对镜头和图像传感器的参数进行估计的过程。这些参数是测量摄像机捕捉到的物体所需要的。这个例子展示了如何以编程方式校准相机。或者,您也可以使用cameraCalibrator
应用程序。
为了校准相机,我们首先需要从不同角度拍摄校准模式的多个图像。典型的校准模式是一个非对称棋盘,其中一侧包含偶数个方格,包括黑色和白色,而另一侧包含奇数个方格。
图案必须贴在一个平面上,它与相机的距离应该与你想测量的物体大致相同。正方形的大小必须尽可能精确地用世界单位来测量,例如毫米。在本例中,我们使用9张图像的模式,但在实践中,建议使用10到20张图像进行精确校准。
准备校准图片
创建校准图像文件名的单元格数组。
numImages = 9;files = cell(1, numImages);为i = 1:numImages文件{i} = fullfile(matlabroot,“工具箱”,“愿景”,“visiondata”,...“校准”,“单反”sprintf (“图像% d.jpg”,我));结束显示一个校准图像放大倍数= 25;I = imread(文件{1});图;imshow(我“InitialMagnification”、放大);标题(“其中一幅校正图像”);
估计摄像机参数
检测图像中的棋盘角。[imagePoints, boardSize] = detectCheckerboardPoints(files);生成棋盘角的世界坐标以%模式为中心的坐标系,左上角为(0,0)。squareSize = 29;%在毫米worldPoints = generateCheckerboardPoints(boardSize, squareSize);校准相机。imageSize = [size(I, 1), size(I, 2)];cameraParams = estimatecamerparameters (imagePoints, worldPoints,...“图象尺寸”、图象尺寸);评估校准精度。图;showReprojectionErrors (cameraParams);标题(“Reprojection错误”);
柱状图表示校准的精度。每条显示对应校准图像的平均重投影误差。重投影误差是图像中检测到的角点与投影到图像中的相应理想世界点之间的距离。
阅读待测物体的图像
加载包含被测量对象的图像。此图像包含校准模式,该模式与您想测量的对象在同一平面上。在这个例子中,图案和硬币都在同一个桌面上。
或者,您可以使用两个单独的图像:一个包含模式,另一个包含要测量的对象。同样,对象和图案必须在同一个平面上。此外,图像必须从完全相同的视角捕捉,这意味着相机必须固定在适当的位置。
imOrig = imread (fullfile (matlabroot“工具箱”,“愿景”,“visiondata”,...“校准”,“单反”,“image9.jpg”));图;imshow (imOrig“InitialMagnification”、放大);标题(输入图像的);
Undistort图像
使用camerparameters对象从图像中去除镜头失真。这是精确测量的必要条件。
由于镜头引入了一点失真,使用“完整”输出视图来说明。已解除对映像的存储。如果我们使用默认的“相同”选项,这将是困难的%来注意与原始图像相比的任何差异。注意小的黑色边框。[im, newOrigin] = undistortion timage (imOrig, cameraParams,“OutputView”,“全部”);图;imshow (im,“InitialMagnification”、放大);标题(“无畸变的图像”);
注意,这张照片展示了非常小的镜头失真。如果你使用广角镜头或低端摄像头,不失真的步骤要重要得多。
段硬币
在这种情况下,硬币是彩色的白色背景。使用图像HSV表示的饱和度组件将它们分割出来。
将图像转换为HSV颜色空间。imHSV = rgb2hsv (im);获取饱和通道。饱和度= imHSV(:,:, 2);%阈值图像t = graythresh(饱和);imCoin =(饱和度> t);图;imshow (imCoin“InitialMagnification”、放大);标题(“分段硬币”);
检测硬币
我们可以假设分割图像中两个最大的连接组件对应硬币。
查找连接组件。blobAnalysis =愿景。BlobAnalysis (“AreaOutputPort”,真的,...“CentroidOutputPort”假的,...“BoundingBoxOutputPort”,真的,...“MinimumBlobArea”, 200,“ExcludeBorderBlobs”,真正的);[areas, boxes] = step(blobAnalysis, imCoin);%按面积降序排列连接组件[~, idx] = sort(regions,“下”);得到两个最大的分量。box = double(box (idx(1:2),:));减少显示图像的大小。比例=放大倍率/ 100;imDetectedCoins = imresize(im, scale);为硬币插入标签。imDetectedCoins = insertObjectAnnotation (imDetectedCoins,“矩形”,...规模*盒子,“一分钱”);图;imshow (imDetectedCoins);标题(“发现硬币”);
计算外在
为了将图像坐标中的点映射到世界坐标中的点,我们需要计算相机相对于校准模式的旋转和平移。请注意,外在
函数假设没有透镜畸变。在这种情况下,imagePoints已经在已经使用未失真的图像中检测到undistortImage
.
检测棋盘。[imagePoints, boardSize] = detectCheckerboardPoints(im);调整imagePoints,使它们在坐标系统中表示%在原始图像未失真之前使用。这种调整%使它与为原始图像计算的cameraparparameters对象兼容。imagePoints = imagePoints + newOrigin;%将newOrigin添加到imagePoints的每一行计算相机的旋转和平移。。[R, t] = extrinsics(imagePoints, worldPoints, cameraParams);
测量第一枚硬币
为了测量第一枚硬币,我们将边界框的左上角和右上角转换为世界坐标。然后我们以毫米为单位计算它们之间的欧氏距离。请注意,一枚美国便士的实际直径是19.05毫米。
调整坐标系统移动的边框左上角%由undistortion timage导致,输出视图为“full”。这不是如果输出是'same',则需要%。这一调整使各点兼容%与原始图像的相机参数。boxes = boxes + [newOrigin, 0,0];为宽度和高度添加% 0填充得到左上角和右上角。。Box1 = double(boxes(1,:));imagePoints1 = [box1 (1:2);...Box1 (1) + Box1 (3), Box1 (2)];获取角落的世界坐标。worldPoints1 = pointsToWorld(cameraParams, R, t, imagePoints1);用毫米计算硬币的直径。d = worldPoints1(2,:) - worldPoints1(1,:);径terinmm = hypot(d(1), d(2));流(“一便士的直径= %0.2f mm\n”, diameterInMillimeters);
一便士的测量直径= 19.00毫米
测量第二枚硬币
用第一枚硬币同样的方法量第二枚硬币。
得到左上角和右上角。。Box2 = double(boxes(2,:));imagePoints2 = [box2 (1:2);...Box2 (1) + Box2 (3), Box2 (2)];应用图像到世界的逆变换。worldPoints2 = pointsToWorld(cameraParams, R, t, imagePoints2);用毫米计算硬币的直径。d = worldPoints2(2,:) - worldPoints2(1,:);径terinmm = hypot(d(1), d(2));流(“另一便士的测量直径= %0.2f mm\n”, diameterInMillimeters);
另一枚硬币的直径为18.85毫米
测量到第一枚硬币的距离
除了测量硬币的大小,我们还可以测量硬币离相机的距离。
计算图像中第一枚硬币的中心。Center1_image = box1(1:2) + box1(3:4)/2;%转换为世界坐标。center1_world = pointsToWorld(cameraParams, R, t, center1_image);记住要加上z坐标为0。Center1_world = [Center1_world 0];计算到相机的距离。[~, cameraLocation] = extrinsicsToCameraPose(R, t);distanceToCamera = norm(center1_world - cameraLocation);流('从相机到第一便士的距离= %0.2f mm\n',...distanceToCamera);
从相机到第一便士的距离= 719.52毫米
总结
这个例子展示了如何使用校准相机来测量平面物体。注意,测量精度在0.2毫米以内。
参考文献
[1] z。一种灵活的摄像机标定新技术。模式分析与机器智能学报,22(11):1330-1334,2000。