一 相机的成像模型
空间中物体表面的三维坐标点与图像的像素坐标点存在某种关系,需要通过建立相机成像的几何模型来求解。其中,空间中三维坐标点存在于 世界坐标系、相机坐标系,二维坐标点存在于 图像坐标系、像素坐标系;世界坐标系 到 相机坐标系的变换关系就是相机的外参标定【姿态R和位置t】,相机坐标系 到 像素坐标系关系就是 相机的内参标定【焦距f、主点坐标(u0、v0)、像素尺寸(dx, dy)】。
1 为什么要有相机的内参标定?
2 为什么要有相机的外参标定?
二 相机的标定
由相机的成像模型可知,当已知世界坐标系中的三维坐标、图像像素坐标系中二维坐标时,就可以求解相机的内参、外参。接下来介绍OpenCV中的相机标定的相关函数、标定流程、代码及运行结果。
1 OpenCV中的相机标定相关函数介绍
1.1 findChessboardCorners() 函数
1.2 findCirclesGrid() 函数
1.3 find4QuadCornerSubpix()函数
1.4 drawChessboardCorners()函数
1.5 相机标定函数calibrateCamera()
1.6 Rodrigues() 函数
2 相机标定的步骤
- 选取N张不同角度拍摄的棋盘格图像,使用角点检测得到每张图像上的棋盘像素坐标点;
- 设定棋盘格中每个方格的物理尺寸和角点的数量,计算世界坐标系中的三维坐标点(z轴设置为0,只需计算x、y轴的坐标);
- 调用 calibrateCamera() 获取相机的内参矩阵、畸变系数矩阵、外参中的旋转向量、平移向量;
3 相机标定的代码与运行结果
#include
#include
#include
#include
using namespace std;
using namespace cv;
int main()
{
//读取所有图像
vector imgs;
string imageName;
string path = "D:zMaterialsalgorithmAlgoDatacal";
ifstream fin(path + "calibdata.txt");
while (getline(fin, imageName))
{
Mat img = imread(path + imageName);
imgs.push_back(img);
}
Size board_size = Size(9, 6); //方格标定板内角点数目(宽,高)
vector> imgsPoints;
for (int i = 0; i img1_points;
findChessboardCorners(gray1, board_size, img1_points); //计算方格标定板角点
find4QuadCornerSubpix(gray1, img1_points, Size(5, 5)); //细化方格标定板角点坐标
imgsPoints.push_back(img1_points);
drawChessboardCorners(img1, board_size, img1_points, true);
imshow(to_string(i), img1);
waitKey(0);
}
//生成棋盘格每个内角点的空间三维坐标
Size squareSize = Size(10, 10); //棋盘格每个方格的真实尺寸
vector> objectPoints;
for (int i = 0; i tempPointSet;
for (int j = 0; j rvecs; //每幅图像的旋转向量
vector tvecs; //每张图像的平移量
calibrateCamera(objectPoints, imgsPoints, imageSize, cameraMatrix, distCoeffs, rvecs, tvecs, 0);
cout
运行结果
三 相机(图像)校正
通过标定得到了相机内参矩阵、畸变矩阵,此时可以进行图像校正来去除图像畸变。以下为校正前后的图像:
从图像可以看出,校正前棋盘格的边缘有畸变(曲线),而校正后棋盘格的边缘畸变消失了。
1 OpenCV中去畸变的相关函数
1.1 undistort() 函数
1.2 initUndistortRectifyMap() 和 remap() 函数
2 去畸变的代码及运行结果
#include
#include
#include
#include
using namespace std;
using namespace cv;
//使用initUndistortRectifyMap()函数和remap()函数校正图像
void initUndistAndRemap(vector imgs, //所有原图像向量
Mat cameraMatrix, //计算得到的相机内参
Mat distCoeffs, //计算得到的相机畸变系数
Size imageSize, //图像的尺寸
vector &undistImgs) //校正后的输出图像
{
//计算映射坐标矩阵
Mat R = Mat::eye(3, 3, CV_32F);
Mat ma服务器托管网px = Mat(imageSize, CV_32FC1);
Mat mapy = Mat(imageSize, CV_32FC1);
initUndistortRectifyMap(cameraMatrix, distCoeffs, R, cameraMatrix, imageSize, CV_32FC1, mapx, mapy);
//校正图像
for (int i = 0; i imgs, //所有原图像向量
Mat cameraMatrix, //计算得到的相机内参
Mat distCoeffs, //计算得到的相机畸变系数
vector &undistImgs) //校正后的输出图像
{
for (int i = 0; i imgs;
string imageName;
string path = "D:zMaterialsalgorithmAlgoDatacal";
ifstream fin(path + "calibdata.txt");
while (getline(fin, imageName))
{
Mat img = imread(path + imageName);
imgs.push_back(img);
}
//输入前文计算得到的内参矩阵
Mat cameraMatrix = (Mat_(3, 3) (1, 5) undistImgs;
Size imageSize;
imageSize.width = imgs[0].cols;
imageSize.height = imgs[0].rows;
//使用initUndistortRectifyMap()函数和remap()函数校正图像
服务器托管网 initUndistAndRemap(imgs, cameraMatrix, distCoeffs, imageSize, undistImgs);
//用undistort()函数直接计算校正图像,下一行代码取消注释即可
//undist(imgs, cameraMatrix, distCoeffs, undistImgs);
//显示校正前后的图像
for (int i = 0; i
运行结果
四 相机投影
单目投影是指根据相机的成像模型计算空间中三维坐标点在图像二维平面中坐标的过程。OpenCV4 中提供 projectPoints() 函数用于计算世界坐标系中的三维点投影到像素坐标系中的二维坐标。
在单目投影时,需要提供三维点在世界坐标系中的坐标、世界坐标系变换到相机坐标系的旋转向量和平移向量以及相机的内参矩阵和畸变矩阵。
1 OpenCV中projectPoints()函数
2 单目投影代码和运行结果
#include "opencv2/opencv.hpp"
#include
#include
using namespace std;
using namespace cv;
int main()
{
/***************各项参数都是标定时得到的*****************/
//输入前文计算得到的内参矩阵和畸变矩阵
Mat cameraMatrix = (Mat_(3, 3) (1, 5) (1, 3) (1, 3) (1, 3) (1, 3) PointSets;
for (int j = 0; j imagePoints;
projectPoints(PointSets, rvec, tvec, cameraMatrix, distCoeffs, imagePoints);
/***********计算图像中内角点的真实坐标误差******************/
string path = "D:zMaterialsalgorithmAlgoDatacalleft02.jpg";
Mat img = imread(path);
Mat gray;
cvtColor(img, gray, COLOR_BGR2GRAY);
vector imgPoints;
findChessboardCorners(gray, boardSize, imgPoints); //计算方格标定板角点
find4QuadCornerSubpix(gray, imgPoints, Size(5, 5)); //细化方格标定板角点坐标
//计算估计值和图像中计算的真实时之间的平均误差
float e = 0;
for (int i = 0; i
运行结果:通过成像模型的内外参评估后的像素坐标系中二维坐标的误差很小。
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net
1. event(自定义事件): (1). 点击事件: # 子组件: // click事件,是在组件内部的元素上声明的. export default { methods: { handleClick (event) { this.$emit(‘on-clic…