亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

聊一聊OpenCV相機(jī)標(biāo)定

 更新時(shí)間:2018年01月10日 11:22:01   作者:林多  
這篇文章主要為大家詳細(xì)介紹了OpenCV相機(jī)標(biāo)定的相關(guān)資料,即獲得相機(jī)參數(shù)的過程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

相機(jī)標(biāo)定:簡(jiǎn)單的說,就是獲得相機(jī)參數(shù)的過程。參數(shù)如:相機(jī)內(nèi)參數(shù)矩陣,投影矩陣,旋轉(zhuǎn)矩陣和平移矩陣等

什么叫相機(jī)參數(shù)?

簡(jiǎn)單的說,將現(xiàn)實(shí)世界中的人、物,拍成一張圖像(二維)。人或物在世界中的三維坐標(biāo),和圖像上對(duì)應(yīng)的二維坐標(biāo)間的關(guān)系。表達(dá)兩種不同維度坐標(biāo)間的關(guān)系用啥表示?用相機(jī)參數(shù)。

相機(jī)的成像原理

先來看一下,相機(jī)的成像原理:

這里寫圖片描述 

如圖所示,這是一個(gè)相機(jī)模型。將物體簡(jiǎn)化看成一個(gè)點(diǎn)。來自物體的光,通過鏡頭,擊中圖像平面(圖像傳感器),以此成像。d0是物體到鏡頭的距離,di時(shí)鏡頭到圖像平面的距離,f是鏡頭的焦距。三者滿足以下關(guān)系。

這里寫圖片描述 

現(xiàn)在,簡(jiǎn)化上面的相機(jī)模型。

將相機(jī)孔徑看成無窮小,只考慮中心位置的射線,這樣就忽視了透鏡的影響。然后由于d0遠(yuǎn)遠(yuǎn)大于di,將圖像平面放在焦距處,這樣物體在圖像平面上成像為倒立的影像(沒有透鏡的影響,只考慮從中心的孔徑進(jìn)入的光線)。這個(gè)簡(jiǎn)化的模型就是針孔攝像機(jī)模型。然后,我們?cè)阽R頭前,將圖像平面放在焦距距離的位置,就可以簡(jiǎn)單獲得一個(gè)筆直的圖像(不倒立)。當(dāng)然,這只是理論上的,你不可能將圖像傳感器從相機(jī)里拿出來,放在鏡頭前面。實(shí)際應(yīng)用中,針孔攝像機(jī)應(yīng)該是將成像后的圖像倒過來,以獲得正立的圖像。
到此,我們獲得了一個(gè)簡(jiǎn)化的模型,如下圖:

這里寫圖片描述 

h0是物體的高,hi是圖像上物體的高,f是焦距(距離),d0是圖像到鏡頭的距離。四者滿足如下關(guān)系:

這里寫圖片描述(1)

物體在圖像中的高度hi,和d0成反比。也就是說,離鏡頭越遠(yuǎn),物體在圖像中越小,離得越近越大(好吧,這句話是廢話)。
但通過這個(gè)式子,我們便能夠預(yù)測(cè)三維中的物體,在圖像(二維)中的位置。那么怎么預(yù)測(cè)?

相機(jī)標(biāo)定

如下圖所示,根據(jù)上面簡(jiǎn)化的模型,考慮三維世界中的一個(gè)點(diǎn),和其在圖像(二維)中的坐標(biāo)關(guān)系。

這里寫圖片描述 

(X,Y,Z)為點(diǎn)的三維坐標(biāo),(x,y)為其通過相機(jī)成像后在圖像(二維)上的坐標(biāo)。u0和v0是相機(jī)的中心點(diǎn)(主點(diǎn)),該點(diǎn)位于圖像平面中心(理論上是這樣。但實(shí)際的相機(jī)會(huì)有幾個(gè)像素的偏差)
現(xiàn)在只考慮y方向上,由于需要將三維世界中的坐標(biāo),轉(zhuǎn)換為圖像上的像素(圖像上的坐標(biāo),實(shí)際上是像素的位置),需要求y方向上焦距等于多少個(gè)像素(用像素值表示焦距),Py表示像素的高,焦距f(米或毫米)。垂直像素表示的焦距為

這里寫圖片描述

根據(jù)式子(1),只考慮y方向。我們?nèi)S世界中得點(diǎn),在圖像(二維)中y的坐標(biāo)。

