水平相机校准

水平相机校准


该图案必须贴在一个平面上,它应该与你所要测量的物体的距离大致相同
Prepare Calibration Images
Create a cell array of file names of calibration images.
准备校准图像
创建校准图像文件名的单元格数组。


numImages = 9;
files = cell(1, numImages);
for i = 1:numImages
    files{i} = fullfile(matlabroot, 'toolbox', 'vision', 'visiondata', ...
        'calibration', 'slr', sprintf('image%d.jpg', i));
end


% Display one of the calibration images显示一个校准图像
magnification = 25;
figure; imshow(files{1}, 'InitialMagnification', magnification);
title('One of the Calibration Images');








Estimate Camera Parameters 摄像机相机参数
% Detect the checkerboard corners in the images.图像棋盘检测
[imagePoints, boardSize] = detectCheckerboardPoints(files);


% Generate the world coordinates of the checkerboard corners in the
% pattern-centric coordinate system, with the upper-left corner at (0,0).
设定坐标,将最左边上方的棋盘格定为(0,0),单位毫米
squareSize = 29; % in millimeters
worldPoints = generateCheckerboardPoints(boardSize, squareSize);


% Calibrate the camera.
cameraParams = estimateCameraParameters(imagePoints, worldPoints);


% Evaluate calibration accuracy.校准精度评估
figure; showReprojectionErrors(cameraParams);
title('Reprojection Errors');




读取待测量的图片
加载包含要测量的对象的图像。该图像包含校准模式,并且该模式与您要测量的对象处于同一平面内。
在这个例子中,图案和硬币都在同一个桌面上。


或者,您可以使用两个独立的图像:一个包含模式,
另一个包含要测量的对象。同样,对象和模式必须位于同一平面内。此外,图像必须从完全相同的视点捕获,
这意味着摄像机必须固定在适当的位置。
imOrig = imread(fullfile(matlabroot, 'toolbox', 'vision', 'visiondata', ...
        'calibration', 'slr', 'image9.jpg'));
figure; imshow(imOrig, 'InitialMagnification', magnification);
title('Input Image');




Undistort the Image失真图像


使用相机参数对象从图像中删除镜头畸变。这是精确测量所必需的。
[im, newOrigin] = undistortImage(imOrig, cameraParams, 'OutputView', 'full');
figure; imshow(im, 'InitialMagnification', magnification);
title('Undistorted Image');




注意,这个图像的镜头畸变很小。不失真的步骤更为重要,如果你使用广角镜头,或低端摄像头。
Segment Coins硬币分割
In this case, the coins are colorful on white background. Use the saturation component(饱和度分量) of the HSV
 representation of the image to segment them out.


% Convert the image to the HSV color space.图像转为HSV
imHSV = rgb2hsv(im);


% Get the saturation channel.获得饱和通道
saturation = imHSV(:, :, 2);


% Threshold the image图像阈值
t = graythresh(saturation);
imCoin = (saturation > t);


figure; imshow(imCoin, 'InitialMagnification', magnification);
title('Segmented Coins');




寻找最大的分量检测硬币
% Find connected components.寻找组件
blobAnalysis = vision.BlobAnalysis('AreaOutputPort', true,...
    'CentroidOutputPort', false,...
    'BoundingBoxOutputPort', true,...
    'MinimumBlobArea', 200, 'ExcludeBorderBlobs', true);
[areas, boxes] = step(blobAnalysis, imCoin);


% Sort connected components in descending order by area区域降序寻找组件
[~, idx] = sort(areas, 'Descend');


% Get the two largest components.得到最大的组件
boxes = double(boxes(idx(1:2), :));


% Adjust for coordinate system shift caused by undistortImage调整坐标系偏移引起的失真图像
boxes(:, 1:2) = bsxfun(@plus, boxes(:, 1:2), newOrigin);


% Reduce the size of the image for display.缩小显示图像大小
scale = magnification / 100;
imDetectedCoins = imresize(im, scale);


% Insert labels for the coins.给硬币插入标签
imDetectedCoins = insertObjectAnnotation(imDetectedCoins, 'rectangle', ...
    scale * boxes, 'penny');
figure; imshow(imDetectedCoins);
title('Detected Coins');




计算外部


为了将图像坐标中的点映射到世界坐标点,我们需要计算摄像机相对于标定模式的旋转和平移。
注意:非本征函数假定没有镜头畸变。在这种情况下图像点已在已无失真图像检测应用。
% Detect the checkerboard.棋盘格检测
[imagePoints, boardSize] = detectCheckerboardPoints(im);


% Compute rotation and translation of the camera.计算摄像机的旋转与平移
[R, t] = extrinsics(imagePoints, worldPoints, cameraParams);




测量第一枚硬币


为了测量第一枚硬币,我们将包围框的左上角和右上角转换为世界坐标。然后
我们用毫米计算它们之间的距离。一个硬币实际直径是19.05毫米。


% Get the top-left and the top-right corners.得到左上和右上脚的位置
box1 = double(boxes(1, :));
imagePoints1 = [box1(1:2); ...
                box1(1) + box1(3), box1(2)];


% Get the world coordinates of the corners 获取角的世界坐标
worldPoints1 = pointsToWorld(cameraParams, R, t, imagePoints1);


% Compute the diameter of the coin in millimeters.毫米计算直径的距离
d = worldPoints1(2, :) - worldPoints1(1, :);
diameterInMillimeters = hypot(d(1), d(2));
fprintf('Measured diameter of one penny = %0.2f mm\n', diameterInMillimeters);






Measure the Second Coin计算第二枚硬币
Measure the second coin the same way as the first coin.


% Get the top-left and the top-right corners.
box2 = double(boxes(2, :));
imagePoints2 = [box2(1:2); ...
                box2(1) + box2(3), box2(2)];


% Apply the inverse transformation from image to world
worldPoints2 = pointsToWorld(cameraParams, R, t, imagePoints2);


% Compute the diameter of the coin in millimeters.
d = worldPoints2(2, :) - worldPoints2(1, :);
diameterInMillimeters = hypot(d(1), d(2));
fprintf('Measured diameter of the other penny = %0.2f mm\n', diameterInMillimeters);
Measured diameter of the other penny = 18.88 mm




测量第一个硬币的距离
% Compute the center of the first coin in the image.第一枚硬币的中心位置
center1_image = box1(1:2) + box1(3:4)/2;


% Convert to world coordinates.  转换为世界坐标
center1_world  = pointsToWorld(cameraParams, R, t, center1_image);


% Remember to add the 0 z-coordinate.  给世界坐标标定初始值0的坐标
center1_world = [center1_world 0];


% Compute the distance to the camera.计算相机的距离
distanceToCamera = norm(center1_world + t);
fprintf('Distance from the camera to the first penny = %0.2f mm\n', ...
    distanceToCamera);




(/***精度控制在2mm***/)
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值