针孔相机模型

在针孔相机模型当中, $O$ 为摄像机的光心,$z$ 轴指向相机前方,$x$ 向右,$y$ 向下。设 $P$ 点的坐标为 $[X, Y, Z]^T$, $P'$ 点的坐标为 $[X', Y', X']^T$, 并且设物理成像平面到小孔的距离为 $f$(焦距)。

那么则有

$$ \frac { Z } { f } = - \frac { X } { X ^ { \prime } } = - \frac { Y } { Y ^ { \prime } } $$

简单的, 我们可以认为

$$ \frac { Z } { f } = \frac { X } { X ^ { \prime } } = \frac { Y } { Y ^ { \prime } } $$

Untitled

相机坐标与像素坐标

OpenCV的基本使用

#include <stdio.h>
#include <opencv2/opencv.hpp>

using namespace std;
int main(int argc, char* argv[]) {
    cv::Mat image;
    // 读取图片文件
    string filePath = "./images/lena.png";
    image = cv::imread(filePath);
    // 盘算文件是否正确读取
    if (image.data == nullptr){
        cerr << "文件" << filePath << "不存在" << endl;
        return 0;
    }
    // 输出文件基本信息
    cout << "COL:" << image.cols << " ROW:" << image.rows << " CHANNEL:" << image.channels() << endl;
    // 显示图片
    cv::imshow("image", image);
    cv::waitKey(0);

    // 判断 image 的类型
    if (image.type() != CV_8UC1 && image.type() != CV_8UC3){
        // 图像类型不符合要求
        cout << "image error" << endl;
        return 0;
    }

    // 图像的随机访问
	  // image.at<uchar>(y, x)
    chrono::steady_clock::time_point t1 = chrono::steady_clock::now();
    for (size_t y=0; y<image.rows; y++){
        for (size_t x = 0; x<image.cols; x++){
            // 获取行指针
            unsigned char *row_ptr = image.ptr(y);
            unsigned char *data_ptr = &row_ptr[x*image.channels()];
            for (int c=0; c!=image.channels(); c++){
                unsigned char data = data_ptr[c];
            }
        }
    }
    chrono::steady_clock::time_point t2 = chrono::steady_clock::now();
    chrono::duration<double> time_used = t2-t1;
    cout << "Total time:" << time_used.count() << "second" << endl;

    // 关于 cv::Mat 的拷贝
    // 直接赋值不会复制数据
    cv::Mat image_another = image;
    // 直接修改 image_another 会导致 image 的变化
    // 将左上角100*100的像素置为零
    image_another(cv::Rect(0, 0, 100, 100)).setTo(0);
    cv::imshow("image", image);
    cv::waitKey(0);

    // 可以使用 clone函数 来复制数据
    cv::Mat image_clone = image.clone();
    image_clone(cv::Rect(0, 0, 100, 100)).setTo(255);
    cv::imshow("image", image);
    cv::imshow("image_clone", image_clone);
    cv::waitKey(0);

    cv::destroyAllWindows();
    return 0;
}