這里寫圖片描述 

同理,得到x的坐標(biāo)。

這里寫圖片描述 

現(xiàn)在,將上圖中的坐標(biāo)系的原點(diǎn)O,移動(dòng)到圖像的左上角。由于(x,y)是關(guān)于(u0,v0)的偏移,上面表示圖像(二維)中點(diǎn)的坐標(biāo)的式子不變。將式子以矩陣的形式重寫,得。

這里寫圖片描述 

其中,等式左邊的第一個(gè)矩陣,叫做“相機(jī)內(nèi)參數(shù)矩陣”,第二個(gè)矩陣叫(投影矩陣)。

更為一般的情況,開始時(shí)的參考坐標(biāo)系不位于主點(diǎn)(中心點(diǎn)),需要額外兩個(gè)參數(shù)“旋轉(zhuǎn)向量”和“平移向量”來表示這個(gè)式子,這兩個(gè)參數(shù)在不同視角中是不一樣的。整合后,上述式子重寫為。

這里寫圖片描述

校正畸變

通過相機(jī)標(biāo)定,獲得了相機(jī)參數(shù)后,可以計(jì)算兩個(gè)映射函數(shù)(x坐標(biāo)和y坐標(biāo)),它們分別給出了沒有畸變的圖像坐標(biāo)。將畸變的圖像重新映射成為沒有畸變的圖像。

代碼:

做相機(jī)標(biāo)定時(shí),一般用標(biāo)定板(棋盤)拍攝一組圖像,利用這些圖像提取角點(diǎn),通過角點(diǎn)在圖像中得坐標(biāo)和三維世界中的坐標(biāo)(通常自定義3維坐標(biāo)),計(jì)算相機(jī)參數(shù)。

std::vector<cv::Point2f>imageConers;
//提取標(biāo)定圖像角點(diǎn),保存角點(diǎn)坐標(biāo)(二維)
 cv::findChessboardCorners(image,
 boardSize, //角點(diǎn)數(shù)目如(6,4)六行,四列
 imageConers);


函數(shù)calibrateCamera完成相機(jī)標(biāo)定工作。

cv::calibrateCamera(objectPoints,//三維坐標(biāo)
 imagePoints, //二維坐標(biāo)
 imageSize,//圖像大小
 camerMatirx,//相機(jī)內(nèi)參數(shù)矩陣
 disCoeffs,//投影矩陣
 rvecs, //旋轉(zhuǎn)
 tvecs,//平移
flag //標(biāo)記opencv提供幾種參數(shù),可以參看在線的opencv document
);

計(jì)算畸變參數(shù),去畸變

//計(jì)算畸變參數(shù)
cv::initUndistortRectifyMap(camerMatirx, disCoeffs,
  cv::Mat(), cv::Mat(), image.size(), CV_32FC1, 
  map1, //x映射函數(shù)
  map2 //y映射函數(shù)
  );
//應(yīng)用映射函數(shù)
cv::remap(image, //畸變圖像
undistorted, //去畸變圖像
map1, map2, cv::INTER_LINEAR);


現(xiàn)在整合代碼。

示例:

標(biāo)頭.h

#include<opencv2\core\core.hpp>
#include<opencv2\highgui\highgui.hpp>
#include<opencv2\imgproc\imgproc.hpp>
#include<opencv2\calib3d\calib3d.hpp>
#include <opencv2/features2d/features2d.hpp>
#include<string>
#include<vector>
class CameraCalibrator
{
private:
  //世界坐標(biāo)
  std::vector < std::vector<cv::Point3f >> objectPoints;
  //圖像坐標(biāo)
  std::vector <std::vector<cv::Point2f>> imagePoints;
  //輸出矩陣
  cv::Mat camerMatirx;
  cv::Mat disCoeffs;
  //標(biāo)記
  int flag;
  //去畸變參數(shù)
  cv::Mat map1, map2;
  //是否去畸變
  bool mustInitUndistort;

