关于图像校正我们需要用到以下几个函数
// 假设你已经有了相机内参矩阵和畸变系数
cv::Mat cameraMatrix;
cv::Mat distCoeffs;
// 读取需要矫正的图像
cv::Mat distortedImage = cv::imread("distorted.jpg");
// 进行畸变矫正
cv::Mat undistortedImage;
cv::undistort(distortedImage, undistortedImage, cameraMatrix, distCoeffs);
// 显示矫正后的图像
cv::imshow("Undistorted Image", undistortedImage);
cv::waitKey(0);
1,cv::undistort(distortedImage, undistortedImage, cameraMatrix, distCoeffs);这个函数是主要的进行畸变矫正的
2,我们需要得到cameraMatrix(相机内参矩阵)和distCoeffs(畸变系数)这通常通过拍摄一个棋盘格标定板并使用cv::calibrateCamera函数来完成。
double cv::calibrateCamera(InputArrayOfArrays objectPoints, InputArrayOfArrays imagePoints, Size imageSize, OutputArray cameraMatrix, OutputArray distCoeffs, OutputArrayOfArrays rvecs = noArray(), OutputArrayOfArrays tvecs = noArray(), int flags = 0, TermCriteria criteria = TermCriteria( TermCriteria::COUNT+TermCriteria::EPS, 30, DBL_EPSILON) );
参数说明:
objectPoints:实际的3D点。
imagePoints:每个3D点对应的图像中的2D点。
imageSize:图像的大小。
cameraMatrix:输出的相机内参矩阵。
distCoeffs:输出的畸变系数。
rvecs:输出的旋转向量,每个向量对应于每个图像点。
tvecs:输出的平移向量,每个向量对应于每个图像点。
flags:标定方法的标志。
criteria:迭代优化算法的终止条件。
那么这里我们需要知道的是实际的3D点(世界坐标系)和2D点
以下是一个基本代码
// 假设你已经有了3D实际点和对应的2D图像点
std::vector<std::vector<cv::Point3f>> objectPoints;
std::vector<std::vector<cv::Point2f>> imagePoints;
// 图像的大小
cv::Size imageSize(640, 480);
// 进行相机标定
cv::Mat cameraMatrix, distCoeffs;
cv::calibrateCamera(objectPoints, imagePoints, imageSize, cameraMatrix, distCoeffs);
3,cv::findChessboardCorners或cv::findCirclesGrid来得到3D实际点和对应的2D图像点
cv::findChessboardCorners函数在OpenCV中用于在图像中检测棋盘格的角点。这个函数通常用于相机标定,因为它可以提供一组已知的3D实际点和对应的2D图像点。
bool cv::findChessboardCorners(InputArray image, Size patternSize, OutputArray corners, int flags = CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE)
参数说明:
image:输入图像,必须是8位灰度图像。
patternSize:棋盘格的大小(即横向和纵向的角点数)。
corners:输出的角点列表。
flags:操作标志,可以是以下值之一或它们的组合:
CALIB_CB_ADAPTIVE_THRESH
CALIB_CB_NORMALIZE_IMAGE
CALIB_CB_FILTER_QUADS
CALIB_CB_FAST_CHECK
以下是一个基本的例子:
// 读取图像
cv::Mat image = cv::imread("chessboard.jpg", cv::IMREAD_GRAYSCALE);
// 检测棋盘格角点
std::vector<cv::Point2f> corners;
bool found = cv::findChessboardCorners(image, cv::Size(9, 6), corners);
if (found) {
// 如果找到了角点,进行亚像素级别的精确化
cv::cornerSubPix(image, corners, cv::Size(11, 11), cv::Size(-1, -1), cv::TermCriteria(cv::TermCriteria::EPS + cv::TermCriteria::COUNT, 30, 0.1));
}
在这个例子中,我首先读取了一张棋盘格图像。然后,我使用cv::findChessboardCorners函数检测了棋盘格的角点。如果找到了角点,我还使用cv::cornerSubPix函数进行了亚像素级别的精确化。
4,在畸形矫正中图像的3D实际点如何获取?
在相机标定和畸变矫正中,3D实际点通常来自于一个已知的标定对象,如棋盘格或圆形网格。这些标定对象在世界坐标系中的位置是已知的,因此可以直接得到3D实际点。
例如,如果你使用一个棋盘格作为标定板,你可以假设棋盘格在一个平面上(例如,Z=0),并且你知道每个格子的大小,那么你就可以计算出每个格子交点的3D坐标。
以下是一个基本的例子:
// 创建3D实际点
std::vector<cv::Point3f> objectPoints;
for (int i = 0; i < 6; ++i) {
for (int j = 0; j < 9; ++j) {
objectPoints.push_back(cv::Point3f(j * 1.0, i * 1.0, 0.0));
}
}
在这个例子中,我创建了3D实际点,假设棋盘格的大小是1x1,并且棋盘格在Z=0的平面上。