• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            魚眼相機(jī)標(biāo)定以及OpenCV實(shí)現(xiàn)


            在另一篇文章中我已經(jīng)寫過(guò)有關(guān)普通相機(jī)模型及其OpenCV標(biāo)定實(shí)現(xiàn),這篇文章將主要關(guān)注魚眼相機(jī)模型及其OpenCV標(biāo)定實(shí)現(xiàn)。 
            先看一張魚眼相機(jī)拍攝出來(lái)的結(jié)果:

            這里寫圖片描述

            從圖中可以看出很明顯的畸變。對(duì)魚眼相機(jī)標(biāo)定,有時(shí)候也可以用普通相機(jī)的標(biāo)定方法對(duì)其進(jìn)行標(biāo)定,但是卻不能保證去畸變后的效果是最好的。因此對(duì)于Gopro等魚眼鏡頭拍攝出來(lái)的圖像去畸變,最好的方法就是采用魚眼相機(jī)標(biāo)定方法進(jìn)行標(biāo)定。

            魚眼相機(jī)模型

            魚眼相機(jī)的內(nèi)參模型依然可以表示為: 

            fx000fy0cxcy1

            這與普通鏡頭的成像模型沒有區(qū)別。兩者之間的區(qū)別主要體現(xiàn)在畸變系數(shù),魚眼相機(jī)的畸變系數(shù)為{k1,k2,k3,k4},畸變系數(shù)不同,就導(dǎo)致魚眼相機(jī)的投影關(guān)系也發(fā)生了變化,主要變化發(fā)生在考慮畸變情況下的投影關(guān)系轉(zhuǎn)化: 
            設(shè)(X,Y,Z)為空間中一個(gè)三維點(diǎn),它在成像平面內(nèi)的成像坐標(biāo)為(u,v),在考慮畸變的情況下, 
            xcyczc=RXYZ+T

            a=xc/zc,b=yc/zc 
            r2=a2+b2 
            θ=atan(r) 
            θ=θ(1+k1θ2+k2θ4+k3θ6+k4θ8) 
            x=(θ/r)xc 
            y=(θ/r)yc 
            u=fxx+cx 
            v=fyy+cy

            OpenCV實(shí)現(xiàn)魚眼相機(jī)標(biāo)定

            利用opencv實(shí)現(xiàn)魚眼相機(jī)的標(biāo)定和普通相機(jī)標(biāo)定的標(biāo)定流程基本一致,具體流程如下:

            1. 檢測(cè)角點(diǎn) 
              cv::findChessboardCorners(InputArray image, Size patternSize, OutputArray corners, int 
              flags=CALIB_CB_ADAPTIVE_THRESH+CALIB_CB_NORMALIZE_IMAGE}
               
              獲得棋盤標(biāo)定板的角點(diǎn)位置,使用 
              cornerSubPix(InputArray image, InputOutputArray corners, Size winSize, Size zeroZone, 
              TermCriteria criteria)
              獲取角點(diǎn)更精細(xì)的檢測(cè)結(jié)果
            2. 初始化標(biāo)定板上角點(diǎn)的三維坐標(biāo)
            3. 開始標(biāo)定 
              double fisheye::calibrate(InputArrayOfArrays objectPoints, InputArrayOfArrays imagePoints, 
              const Size& image_size, InputOutputArray K, InputOutputArray D, 
              OutputArrayOfArrays rvecs, OutputArrayOfArrays tvecs, int flags=0, 
              TermCriteria criteria=TermCriteria(TermCriteria::COUNT + TermCriteria:: 
              EPS, 100, DBL_EPSILON))
               
              注意:K,D 分別表示內(nèi)參矩陣和畸變系數(shù)向量,在定義時(shí)要定義為double型,這里推薦使用Matx33d和Vec4d數(shù)據(jù)類型,更為方便簡(jiǎn)單。objectPoints,imagePoints可以是float型,也可以是double型,但是再stereorectify中需要時(shí)double型。flags的可選項(xiàng)有很多,其中需要注意的是必須要指定CALIB_FIX_SKEW,代表求解時(shí)假設(shè)內(nèi)參中fx=fy
              4.評(píng)定誤差(可選項(xiàng))

                  for (int i = 0; i != image_count; i++)
                  {
                      cout << "Frame #" << i + 1 << "..." << endl;
                      string image_Name;
                      stringstream stream;
                      stream << (i + startNum);
                      stream >> image_Name;
                      image_Name = path_ChessboardImage + image_Name + ".jpg";
                      cv::Mat image = imread(image_Name);
                      Mat image_gray;
                      cvtColor(image, image_gray, CV_RGB2GRAY);
                      vector<Point2f> corners;                   
                      bool patternFound = findChessboardCorners(image_gray, board_size, corners,
                          CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE + CALIB_CB_FAST_CHECK);
                      if (!patternFound || fullcornersNum != corners.size())
                      {
                          cout << "can not find chessboard corners!\n";
                          continue;
                      }
                      else
                      {
                          cornerSubPix(image_gray, corners, Size(11, 11), Size(-1, -1), TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1));
                          count = count + corners.size();
                          corners_Seq.push_back(corners);
                          successImageNum = successImageNum + 1;
                          image_Seq.push_back(image);
                      }
                  }
                  /************************************************************************
                  攝像機(jī)定標(biāo)
                  *************************************************************************/
                  vector<vector<Point3f>>  object_Points;        /****  保存定標(biāo)板上角點(diǎn)的三維坐標(biāo)   ****/

                  Mat image_points = Mat(1, count, CV_32FC2, Scalar::all(0));  /*****   保存提取的所有角點(diǎn)   *****/
                  vector<int>  point_counts;                                                         
                  /* 初始化定標(biāo)板上角點(diǎn)的三維坐標(biāo) */
                  for (int t = 0; t<successImageNum; t++)
                  {
                      vector<Point3f> tempPointSet;
                      for (int i = 0; i<board_size.height; i++)
                      {
                          for (int j = 0; j<board_size.width; j++)
                          {
                              /* 假設(shè)定標(biāo)板放在世界坐標(biāo)系中z=0的平面上 */
                              Point3f tempPoint;
                              tempPoint.x = i*square_size.width;
                              tempPoint.y = j*square_size.height;
                              tempPoint.z = 0;
                              tempPointSet.push_back(tempPoint);
                          }
                      }
                      object_Points.push_back(tempPointSet);
                  }
                  for (int i = 0; i< successImageNum; i++)
                  {
                      point_counts.push_back(board_size.width*board_size.height);
                  }
                  /* 開始定標(biāo) */
                  Size image_size = image_Seq[0].size();
                  cv::Matx33d intrinsic_matrix;    /*****    攝像機(jī)內(nèi)參數(shù)矩陣    ****/
                  cv::Vec4d distortion_coeffs;     /* 攝像機(jī)的4個(gè)畸變系數(shù):k1,k2,k3,k4*/
                  std::vector<cv::Vec3d> rotation_vectors;                           /* 每幅圖像的旋轉(zhuǎn)向量 */
                  std::vector<cv::Vec3d> translation_vectors;                        /* 每幅圖像的平移向量 */
                  int flags = 0;
                  flags |= cv::fisheye::CALIB_RECOMPUTE_EXTRINSIC;
                  flags |= cv::fisheye::CALIB_CHECK_COND;
                  flags |= cv::fisheye::CALIB_FIX_SKEW;
                  fisheye::calibrate(object_Points, corners_Seq, image_size, intrinsic_matrix, distortion_coeffs, rotation_vectors, translation_vectors, flags, cv::TermCriteria(3, 20, 1e-6));

              標(biāo)定結(jié)果: 
              這里寫圖片描述


            posted on 2017-11-16 09:55 zmj 閱讀(3047) 評(píng)論(0)  編輯 收藏 引用


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            99久久精品国产毛片| 久久午夜无码鲁丝片秋霞 | 无码日韩人妻精品久久蜜桃| 热99RE久久精品这里都是精品免费 | 久久久久人妻一区二区三区vr | 国产精品九九久久免费视频| 精品久久久久久无码中文字幕| 久久精品国产亚洲7777| 看全色黄大色大片免费久久久| 精品久久久久久中文字幕大豆网| 久久综合狠狠综合久久综合88 | 久久午夜电影网| 久久久久久无码国产精品中文字幕| 伊人久久大香线蕉精品不卡| 久久精品aⅴ无码中文字字幕重口| 亚洲一本综合久久| 伊人色综合久久天天网| 久久亚洲精品成人AV| 国产毛片久久久久久国产毛片| 久久精品免费全国观看国产| 久久久久久久久无码精品亚洲日韩| 91精品国产色综久久 | 久久er国产精品免费观看2| 精品无码人妻久久久久久| 人妻无码精品久久亚瑟影视| 国内精品久久国产大陆| 日产久久强奸免费的看| 久久综合狠狠综合久久综合88| 国产亚洲精久久久久久无码AV| 久久久精品国产免大香伊| 久久综合中文字幕| 久久精品中文无码资源站| 7国产欧美日韩综合天堂中文久久久久| 国产99久久久国产精品小说 | 日本WV一本一道久久香蕉| 久久免费小视频| 中文字幕人妻色偷偷久久| 久久精品不卡| 国产精品久久久久久久| 久久中文字幕人妻丝袜| 国内精品久久久久久麻豆|