  ///保存點(diǎn)數(shù)據(jù)
  void addPoints(const std::vector<cv::Point2f>&imageConers, const std::vector<cv::Point3f>&objectConers)
  {
    imagePoints.push_back(imageConers);
    objectPoints.push_back(objectConers);
  }
public:
  CameraCalibrator() :flag(0), mustInitUndistort(true){}
  //打開棋盤圖片,提取角點(diǎn)
  int addChessboardPoints(const std::vector<std::string>&filelist,cv::Size &boardSize)
  {
    std::vector<cv::Point2f>imageConers;
    std::vector<cv::Point3f>objectConers;
    //輸入角點(diǎn)的世界坐標(biāo)
    for (int i = 0; i < boardSize.height; i++)
    {
      for (int j = 0; j < boardSize.width; j++)
      {
        objectConers.push_back(cv::Point3f(i, j, 0.0f));
      }
    }
    //計(jì)算角點(diǎn)在圖像中的坐標(biāo)
    cv::Mat image;
    int success = 0;
    for (int i = 0; i < filelist.size(); i++)
    {
      image = cv::imread(filelist[i],0);
      //找到角點(diǎn)坐標(biāo)
      bool found = cv::findChessboardCorners(image, boardSize, imageConers);
      cv::cornerSubPix(image, 
        imageConers,
        cv::Size(5, 5),
        cv::Size(-1, -1),
        cv::TermCriteria(cv::TermCriteria::MAX_ITER + cv::TermCriteria::EPS,
        30, 0.1));
      if (imageConers.size() == boardSize.area())
      {
        addPoints(imageConers, objectConers);
        success++;
      }
      //畫出角點(diǎn)
      cv::drawChessboardCorners(image, boardSize, imageConers, found);
      cv::imshow("Corners on Chessboard", image);
      cv::waitKey(100);
    }
    return success;
  }

  //相機(jī)標(biāo)定
  double calibrate(cv::Size&imageSize)
  {
    mustInitUndistort = true;
    std::vector<cv::Mat>rvecs, tvecs;
    //相機(jī)標(biāo)定
    return cv::calibrateCamera(objectPoints, imagePoints, imageSize,
      camerMatirx, disCoeffs, rvecs, tvecs, flag);
  }
  ///去畸變
  cv::Mat remap(const cv::Mat &image)
  {
    cv::Mat undistorted;
    if (mustInitUndistort)
    {
      //計(jì)算畸變參數(shù)
      cv::initUndistortRectifyMap(camerMatirx, disCoeffs,
        cv::Mat(), cv::Mat(), image.size(), CV_32FC1, map1, map2);
      mustInitUndistort = false;
    }
    //應(yīng)用映射函數(shù)
    cv::remap(image, undistorted, map1, map2, cv::INTER_LINEAR);
    return undistorted;
  }
  //常成員函數(shù),獲得相機(jī)內(nèi)參數(shù)矩陣、投影矩陣數(shù)據(jù)
  cv::Mat getCameraMatrix() const { return camerMatirx; }
  cv::Mat getDistCoeffs()  const { return disCoeffs; }
};

源.cpp

#include"標(biāo)頭.h"
#include<iomanip>
#include<iostream>
int main()
{
  CameraCalibrator Cc;
  cv::Mat image;
  std::vector<std::string> filelist;
  cv::namedWindow("Image");
  for (int i = 1; i <= 22; i++)
  {
    ///讀取圖片
    std::stringstream s;
    s << "D:/images/chessboards/chessboard" << std::setw(2) << std::setfill('0') << i << ".jpg";
    std::cout << s.str() << std::endl;

    filelist.push_back(s.str());
    image = cv::imread(s.str(),0);
    cv::imshow("Image", image);
    cv::waitKey(100);
  }
  //相機(jī)標(biāo)定
  cv::Size boardSize(6, 4);
  Cc.addChessboardPoints(filelist, boardSize);
  Cc.calibrate(image.size());

  //去畸變
  image = cv::imread(filelist[1]);
  cv::Mat uImage=Cc.remap(image);
  cv::imshow("原圖像", image);
  cv::imshow("去畸變", uImage);
  //顯示相機(jī)內(nèi)參數(shù)矩陣
  cv::Mat cameraMatrix = Cc.getCameraMatrix();
  std::cout << " Camera intrinsic: " << cameraMatrix.rows << "x" << cameraMatrix.cols << std::endl;
  std::cout << cameraMatrix.at<double>(0, 0) << " " << cameraMatrix.at<double>(0, 1) << " " << cameraMatrix.at<double>(0, 2) << std::endl;
  std::cout << cameraMatrix.at<double>(1, 0) << " " << cameraMatrix.at<double>(1, 1) << " " << cameraMatrix.at<double>(1, 2) << std::endl;
  std::cout << cameraMatrix.at<double>(2, 0) << " " << cameraMatrix.at<double>(2, 1) << " " << cameraMatrix.at<double>(2, 2) << std::endl;

  cv::waitKey(0);
}

