主要内容

このページの翻訳は最新ではありません。ここをクリックして,英語の最新版を参照してください。

キャリブレートされたカメラによる平面オブジェクトの測定

この例では,キャリブレートされた単一のカメラを使ってコインの直径をワールド単位で測定する方法を説明します。

概要

この例では,カメラをキャリブレーションし,それを使ってコインなどの平面オブジェクトのサイズを測定する方法を説明します。この方法の応用例として,品質管理を目的とした,コンベヤーベルト上の部品の測定が挙げられます。

カメラのキャリブレーション

カメラのキャリブレーションは,レンズとイメージセンサーのパラメーターを推定するプロセスです。これらのパラメーターは,カメラで撮影したオブジェクトを測定するために必要です。この例では,プログラミングを使ってカメラのキャリブレーションを行う方法を説明します。別の方法として,cameraCalibratorアプリを使用してカメラをキャリブレーションすることもできます。

カメラのキャリブレーションを行うには,まずキャリブレーションパターンの複数のイメージを異なる角度から撮影する必要があります。一般的なキャリブレーションパターンは,1辺の方向に白黒の正方形が偶数個含まれ,もう1辺の方向には奇数個の正方形が含まれる,非対称のチェッカーボードです。

パターンは平らな面に貼り付けられ,カメラからの距離を測定対象のオブジェクトとほぼ同じにしなければなりません。正方形のサイズは,たとえばミリメートルなどのワールド単位で,できるだけ正確に測定しなければなりません。この例ではパターンのイメージを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 = generateCheckerboardPoints(boardSize, squareSize);校准相机。imageSize = [size(I, 1), size(I, 2)];cameraParams = estimatecamerparameters (imagePoints, worldPoints,...“图象尺寸”、图象尺寸);评估校准精度。图;showReprojectionErrors (cameraParams);标题(“Reprojection错误”);

图中包含一个坐标轴。标题为“重投影错误”的轴包含3个类型为bar, line的对象。这个对象表示总体平均误差:0.90像素。

棒グラフはキャリブレーションの精度を示しています。それぞれのバーは,対応するキャリブレーションイメージの平均再投影誤差を表します。再投影誤差は,イメージ内で検出されたコーナーポイントと,イメージに投影された対応する理想的なワールド座標点との距離です。

測定するオブジェクトのイメージの読み取り

測定対象のオブジェクトを含むイメージを読み込みます。このイメージはキャリブレーションパターンを含んでおり,そのパターンは,測定するオブジェクトと同じ平面にあります。この例では,パターンとコインの両方が同じテーブルの上に置かれています。

別の方法として,パターンを含むイメージと測定対象のオブジェクトを含むイメージという,2つの異なるイメージを使用することもできます。その場合もオブジェクトとパターンは同じ平面上になければなりません。また,イメージをまったく同一の視点から撮影する必要があるので,カメラは固定されていなければなりません。

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

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

イメージの歪み補正

cameraParametersオブジェクトを使用して,イメージからレンズ歪みを除去します。これは正確な測定を行うために必要です。

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

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

このイメージでのレンズ歪みはごくわずかであることに注意してください。広角レンズや低品質のWebカメラを使用する場合には,歪み補正の手順がより重要となります。

コインのセグメント化

ここでは,色彩のついたコインが白を背景として置かれています。イメージのHSV表現の彩度成分を使用してコインを切り出します。

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

图中包含一个坐标轴。标题为分割硬币的轴包含一个类型为image的对象。

コインの検出

セグメント化されたイメージにある2つの最大の連結要素がコインに対応すると仮定できます。

%查找连接的组件。blobAnalysis =愿景。BlobAnalysis (“AreaOutputPort”,真的,...“CentroidOutputPort”假的,...“BoundingBoxOutputPort”,真的,...“MinimumBlobArea”, 200,“ExcludeBorderBlobs”,真正的);[area, boxes] = step(blobAnalysis, imCoin);%按区域降序排列连接组件[~, idx] = sort(区域,“下”);%得到两个最大的分量。box = double(box (idx(1:2),:))); / /指定一个值减少显示的图像的大小。比例=放大倍数/ 100;imDetectedCoins = imresize(im, scale);%为硬币插入标签。imDetectedCoins = insertObjectAnnotation (imDetectedCoins,“矩形”...规模*盒子,“一分钱”);图;imshow (imDetectedCoins);标题(“发现硬币”);

图中包含一个坐标轴。标题为Detected Coins的轴包含一个类型为image的对象。

外部パラメーターの計算

イメージ座標の点をワールド座標の点にマッピングするには,キャリブレーションパターンを基準としてカメラの回転と並進を計算する必要があります。関数外在ではレンズ歪みがないと仮定する点に注意してください。ここでは,undistortImageを使って既に歪み補正されたイメージ内でimagePointsが検出されています。

%检测棋盘。[imagePoints, boardSize] = detectCheckerboardPoints(im);%调整imagePoints,使其在坐标系统中表示%用于原始图像,在它未被扭曲之前。这种调整%使它与为原始图像计算的camerarameters对象兼容。imagePoints = imagePoints + newOrigin;%添加newOrigin到imagePoints的每一行%计算相机的旋转和平移。[R, t] = extrinsics(imagePoints, worldPoints, cameraParams);

最初のコインの測定

最初のコインを測定するには,境界ボックスの左上と右上のコーナーをワールド座標に変換します。そして,その間のユークリッド距離をミリメートル単位で計算します。アメリカの1セント硬貨の実際の直径は19.05毫米であることに注意してください。

调整边界框的左上角以实现坐标系统的移位%由undistortion timage造成,输出视图为'full'。这就不是如果输出“相同”,则需要%。调整使各点兼容%与相机参数的原始图像。[newworigin, 0, 0]; / /点击[newworigin, 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,:);直径in毫米= hypot(d(1), d(2));流('测量一便士的直径= %0.2f mm\n', diameterInMillimeters);
测量直径一便士= 19.00毫米

2番目のコインの測定

2番目のコインを最初のコインと同じ方法で測定します。

%获取左上角和右上角。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,:);直径in毫米= 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);%记得添加0 z坐标。[Center1_world 0];%计算到摄像机的距离。[~, cameraLocation] = extrinsicsToCameraPose(R, t);distanceToCamera = norm(center1_world - cameraLocation);流('从相机到第一便士的距离= %0.2f mm\n'...distanceToCamera);
从相机到第一便士的距离= 719.52毫米

まとめ

この例では,キャリブレートされたカメラを使用して平面オブジェクトを測定する方法を説明しました。測定値が誤差0.2毫米以内の精度であったことに注意してください。

参考文献

[1] z。一种灵活的摄像机标定新技术。计算机工程与应用,2017,36(11):1330-1334,2000。