一、相機成像原理
相機成像原理是將三維物體通過投影變換映射到二維圖像上的過程。在現實世界中,物體的位置被表示為三維坐標,而圖像中的位置被表示為二維坐標。為了將物體的位置映射到圖像上,並保留物體的三維空間信息,需要一個數學模型。
相機成像模型一般使用針孔相機模型,該模型假設相機是由一個光學中心和一個無窮小孔構成。因為孔非常小,所以只有沿着相機中心到孔的光路才能通過相機。這種情況下,物體的每一個點發出的光線都經過針孔並在相機背面上投影成一幅倒立的圖像。
二、針孔相機模型
針孔相機模型描述了相機的光學成像過程。該模型是將三維坐標映射到二維圖像上的一種數學模型。在針孔相機模型中,相機由一個光心和一個無窮小孔構成,該模型的主要參數是焦距。
在針孔相機模型中,三維物體的每一個點都會發出一條射線經過針孔投影到二維圖像平面上,形成一幅倒立的二維圖像。因為針孔越小光闌的變動越小,所以針孔大小的變化會影響圖像的清晰度,需要根據不同的拍攝距離和光學參數選取不同的針孔大小以達到最優的成像效果。
#include
#include
using namespace std;
using namespace cv;
int main()
{
Mat image;
VideoCapture cap;
cap.open(0);
if (!cap.isOpened()) {
cout << "Can't open camera!" << endl;
return -1;
}
while (cap.read(image)) {
imshow("Camera", image);
waitKey(1);
}
return 0;
}
三、相機的標定
在使用相機拍攝時,需要了解相機拍攝的內部參數。這些參數包括焦距、畸變、旋轉矩陣和平移矩陣等。通常情況下,這些參數無法直接得到,需要通過相機的標定來獲取。
相機的標定過程是利用已知的三維點和它們在圖像上的投影點,通過最小二乘法和多項式擬合,計算出相機的內部參數和外部參數。這些參數可以用來表示相機的成像規律,能夠有效地提高圖像的質量。
#include
#include
using namespace std;
using namespace cv;
int main()
{
Mat image;
vector<vector> object_points;
vector<vector> image_points;
Size image_size;
vector rvecs, tvecs;
Mat intrinsic_matrix, dist_coeffs;
int corner_count = 0;
Size board_size = Size(9, 6);
int board_n = board_size.width * board_size.height;
vector corners;
vector temp_object_points;
int success = 0;
VideoCapture cap;
cap.open(0);
if (!cap.isOpened()) {
cout << "Can't open camera!" << endl;
return -1;
}
while (success < 20) {
cap.read(image);
if (image.empty()) {
continue;
}
image_size = image.size();
bool pattern_was_found = findChessboardCorners(image, board_size, corners);
if (pattern_was_found) {
cornerSubPix(image, corners, Size(11, 11), Size(-1, -1),
TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 30, 0.1));
drawChessboardCorners(image, board_size, corners, pattern_was_found);
corner_count += corners.size();
success++;
for (int i = 0; i < board_n; i++) {
Point3f point((float)(i / board_size.width), float(i%board_size.width), 0.0f);
temp_object_points.push_back(point);
}
object_points.push_back(temp_object_points);
image_points.push_back(corners);
}
imshow("Camera", image);
waitKey(1);
}
double rms = calibrateCamera(object_points, image_points, image.size(), intrinsic_matrix,
dist_coeffs, rvecs, tvecs,
CV_CALIB_FIX_K4 + CV_CALIB_FIX_K5);
cout << "Distortion coefficients: " << dist_coeffs << endl;
cout << "Intrinsic matrix: " << intrinsic_matrix << endl;
return 0;
}
四、相機投影變換
在三維空間中定義一個點的坐標為(X, Y, Z),其在相機坐標系中的坐標為(x, y, z)。如何將這個點投影到圖像上呢?
相機投影變換的過程是將三維坐標映射到二維圖像上,這個過程主要分為兩步:第一步是將三維坐標系中的點投影到相機坐標系中;第二步是將相機坐標系中的點投影到二維圖像平面上。
#include
#include
using namespace std;
using namespace cv;
int main()
{
Mat image;
Mat camera_matrix = Mat::zeros(3, 3, CV_64F);
Mat rot_matrix = Mat::zeros(3, 3, CV_64F);
Mat trans_matrix = Mat::zeros(3, 1, CV_64F);
Mat project_matrix = Mat::zeros(3, 4, CV_64F);
double f = 689.0343; // 焦距
double cx = 319.5; // 光心 x 坐標
double cy = 239.5; // 光心 y 坐標
camera_matrix.at(0, 0) = f;
camera_matrix.at(1, 1) = f;
camera_matrix.at(0, 2) = cx;
camera_matrix.at(1, 2) = cy;
camera_matrix.at(2, 2) = 1;
rot_matrix.at(0, 0) = 1;
rot_matrix.at(1, 1) = 1;
rot_matrix.at(2, 2) = 1;
trans_matrix.at(0, 0) = 0;
trans_matrix.at(1, 0) = 0;
trans_matrix.at(2, 0) = 20; // 相機到物體 20cm 的距離
Mat object_points = Mat::zeros(4, 1, CV_64F);
object_points.at(0, 0) = 0;
object_points.at(1, 0) = 0;
object_points.at(2, 0) = 0;
object_points.at(3, 0) = 1;
project_matrix = camera_matrix * rot_matrix * (Mat_(3, 1) << 0, 0, 20) + camera_matrix * trans_matrix;
Mat image_points = project_matrix * object_points;
cout << "Image Points: " << image_points << endl;
return 0;
}
五、結論
相機成像模型是圖像處理領域中的一個重要概念。了解相機成像模型的基本原理,可以更好地理解圖像的成像過程。同時,相機的標定和投影變換等技術也為處理三維物體提供了重要的工具。
原創文章,作者:LQUWT,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/334331.html
微信掃一掃
支付寶掃一掃