国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

用OpenCV進(jìn)行相機(jī)標(biāo)定(張正友標(biāo)定,有代碼)

這篇具有很好參考價(jià)值的文章主要介紹了用OpenCV進(jìn)行相機(jī)標(biāo)定(張正友標(biāo)定,有代碼)。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

1. 內(nèi)參與畸變

理論部分可以參考其他博客或者視覺slam十四講
相機(jī)標(biāo)定主要是為了獲得相機(jī)的內(nèi)參矩陣K和畸變參數(shù)

內(nèi)參矩陣K
用OpenCV進(jìn)行相機(jī)標(biāo)定(張正友標(biāo)定,有代碼)

畸變系數(shù):徑向畸變(k1,k2,k3), 切向畸變(p1,p2)
用OpenCV進(jìn)行相機(jī)標(biāo)定(張正友標(biāo)定,有代碼)徑向畸變公式
用OpenCV進(jìn)行相機(jī)標(biāo)定(張正友標(biāo)定,有代碼)切向畸變公式
用OpenCV進(jìn)行相機(jī)標(biāo)定(張正友標(biāo)定,有代碼)張正友標(biāo)定方法能夠提供一個(gè)比較好的初始解,用于后序的最優(yōu)化.

這里用棋盤格進(jìn)行標(biāo)定,如果能夠處理圓的偏心誤差問題,用圓形圖案標(biāo)定板可能效果更好.

至少三張圖片,一般用10-20張圖片為最佳,要保證相機(jī)視野內(nèi)各個(gè)角度,各個(gè)位置,各個(gè)方向都有圖像.盡量多角度多位置.

最好用買的標(biāo)定板,效果好,平.最好是背光板,能夠保證足夠的亮度和均勻度.

2. 用OpenCV標(biāo)定相機(jī)程序

1,提取角點(diǎn)
2,亞像素角點(diǎn)
3,可視化提取角點(diǎn)(非必須)
4,標(biāo)定
5,誤差計(jì)算(重投影誤差)文章來源地址http://www.zghlxwxcb.cn/news/detail-468988.html

