相機成像模型詳解

一、相機成像原理

相機成像原理是將三維物體通過投影變換映射到二維圖像上的過程。在現實世界中,物體的位置被表示為三維坐標,而圖像中的位置被表示為二維坐標。為了將物體的位置映射到圖像上,並保留物體的三維空間信息,需要一個數學模型。

相機成像模型一般使用針孔相機模型,該模型假設相機是由一個光學中心和一個無窮小孔構成。因為孔非常小,所以只有沿着相機中心到孔的光路才能通過相機。這種情況下,物體的每一個點發出的光線都經過針孔並在相機背面上投影成一幅倒立的圖像。

二、針孔相機模型

針孔相機模型描述了相機的光學成像過程。該模型是將三維坐標映射到二維圖像上的一種數學模型。在針孔相機模型中,相機由一個光心和一個無窮小孔構成,該模型的主要參數是焦距。

在針孔相機模型中,三維物體的每一個點都會發出一條射線經過針孔投影到二維圖像平面上,形成一幅倒立的二維圖像。因為針孔越小光闌的變動越小,所以針孔大小的變化會影響圖像的清晰度,需要根據不同的拍攝距離和光學參數選取不同的針孔大小以達到最優的成像效果。

#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-hant/n/334331.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
LQUWT的頭像LQUWT
上一篇 2025-02-05 13:05
下一篇 2025-02-05 13:05

相關推薦

  • TensorFlow Serving Java:實現開發全功能的模型服務

    TensorFlow Serving Java是作為TensorFlow Serving的Java API,可以輕鬆地將基於TensorFlow模型的服務集成到Java應用程序中。…

    編程 2025-04-29
  • Python訓練模型後如何投入應用

    Python已成為機器學習和深度學習領域中熱門的編程語言之一,在訓練完模型後如何將其投入應用中,是一個重要問題。本文將從多個方面為大家詳細闡述。 一、模型持久化 在應用中使用訓練好…

    編程 2025-04-29
  • ARIMA模型Python應用用法介紹

    ARIMA(自回歸移動平均模型)是一種時序分析常用的模型,廣泛應用於股票、經濟等領域。本文將從多個方面詳細闡述ARIMA模型的Python實現方式。 一、ARIMA模型是什麼? A…

    編程 2025-04-29
  • Python實現一元線性回歸模型

    本文將從多個方面詳細闡述Python實現一元線性回歸模型的代碼。如果你對線性回歸模型有一些了解,對Python語言也有所掌握,那麼本文將對你有所幫助。在開始介紹具體代碼前,讓我們先…

    編程 2025-04-29
  • VAR模型是用來幹嘛

    VAR(向量自回歸)模型是一種經濟學中的統計模型,用於分析並預測多個變量之間的關係。 一、多變量時間序列分析 VAR模型可以對多個變量的時間序列數據進行分析和建模,通過對變量之間的…

    編程 2025-04-28
  • 如何使用Weka下載模型?

    本文主要介紹如何使用Weka工具下載保存本地機器學習模型。 一、在Weka Explorer中下載模型 在Weka Explorer中選擇需要的分類器(Classifier),使用…

    編程 2025-04-28
  • Python實現BP神經網絡預測模型

    BP神經網絡在許多領域都有着廣泛的應用,如數據挖掘、預測分析等等。而Python的科學計算庫和機器學習庫也提供了很多的方法來實現BP神經網絡的構建和使用,本篇文章將詳細介紹在Pyt…

    編程 2025-04-28
  • Python AUC:模型性能評估的重要指標

    Python AUC是一種用於評估建立機器學習模型性能的重要指標。通過計算ROC曲線下的面積,AUC可以很好地衡量模型對正負樣本的區分能力,從而指導模型的調參和選擇。 一、AUC的…

    編程 2025-04-28
  • 量化交易模型的設計與實現

    本文將從多個方面對量化交易模型進行詳細闡述,並給出對應的代碼示例。 一、量化交易模型的概念 量化交易模型是一種通過數學和統計學方法對市場進行分析和預測的手段,可以幫助交易者進行決策…

    編程 2025-04-27
  • Python決定係數0.8模型可行嗎

    Python決定係數0.8模型的可行性,是在機器學習領域被廣泛關注的問題之一。本篇文章將從多個方面對這個問題進行詳細的闡述,並且給出相應的代碼示例。 一、Python決定係數0.8…

    編程 2025-04-27

發表回復

登錄後才能評論