實(shí)驗(yàn)結(jié)果:

這里寫圖片描述
這里寫圖片描述 

看以看到,相機(jī)內(nèi)參數(shù)矩陣為

172.654 、0、157.829
0、184.195、118.635
0 、0 、1

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • C語言實(shí)現(xiàn)循環(huán)隊(duì)列基本操作

    C語言實(shí)現(xiàn)循環(huán)隊(duì)列基本操作

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)循環(huán)隊(duì)列基本操作,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • C++實(shí)現(xiàn)的鏈表類實(shí)例

    C++實(shí)現(xiàn)的鏈表類實(shí)例

    這篇文章主要介紹了C++實(shí)現(xiàn)的鏈表類,以完整實(shí)例分析了C++實(shí)現(xiàn)鏈表類的定義、插入、刪除、遍歷、統(tǒng)計(jì)等相關(guān)技巧,需要的朋友可以參考下
    2015-06-06
  • C語言對(duì)CSV文件從最后往前一行一行讀取的實(shí)現(xiàn)方法

    C語言對(duì)CSV文件從最后往前一行一行讀取的實(shí)現(xiàn)方法

    今天小編就為大家分享一篇關(guān)于C語言對(duì)CSV文件從最后往前一行一行讀取的實(shí)現(xiàn)方法,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • 基于OpenCV?差分法實(shí)現(xiàn)綠葉識(shí)別

    基于OpenCV?差分法實(shí)現(xiàn)綠葉識(shí)別

    物體識(shí)別是圖像處理學(xué)在現(xiàn)實(shí)生活中較多的應(yīng)用之一,本文提供了一種相對(duì)簡(jiǎn)單的思路來實(shí)現(xiàn)綠葉識(shí)別,適合初學(xué)圖像處理的新人研究參考。感興趣的同學(xué)可以關(guān)注一下
    2021-11-11
  • C語言結(jié)構(gòu)體占用內(nèi)存深入講解

    C語言結(jié)構(gòu)體占用內(nèi)存深入講解

    這篇文章主要給大家介紹了關(guān)于C語言結(jié)構(gòu)體占用內(nèi)存的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • C++實(shí)現(xiàn)雙向鏈表(List)

    C++實(shí)現(xiàn)雙向鏈表(List)

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)雙向鏈表,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • C語言實(shí)現(xiàn)txt數(shù)據(jù)讀入內(nèi)存/CPU緩存實(shí)例詳解

    C語言實(shí)現(xiàn)txt數(shù)據(jù)讀入內(nèi)存/CPU緩存實(shí)例詳解

    這篇文章主要介紹了C語言實(shí)現(xiàn)txt數(shù)據(jù)讀入內(nèi)存/CPU緩存實(shí)例詳解的相關(guān)資料,這里對(duì)實(shí)現(xiàn)該函數(shù)進(jìn)行了代碼實(shí)現(xiàn),需要的朋友可以參考下
    2017-01-01
  • C語言main()函數(shù)的參數(shù)問題詳解

    C語言main()函數(shù)的參數(shù)問題詳解

    這篇文章主要為大家詳細(xì)介紹了C語言main()函數(shù)的參數(shù)問題,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02
  • 將CString字符串輸入轉(zhuǎn)化成整數(shù)的實(shí)現(xiàn)方法

    將CString字符串輸入轉(zhuǎn)化成整數(shù)的實(shí)現(xiàn)方法

    下面小編就為大家?guī)硪黄獙String字符串輸入轉(zhuǎn)化成整數(shù)的實(shí)現(xiàn)方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-09-09
  • C 標(biāo)準(zhǔn)I/O庫的粗略實(shí)現(xiàn)教程

    C 標(biāo)準(zhǔn)I/O庫的粗略實(shí)現(xiàn)教程

    下面小編就為大家分享一篇C 標(biāo)準(zhǔn)I/O庫的粗略實(shí)現(xiàn)教程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2017-12-12

最新評(píng)論