#include <iostream>
#include <fstream>
#include <string>
#include <opencv2/opencv.hpp>
using namespace std;
int main(int argc, char **argv)
{
    string dir = "/home/wfq/MyProjects/cal_images/";  //標(biāo)定圖片所在文件夾
    ifstream fin(dir + "file_images.txt"); //讀取標(biāo)定圖片的路徑,與cpp程序在同一路徑下
    if (!fin)                              //檢測是否讀取到文件
    {
        cerr << "沒有找到文件" << endl;
        return -1;
    }
    ofstream fout(dir + "calibration_result.txt"); //輸出結(jié)果保存在此文本文件下
    //依次讀取每一幅圖片,從中提取角點(diǎn)
    cout << "開始提取角點(diǎn)……" << endl;
    int image_nums = 0;  //圖片數(shù)量
    cv::Size image_size; //圖片尺寸
    int points_per_row = 10;  //每行的內(nèi)點(diǎn)數(shù)
    int points_per_col = 7;   //每列的內(nèi)點(diǎn)數(shù)
    cv::Size corner_size = cv::Size(points_per_row, points_per_col); //標(biāo)定板每行每列角點(diǎn)個(gè)數(shù),共10*7個(gè)角點(diǎn)
    vector<cv::Point2f> points_per_image;                            //緩存每幅圖檢測到的角點(diǎn)
    vector<vector<cv::Point2f>> points_all_images;                   //用一個(gè)二維數(shù)組保存檢測到的所有角點(diǎn)
    string image_file_name;                                          //聲明一個(gè)文件名的字符串

    while (getline(fin, image_file_name)) //逐行讀取,將行讀入字符串
    {
        image_nums++;
        //讀入圖片
        cv::Mat image_raw = cv::imread(dir + image_file_name);
        if (image_nums == 1)
        {
            // cout<<"channels = "<<image_raw.channels()<<endl;
            // cout<<image_raw.type()<<endl;  //CV_8UC3
            image_size.width = image_raw.cols;  //圖像的寬對應(yīng)著列數(shù)
            image_size.height = image_raw.rows; //圖像的高對應(yīng)著行數(shù)
            cout << "image_size.width = " << image_size.width << endl;
            cout << "image_size.height = " << image_size.height << endl;
        }
        //角點(diǎn)檢測
        cv::Mat image_gray;                               //存儲灰度圖的矩陣
        cv::cvtColor(image_raw, image_gray, CV_BGR2GRAY); //將BGR圖轉(zhuǎn)化為灰度圖
        // cout<<"image_gray.type() = "<<image_gray.type()<<endl;  //CV_8UC1
        //step1 提取角點(diǎn)
        bool success = cv::findChessboardCorners(image_gray, corner_size, points_per_image);
        if (!success)
        {
            cout << "can not find the corners " << endl;
            exit(1);
        }
        else
        {
            //亞像素精確化(兩種方法)
            //step2 亞像素角點(diǎn)
            cv::find4QuadCornerSubpix(image_gray, points_per_image, cv::Size(5, 5));
            // cornerSubPix(image_gray,points_per_image,Size(5,5));
            points_all_images.push_back(points_per_image); //保存亞像素角點(diǎn)
            //在圖中畫出角點(diǎn)位置
            //step3 角點(diǎn)可視化
            cv::drawChessboardCorners(image_raw, corner_size, points_per_image, success); //將角點(diǎn)連線
            cv::imshow("Camera calibration", image_raw);
            cv::waitKey(0); //等待按鍵輸入
        }
    }
    cv::destroyAllWindows();
    //輸出圖像數(shù)目
    int image_sum_nums = points_all_images.size();
    cout << "image_sum_nums = " << image_sum_nums << endl;

    //開始相機(jī)標(biāo)定
    cv::Size block_size(21, 21);                            //每個(gè)小方格實(shí)際大小, 只會影響最后求解的平移向量t
    cv::Mat camera_K(3, 3, CV_32FC1, cv::Scalar::all(0));   //內(nèi)參矩陣3*3
    cv::Mat distCoeffs(1, 5, CV_32FC1, cv::Scalar::all(0)); //畸變矩陣1*5
    vector<cv::Mat> rotationMat;                            //旋轉(zhuǎn)矩陣
    vector<cv::Mat> translationMat;                         //平移矩陣
    //初始化角點(diǎn)三維坐標(biāo),從左到右,從上到下!!!
    vector<cv::Point3f> points3D_per_image;
    for (int i = 0; i < corner_size.height; i++)
    {
        for (int j = 0; j < corner_size.width; j++)
        {
            points3D_per_image.push_back(cv::Point3f(block_size.width * j, block_size.height * i, 0));
        }
    }
    vector<vector<cv::Point3f>> points3D_all_images(image_nums,points3D_per_image);        //保存所有圖像角點(diǎn)的三維坐標(biāo), z=0

    int point_counts = corner_size.area(); //每張圖片上角點(diǎn)個(gè)數(shù)
    //!標(biāo)定
    /**
     * points3D_all_images: 真實(shí)三維坐標(biāo)
     * points_all_images: 提取的角點(diǎn)
     * image_size: 圖像尺寸
     * camera_K : 內(nèi)參矩陣K
     * distCoeffs: 畸變參數(shù)
     * rotationMat: 每個(gè)圖片的旋轉(zhuǎn)向量
     * translationMat: 每個(gè)圖片的平移向量
     * */
    //step4 標(biāo)定
    cv::calibrateCamera(points3D_all_images, points_all_images, image_size, camera_K, distCoeffs, rotationMat, translationMat, 0);

    //step5 對標(biāo)定結(jié)果進(jìn)行評價(jià)
    double total_err = 0.0;               //所有圖像平均誤差總和
    double err = 0.0;                     //每幅圖像的平均誤差
    vector<cv::Point2f> points_reproject; //重投影點(diǎn)
    cout << "\n\t每幅圖像的標(biāo)定誤差:\n";
    fout << "每幅圖像的標(biāo)定誤差:\n";
    for (int i = 0; i < image_nums; i++)
    {
        vector<cv::Point3f> points3D_per_image = points3D_all_images[i];
        //通過之前標(biāo)定得到的相機(jī)內(nèi)外參,對三維點(diǎn)進(jìn)行重投影
        cv::projectPoints(points3D_per_image, rotationMat[i], translationMat[i], camera_K, distCoeffs, points_reproject);
        //計(jì)算兩者之間的誤差
        vector<cv::Point2f> detect_points = points_all_images[i];  //提取到的圖像角點(diǎn)
        cv::Mat detect_points_Mat = cv::Mat(1, detect_points.size(), CV_32FC2); //變?yōu)?*70的矩陣,2通道保存提取角點(diǎn)的像素坐標(biāo)
        cv::Mat points_reproject_Mat = cv::Mat(1, points_reproject.size(), CV_32FC2);  //2通道保存投影角點(diǎn)的像素坐標(biāo)
        for (int j = 0; j < detect_points.size(); j++)
        {
            detect_points_Mat.at<cv::Vec2f>(0, j) = cv::Vec2f(detect_points[j].x, detect_points[j].y);
            points_reproject_Mat.at<cv::Vec2f>(0, j) = cv::Vec2f(points_reproject[j].x, points_reproject[j].y);
        }
        err = cv::norm(points_reproject_Mat, detect_points_Mat, cv::NormTypes::NORM_L2);
        total_err += err /= point_counts;
        cout << "第" << i + 1 << "幅圖像的平均誤差為: " << err << "像素" << endl;
        fout << "第" << i + 1 << "幅圖像的平均誤差為: " << err << "像素" << endl;
    }
    cout << "總體平均誤差為: " << total_err / image_nums << "像素" << endl;
    fout << "總體平均誤差為: " << total_err / image_nums << "像素" << endl;
    cout << "評價(jià)完成!" << endl;

    //將標(biāo)定結(jié)果寫入txt文件
    cv::Mat rotate_Mat = cv::Mat(3, 3, CV_32FC1, cv::Scalar::all(0)); //保存旋轉(zhuǎn)矩陣
    cout << "\n相機(jī)內(nèi)參數(shù)矩陣:" << endl;
    cout << camera_K << endl<< endl;
    fout << "\n相機(jī)內(nèi)參數(shù)矩陣:" << endl;
    fout << camera_K << endl<< endl;
    cout << "畸變系數(shù):\n";
    cout << distCoeffs << endl<< endl<< endl;
    fout << "畸變系數(shù):\n";
    fout << distCoeffs << endl<< endl<< endl;
    for (int i = 0; i < image_nums; i++)
    {
        cv::Rodrigues(rotationMat[i], rotate_Mat); //將旋轉(zhuǎn)向量通過羅德里格斯公式轉(zhuǎn)換為旋轉(zhuǎn)矩陣
        fout << "第" << i + 1 << "幅圖像的旋轉(zhuǎn)矩陣為:" << endl;
        fout << rotate_Mat << endl;
        fout << "第" << i + 1 << "幅圖像的平移向量為:" << endl;
        fout << translationMat[i] << endl
             << endl;
    }
    fout << endl;
    fout.close();

    return 0;
}

3.畫棋盤標(biāo)定板

//函數(shù)聲明,默認(rèn)每行11個(gè)block, 沒列8個(gè)block, block大小為75個(gè)像素. 也就是10*7個(gè)內(nèi)點(diǎn)
void drawChessBoard(int blocks_per_row=11, int blocks_per_col=8, int block_size = 75);

// 11  8  75
void drawChessBoard(int blocks_per_row, int blocks_per_col, int block_size)
{
    //blocks_per_row=11 //每行11個(gè)格子,也就是10個(gè)點(diǎn)
    //blocks_per_col=8  //每列8個(gè)格子,也就是7個(gè)點(diǎn)
    //block_size=75     //每個(gè)格子的像素大小
    cv::Size board_size = cv::Size(block_size * blocks_per_row, block_size * blocks_per_col);
    cv::Mat chessboard = cv::Mat(board_size, CV_8UC1);
    unsigned char color = 0;
    for (int i = 0; i < blocks_per_row; i++)
    {
        color = ~color;
        for (int j = 0; j < blocks_per_col; j++)
        {
            chessboard(cv::Rect(i * block_size, j * block_size, block_size, block_size)).setTo(color);
            color = ~color;
        }
    }
    cv::Mat chess_board = cv::Mat(board_size.height + 100, board_size.width + 100, CV_8UC1, cv::Scalar::all(256)); //上下左右留出50個(gè)像素空白
    chessboard.copyTo(chess_board.rowRange(50, 50 + board_size.height).colRange(50, 50 + board_size.width));
    cv::imshow("chess_board", chess_board);
    cv::imwrite("chess_board.png", chess_board);
    cv::waitKey(-1);
    cv::destroyAllWindows();
}

4.OpenCV拍照

#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
int main(int argc, char **argv)
{
    cv::namedWindow("Camera",cv::WINDOW_AUTOSIZE);

    cv::VideoCapture cap;
    cap.open(0);

    if(!cap.isOpened())
    {
        cout<<"camera open failed!\n";
        return -1;
    }

    cv::Mat image;
    int id=1;
    char symbol;
    while(id<=6)
    {
        cap>>image;
        if(image.empty())
            break;
        cout<<"y or n"<<endl;
        cin>>symbol;
        if(symbol=='y')
        {
            cv::imwrite(to_string(id)+".png",image);
            cout<<"第"<<id<<"張圖片"<<endl;
            id++;
        }
    }
    return 0;
}

到了這里,關(guān)于用OpenCV進(jìn)行相機(jī)標(biāo)定(張正友標(biāo)定,有代碼)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 相機(jī)標(biāo)定張正友、opencv和halcon對比(1)

    相機(jī)標(biāo)定張正友、opencv和halcon對比(1)

    本文將從基本標(biāo)定開始,結(jié)合實(shí)際工作經(jīng)驗(yàn),分析張正友、opencv和halcon三者相機(jī)標(biāo)定的深層原理與不同之處,內(nèi)容比較多,如果出現(xiàn)錯(cuò)誤請指正。 我們使用的鏡頭都是由多組鏡片組成,它實(shí)際上是一種厚透鏡模型,但是目前所有的相機(jī)標(biāo)定是基于針孔模型來進(jìn)行標(biāo)定的,因此

    2024年02月03日
    瀏覽(21)
  • 【相機(jī)標(biāo)定】opencv python 標(biāo)定相機(jī)內(nèi)參時(shí)不計(jì)算 k3 畸變參數(shù)

    畸變參數(shù) k3 通常用于描述徑向畸變的更高階效應(yīng),即在需要高精度的應(yīng)用中可以用到,一般的應(yīng)用中 k1, k2 足矣。 常見的應(yīng)用中, orbslam3 中是否傳入 k3 是可選的,而 kalibr 標(biāo)定中則只需要傳入 k1, k2 。但計(jì)算 k3 時(shí)的 k1, k2 不等于不計(jì)算 k3 時(shí)的 k1, k2 ,因此需要學(xué)會兩種場景下

    2024年02月09日
    瀏覽(32)
  • OpenCV開發(fā)筆記(七十七):相機(jī)標(biāo)定(二):通過棋盤標(biāo)定計(jì)算相機(jī)內(nèi)參矩陣矯正畸變攝像頭圖像

    OpenCV開發(fā)筆記(七十七):相機(jī)標(biāo)定(二):通過棋盤標(biāo)定計(jì)算相機(jī)內(nèi)參矩陣矯正畸變攝像頭圖像

    若該文為原創(chuàng)文章,轉(zhuǎn)載請注明原文出處 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/136616551 各位讀者,知識無窮而人力有窮,要么改需求,要么找專業(yè)人士,要么自己研究 紅胖子(紅模仿)的博文大全:開發(fā)技術(shù)集合(包含Qt實(shí)用技術(shù)、樹莓派、三維、OpenCV、OpenGL、

    2024年03月13日
    瀏覽(32)
  • 相機(jī)的內(nèi)外參數(shù)標(biāo)定和畸變矯正原理和代碼

    相機(jī)的內(nèi)外參數(shù)標(biāo)定和畸變矯正原理和代碼

    相機(jī)的成像過程實(shí)質(zhì)上是坐標(biāo)系轉(zhuǎn)換。首先空間中的點(diǎn)坐標(biāo)由世界坐標(biāo)系轉(zhuǎn)換到相機(jī)坐標(biāo)系,然后將其投影到成像平面(圖像物理坐標(biāo)系),最后再將成像平面上的數(shù)據(jù)轉(zhuǎn)換到圖像像素坐標(biāo)系。但是由于透鏡制造精度及組裝工藝的差別會引入畸變,導(dǎo)致原始圖像的失真。鏡頭

    2024年04月16日
    瀏覽(23)
  • 相機(jī)標(biāo)定—— 張正友標(biāo)定法(1)

    相機(jī)標(biāo)定—— 張正友標(biāo)定法(1)

    我們首先要明白兩個(gè)問題:1、相機(jī)是如何成像的?2、相機(jī)標(biāo)定的目的是什么? 相機(jī)的成像過程涉及了 4 種坐標(biāo)系與 3 種變換關(guān)系,這 3種變換關(guān)系分別是剛體變換、投影變換和離散化。 圖 1 : 四 種 坐 標(biāo) 系 的 關(guān) 系 圖1 :四種坐標(biāo)系的關(guān)系 圖 1 : 四 種 坐 標(biāo) 系 的 關(guān) 系

    2023年04月09日
    瀏覽(27)
  • 相機(jī)標(biāo)定-張正友棋盤格標(biāo)定法

    相機(jī)標(biāo)定-張正友棋盤格標(biāo)定法

    目錄 1.針孔相機(jī)模型 2.相機(jī)成像過程 2.1? 各個(gè)坐標(biāo)系之間的轉(zhuǎn)換 2.1.1 圖像坐標(biāo)系到像素坐標(biāo)系? 2.1.2 相機(jī)坐標(biāo)系到圖像坐標(biāo)系 ?2.1.3世界坐標(biāo)系到相機(jī)坐標(biāo)系 ?2.1.4世界坐標(biāo)系到像素坐標(biāo)系 3.畸變與畸變矯正 3.1 畸變 3.2 畸變公式 4.相機(jī)標(biāo)定原理 5.張正友標(biāo)定法介紹 5.1張正友

    2024年01月16日
    瀏覽(21)
  • 【三維重建】相機(jī)標(biāo)定:張正友標(biāo)定法

    【三維重建】相機(jī)標(biāo)定:張正友標(biāo)定法

    本系列開始于2022.12.25,開始記錄三維重建項(xiàng)目課題研究時(shí)的學(xué)習(xí)筆記,其中主要分為以下幾部分組成: 一、相機(jī)成像及坐標(biāo)系之間的轉(zhuǎn)換關(guān)系 二、相機(jī)標(biāo)定:張正友標(biāo)定法 三、特征檢測與匹配 四、運(yùn)動(dòng)恢復(fù)結(jié)構(gòu)法 目錄 系列文章目錄 文章目錄 前言 一、 標(biāo)定目的 二、 張正

    2024年02月07日
    瀏覽(20)
  • 張正友相機(jī)標(biāo)定法原理與實(shí)現(xiàn)

    張正友相機(jī)標(biāo)定法原理與實(shí)現(xiàn)

    張正友相機(jī)標(biāo)定法是張正友教授1998年提出的單平面棋盤格的相機(jī)標(biāo)定方法。傳統(tǒng)標(biāo)定法的標(biāo)定板是需要三維的,需要非常精確,這很難制作,而張正友教授提出的方法介于傳統(tǒng)標(biāo)定法和自標(biāo)定法之間,但克服了傳統(tǒng)標(biāo)定法需要的高精度標(biāo)定物的缺點(diǎn),而僅需使用一個(gè)打印出來

    2024年02月04日
    瀏覽(23)
  • opencv對相機(jī)進(jìn)行畸變矯正,及矯正前后的坐標(biāo)對應(yīng)

    opencv對相機(jī)進(jìn)行畸變矯正,及矯正前后的坐標(biāo)對應(yīng)

    目前有個(gè)項(xiàng)目,需要用到熱成像相機(jī)。但是這個(gè)熱成像相機(jī)它的畸變比較厲害,因此需要用標(biāo)定板進(jìn)行標(biāo)定,從而消除鏡頭畸變。 同時(shí)需要實(shí)現(xiàn)用戶用鼠標(biāo)點(diǎn)擊校正后的畫面后,顯示用戶點(diǎn)擊位置的像素所代表的溫度。 另外熱成像sdk中還有個(gè)功能:選定一個(gè)rect,可以返回這

    2024年02月15日
    瀏覽(21)
  • opencv對相機(jī)進(jìn)行畸變校正,及校正前后的坐標(biāo)對應(yīng)

    opencv對相機(jī)進(jìn)行畸變校正,及校正前后的坐標(biāo)對應(yīng)

    目前有個(gè)項(xiàng)目,需要用到熱成像相機(jī)。但是這個(gè)熱成像相機(jī)它的畸變比較厲害,因此需要用標(biāo)定板進(jìn)行標(biāo)定,從而消除鏡頭畸變。 同時(shí)需要實(shí)現(xiàn)用戶用鼠標(biāo)點(diǎn)擊校正后的畫面后,顯示用戶點(diǎn)擊位置的像素所代表的溫度。 另外熱成像sdk中還有個(gè)功能:選定一個(gè)rect,可以返回這

    2024年02月14日
    瀏覽(19)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包