日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

相机标定:PNP基于单应面解决多点透视问题

發(fā)布時間:2023/12/31 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 相机标定:PNP基于单应面解决多点透视问题 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

??????? ?????????

??????? 利用二維視野內(nèi)的圖像,求出三維圖像在場景中的位姿,這是一個三維透視投影的反向求解問題。常用方法是PNP方法,需要已知三維點集的原始模型。

??????? 本文做了大量修改,如有不適,請移步原文:? 文章:張正友相機標(biāo)定&OpenCV實現(xiàn)&程序評價&矯正流程解析??? ?

??????? 文章:相機標(biāo)定原理介紹----相機標(biāo)定---

相機模型

????? ? 根據(jù)光學(xué)成像的基本原理,針孔相機在定焦時候有固定的投射關(guān)系,這個投射關(guān)系是相機參數(shù)的大致決定因素。但是對于現(xiàn)實中的相機來說,相機參數(shù)會與理想模型有些偏差,涉及到幾個因素:第一、相機安裝導(dǎo)致光軸不準(zhǔn);第二、使用光學(xué)透鏡導(dǎo)致成像畸變;第三、若實現(xiàn)變焦功能則整個模型參數(shù)都會發(fā)生改變;第四、若是雙目相機,相機安裝導(dǎo)致光軸不平行。

??????? 且對于工業(yè)制品,相機的焦距長度只能精確到其標(biāo)稱值的4%,只有對焦到無窮遠處時相機時焦距長度才是固定的。

??????? 所以直接根據(jù)投射關(guān)系來推算相機參數(shù)幾乎是不準(zhǔn)確的,因此對相機需要參數(shù)進行更細致地描述,由此引發(fā)了相機標(biāo)定過程,使用外在的標(biāo)準(zhǔn)幾何模型,來直接推算相機的內(nèi)部參數(shù)。

??????? 相機標(biāo)定的基本原理仍然是透視法則即小孔成像原理,標(biāo)準(zhǔn)幾何模型一般使用平面點集根據(jù)所謂的單應(yīng)性來推算相機的單應(yīng)矩陣,進而解算出內(nèi)參。

相機標(biāo)定

??????? 可惜了,只標(biāo)定過一次之后便棄之不用,且只是標(biāo)定過一個相機,所以標(biāo)定方法將近生疏。

拿來主義就是方便,直接抄,省得想邏輯完備性!看知乎:機器視覺的相機標(biāo)定到底在標(biāo)定什么?

??????? 所以相機標(biāo)定得到的內(nèi)參僅僅是對相機物理特性的【近似】,這一點有些人可能一輩子都沒辦法意識到。

??????? 傳統(tǒng)相機標(biāo)定假設(shè)相機是小孔成像模型,一般使用兩種畸變來模擬鏡片的物理畸變。但實際相機的物理特性很可能沒辦法通過上述假設(shè)來得到完全的擬合。所以需要意識到,每一次相機標(biāo)定僅僅只是對物理相機模型的一次近似,再具體一點來說,每一次標(biāo)定僅僅是對相機物理模型在采樣空間范圍內(nèi)的一次近似。

??????? 所以當(dāng)成像物體所在的空間跟相機標(biāo)定時的采樣空間不一樣的時候,你可能永遠都沒辦法得到足夠的精度,當(dāng)你大幅改變相機與成像物體的距離的時候,你最好重新標(biāo)定相機。如果你想在一個空間里得到更高的精度,你可以在空間里分層多次標(biāo)定,實際計算的時候通過其他方式得到成像距離,從而選擇合適的標(biāo)定參數(shù)。
??????? 傳統(tǒng)標(biāo)定方法需要相機拍攝一個三維標(biāo)定靶,但仍然估計不出相機畸變。

張正友標(biāo)定法?

???? ? ? ? ? ?
?????? 文章:張正友相機標(biāo)定&OpenCV實現(xiàn)&程序評價&矯正流程解析??? ????
?????? 文章:張正友相機標(biāo)定的原理與實現(xiàn)???????????????
?????? 1999年,微軟研究院的張正友提出了基于移動平面模板的相機標(biāo)定方法。此方法是介于傳統(tǒng)標(biāo)定方法和自標(biāo)定方法之間的一種方法,傳統(tǒng)標(biāo)定方法雖然精度高設(shè)備有較高的要求,其操作過程也比較繁瑣,自標(biāo)定方法的精度不高,張正友標(biāo)定算法克服了這兩者的缺點同時又兼?zhèn)涠叩膬?yōu)點,因此對辦公、家庭的場合使用的桌面視覺系統(tǒng)(DVS)很適合。
?????? 張的文章題目叫做 A Flexible New Technique for Camera Calibration,如果使用高精度的測量儀器制作一個精度極高的參照物,然后把每個點的坐標(biāo)輸入程序進去,這當(dāng)然是可以的,更經(jīng)典的標(biāo)定方法需要制作一個三維的標(biāo)定物體以避免退化的情況,但是這些沒有辦法體現(xiàn)flexible。?????? 標(biāo)定方法使用了立體視覺平面單應(yīng)性的情景,一般圖像標(biāo)定使用三張圖像實現(xiàn)平面就可以,即需要對一個標(biāo)定平面在一個空間位置進行至少三個角度的采樣。


平面單應(yīng)性應(yīng)用
??????
??????? 使用相機從不同角度觀測平面上的點集合,滿足了重建的單應(yīng)性場景。根據(jù)單應(yīng)性的約束,可以求取相機的單應(yīng)矩陣。用于標(biāo)定過程,可以求取相機的本質(zhì)矩陣。
???????
??
約束關(guān)系為:
????



平面的使用

??????? 標(biāo)定方法建議使用標(biāo)定板,保持標(biāo)定板的平面性質(zhì)是重要的。一般方法使用一個工業(yè)標(biāo)準(zhǔn)標(biāo)定板,現(xiàn)階段合適的方法是使用一個LCD顯示器,工業(yè)級的顯示器一般能保證標(biāo)定圖片的平面性。


標(biāo)定輸出
???????? 2. 外參矩陣:現(xiàn)實世界點P( 世界坐標(biāo) )是怎樣經(jīng)過旋轉(zhuǎn)R和平移t,然后落到另一個現(xiàn)實世界點( 攝像機坐標(biāo)系 )上。
? ? ?? ? 1. 內(nèi)參矩陣:點P在2的基礎(chǔ)上,是如何繼續(xù)經(jīng)過攝像機的鏡頭、并通過針孔成像透視變換成為像素點(圖像坐標(biāo)系)。

??? ? ? 3. 畸變矩陣:上面那個像素點并沒有落在理論計算該落在的位置上,還tm產(chǎn)生了一定的偏移和變形!!!

???????? 好了,到這里是不是明白了一點?上述3點的每一個轉(zhuǎn)換,都有已經(jīng)有成熟的數(shù)學(xué)描述,通過計算,我們完全可以精確地重現(xiàn)現(xiàn)實世界的任意一個點到其數(shù)字圖像上對應(yīng)像素點的投影過程。


???????? 對于雙目視覺系統(tǒng),通過立體標(biāo)定還能進一步得到下面的參數(shù):

??????? 4.結(jié)構(gòu)參數(shù)。告訴你右攝像機是怎樣相對于左攝像機經(jīng)過旋轉(zhuǎn)和平移達到現(xiàn)在的位置。通過結(jié)構(gòu)參數(shù),便能把左右攝像機獲取的圖像的每一個像素點之間的關(guān)系用數(shù)學(xué)語言定量描述,保證兩個相機都處于我們“可求”的狀態(tài)。


標(biāo)定流程

?????? 標(biāo)定流程按照這張圖里面的原理

??????

?????? ????? 文章:張正友相機標(biāo)定的原理與實現(xiàn)????????????

標(biāo)定程序的完整流程:

? ? 1、準(zhǔn)備輸入棋盤格圖片:對一個標(biāo)定板在不同位置、不同角度、不同姿態(tài)下拍攝,至少三張。一般使用黑白棋盤格。 ???

??? 2、對棋盤格圖片,提取角點信息:對棋盤格圖像檢測角點,使用findChessboardCorners檢測函數(shù),專門檢測棋盤格內(nèi)角點。

??? 3、進行再次計算,提取亞像素級角點信息:提高精度,使用亞像素級角點尋找方法。

??? 4、對相機進行標(biāo)定-使用標(biāo)定流程:使用啟動標(biāo)定流程,可是直接使用OpenCV的calibrateCamera函數(shù),輸出內(nèi)參外參........................................

? ? 5、對標(biāo)定結(jié)果進行評價

??? 6、查看標(biāo)定結(jié)果,利用標(biāo)定結(jié)果對棋盤格圖進行矯正


標(biāo)定的具體流程是:

??? 1)把被取的十個點的世界坐標(biāo)(齊次坐標(biāo))進行轉(zhuǎn)置。

??? 2)對單應(yīng)性矩陣求解并優(yōu)化。

??? 3)把六幅圖的單應(yīng)矩陣求解出來后求解出6向量(B矩陣)。因為每個單應(yīng)矩陣可以得到兩個方程,通過循環(huán)對矩陣y 賦值后,再對y進行正交分解即可得到6向量。進而得到相機的內(nèi)參矩陣。

??? 4)先求解出相機的外參,然后對畸變系數(shù)進行求解,得到相機坐標(biāo)(Xc, Yc, Zc)。

??? 5)調(diào)用函數(shù)對內(nèi)參和畸變系數(shù)進行優(yōu)化,并顯示優(yōu)化后的結(jié)果。然后根據(jù)優(yōu)化后的結(jié)果求解外參矩陣。

??? 6)從旋轉(zhuǎn)矩陣中分解出獨立變量(三個坐標(biāo)的轉(zhuǎn)角),再得到平移矩陣,最后把它們和內(nèi)參、畸變系數(shù)一起優(yōu)化進行最終優(yōu)化。


?OpenCV代碼:

#include "opencv2/core/core.hpp" #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/calib3d/calib3d.hpp" #include "opencv2/highgui/highgui.hpp" #include <iostream> #include <fstream> using namespace cv;using namespace std;double coff = 0.0;ifstream fin("calibdata.txt"); /* 標(biāo)定所用圖像文件的路徑 */ofstream fout("caliberation_result.txt"); /* 保存標(biāo)定結(jié)果的文件 *///讀取每一幅圖像,從中提取出角點,然后對角點進行亞像素精確化 cout << "開始提取角點………………";int image_count = 0; /* 圖像數(shù)量 */Size image_size; /* 圖像的尺寸 */Size board_size = Size(4, 6); /* 標(biāo)定板上每行、列的角點數(shù) */std::vector<Point2f> image_points_buf; /* 緩存每幅圖像上檢測到的角點 */std::vector<std::vector<Point2f>> image_points_seq; /* 保存檢測到的所有角點 */string filename;int count = -1;//用于存儲角點個數(shù)。 while (getline(fin, filename)){image_count++;// 用于觀察檢驗輸出 cout << "image_count = " << image_count << endl;/* 輸出檢驗*/cout << "-->count = " << count;cv::Mat imageInput = imread(filename);if (image_count == 1) //讀入第一張圖片時獲取圖像寬高信息 {image_size.width = imageInput.cols;image_size.height = imageInput.rows;cout << "image_size.width = " << image_size.width << endl;cout << "image_size.height = " << image_size.height << endl;}/* 提取角點 */if (0 == findChessboardCorners(imageInput, board_size, image_points_buf)){cout << "can not find chessboard corners!\n"; //找不到角點 exit(1);}else{cv::Mat view_gray;cvtColor(imageInput, view_gray, CV_RGB2GRAY);/* 亞像素精確化 */find4QuadCornerSubpix(view_gray, image_points_buf, Size(5, 5)); //對粗提取的角點進行精確化 //cornerSubPix(view_gray,image_points_buf,Size(5,5),Size(-1,-1),TermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER,30,0.1)); image_points_seq.push_back(image_points_buf); //保存亞像素角點 /* 在圖像上顯示角點位置 */drawChessboardCorners(view_gray, board_size, image_points_buf, false); //用于在圖片中標(biāo)記角點 imshow("Camera Calibration", view_gray);//顯示圖片 waitKey(500);//暫停0.5S }}int total = image_points_seq.size();cout << "total = " << total << endl;int CornerNum = board_size.width*board_size.height; //每張圖片上總的角點數(shù) for (int ii = 0; ii < total; ii++){if (0 == ii%CornerNum)// 24 是每幅圖片的角點個數(shù)。此判斷語句是為了輸出 圖片號,便于控制臺觀看 {int i = -1;i = ii / CornerNum;int j = i + 1;cout << "--> 第 " << j << "圖片的數(shù)據(jù) --> : " << endl;}if (0 == ii % 3) // 此判斷語句,格式化輸出,便于控制臺查看 {cout << endl;}else{cout.width(10);}//輸出所有的角點 cout << " -->" << image_points_seq[ii][0].x;cout << " -->" << image_points_seq[ii][0].y;}cout << "角點提取完成!\n";//以下是攝像機標(biāo)定 cout << "開始標(biāo)定………………";/*棋盤三維信息*/Size square_size = Size(10, 10); /* 實際測量得到的標(biāo)定板上每個棋盤格的大小 */std::vector<std::vector<Point3f>> object_points; /* 保存標(biāo)定板上角點的三維坐標(biāo) *//*內(nèi)外參數(shù)*/cv::Mat cameraMatrix = cv::Mat(3, 3, CV_32FC1, Scalar::all(0)); /* 攝像機內(nèi)參數(shù)矩陣 */std::vector<int> point_counts; // 每幅圖像中角點的數(shù)量 cv::Mat distCoeffs = cv::Mat(1, 5, CV_32FC1, Scalar::all(0)); /* 攝像機的5個畸變系數(shù):k1,k2,p1,p2,k3 */std::vector<cv::Mat> tvecsMat; /* 每幅圖像的旋轉(zhuǎn)向量 */std::vector<cv::Mat> rvecsMat; /* 每幅圖像的平移向量 *//* 初始化標(biāo)定板上角點的三維坐標(biāo) */int i, j, t;for (t = 0; t < image_count; t++){std::vector<Point3f> tempPointSet;for (i = 0; i < board_size.height; i++){for (j = 0; j < board_size.width; j++){Point3f realPoint;/* 假設(shè)標(biāo)定板放在世界坐標(biāo)系中z=0的平面上 */realPoint.x = i*square_size.width;realPoint.y = j*square_size.height;realPoint.z = 0;tempPointSet.push_back(realPoint);}}object_points.push_back(tempPointSet);}/* 初始化每幅圖像中的角點數(shù)量,假定每幅圖像中都可以看到完整的標(biāo)定板 */for (i = 0; i < image_count; i++){point_counts.push_back(board_size.width*board_size.height);}/* 開始標(biāo)定 */calibrateCamera(object_points, image_points_seq, image_size, cameraMatrix, distCoeffs, rvecsMat, tvecsMat, 0);cout << "標(biāo)定完成!\n";//對標(biāo)定結(jié)果進行評價 cout << "開始評價標(biāo)定結(jié)果………………\n";double total_err = 0.0; /* 所有圖像的平均誤差的總和 */double err = 0.0; /* 每幅圖像的平均誤差 */std::vector<Point2f> image_points2; /* 保存重新計算得到的投影點 */cout << "\t每幅圖像的標(biāo)定誤差:\n";fout << "每幅圖像的標(biāo)定誤差:\n";for (i = 0; i < image_count; i++){std::vector<Point3f> tempPointSet = object_points[i];/* 通過得到的攝像機內(nèi)外參數(shù),對空間的三維點進行重新投影計算,得到新的投影點 */projectPoints(tempPointSet, rvecsMat[i], tvecsMat[i], cameraMatrix, distCoeffs, image_points2);/* 計算新的投影點和舊的投影點之間的誤差*/std::vector<Point2f> tempImagePoint = image_points_seq[i];cv::Mat tempImagePointMat = cv::Mat(1, tempImagePoint.size(), CV_32FC2);cv::Mat image_points2Mat = cv::Mat(1, image_points2.size(), CV_32FC2);for (int j = 0; j < tempImagePoint.size(); j++){image_points2Mat.at<Vec2f>(0, j) = Vec2f(image_points2[j].x, image_points2[j].y);tempImagePointMat.at<Vec2f>(0, j) = Vec2f(tempImagePoint[j].x, tempImagePoint[j].y);}err = norm(image_points2Mat, tempImagePointMat, NORM_L2);total_err += err /= point_counts[i];std::cout << "第" << i + 1 << "幅圖像的平均誤差:" << err << "像素" << endl;fout << "第" << i + 1 << "幅圖像的平均誤差:" << err << "像素" << endl;}std::cout << "總體平均誤差:" << total_err / image_count << "像素" << endl;fout << "總體平均誤差:" << total_err / image_count << "像素" << endl << endl;std::cout << "評價完成!" << endl;//保存定標(biāo)結(jié)果 std::cout << "開始保存定標(biāo)結(jié)果………………" << endl;cv::Mat rotation_Matrix = cv::Mat(3, 3, CV_32FC1, Scalar::all(0)); /* 保存每幅圖像的旋轉(zhuǎn)矩陣 */fout << "相機內(nèi)參數(shù)矩陣:" << endl;fout << cameraMatrix << endl << endl;fout << "畸變系數(shù):\n";fout << distCoeffs << endl << endl << endl;for (int i = 0; i < image_count; i++){fout << "第" << i + 1 << "幅圖像的旋轉(zhuǎn)向量:" << endl;fout << tvecsMat[i] << endl;/* 將旋轉(zhuǎn)向量轉(zhuǎn)換為相對應(yīng)的旋轉(zhuǎn)矩陣 */Rodrigues(tvecsMat[i], rotation_cv::Matrix);fout << "第" << i + 1 << "幅圖像的旋轉(zhuǎn)矩陣:" << endl;fout << rotation_Matrix << endl;fout << "第" << i + 1 << "幅圖像的平移向量:" << endl;fout << rvecsMat[i] << endl << endl;}std::cout << "完成保存" << endl;fout << endl;/************************************************************************顯示定標(biāo)結(jié)果*************************************************************************/cv::Mat mapx = cv::Mat(image_size, CV_32FC1);cv::Mat mapy = cv::Mat(image_size, CV_32FC1);cv::Mat R = cv::Mat::eye(3, 3, CV_32F);std::cout << "保存矯正圖像" << endl;string imageFileName;std::stringstream StrStm;for (int i = 0; i != image_count; i++){std::cout << "Frame #" << i + 1 << "..." << endl;initUndistortRectifyMap(cameraMatrix, distCoeffs, R, cameraMatrix, image_size, CV_32FC1, mapx, mapy);StrStm.clear();imageFileName.clear();string filePath = "chess";StrStm << i + 1;StrStm >> imageFileName;filePath += imageFileName;filePath += ".bmp";cv::Mat imageSource = imread(filePath);cv::Mat newimage = imageSource.clone();//另一種不需要轉(zhuǎn)換矩陣的方式 //undistort(imageSource,newimage,cameracv::Matrix,distCoeffs); remap(imageSource, newimage, mapx, mapy, INTER_LINEAR);StrStm.clear();filePath.clear();StrStm << i + 1;StrStm >> imageFileName;imageFileName += "_d.jpg";imwrite(imageFileName, newimage);}std::cout << "保存結(jié)束" << endl;return coff;}

后記

?????? 相機標(biāo)定其實是一個體力活,所以標(biāo)定一次之后幾乎再也沒有自行標(biāo)定過..............................

?????? 此后,建議使用平板電腦,不過大多數(shù)平板電腦不適特別的平。

總結(jié)

以上是生活随笔為你收集整理的相机标定:PNP基于单应面解决多点透视问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 人体私拍套图hdxxxx | www国产亚洲精品久久网站 | 亚洲狼人综合 | 新婚若妻侵犯中文字幕 | 九九视频精品在线 | 强行糟蹋人妻hd中文 | 欧美 日韩 人妻 高清 中文 | 少妇一级淫免费观看 | 少妇搡bbbb搡bbb搡打电话 | 色乱码一区二区三区熟女 | 色七七桃花影院 | 天天拍夜夜爽 | 好男人在线观看 | 色婷婷aⅴ | 国产欧美精品一区二区色综合朱莉 | 中文字幕被公侵犯的漂亮人妻 | 爱爱视频免费看 | 色视频2| 综合色婷婷| 亚洲视频456 | 免费极品av一视觉盛宴 | 在线免费观看视频你懂的 | 美女性高潮视频 | 久久99成人| 午夜视频免费观看 | 国产剧情精品 | 手机免费在线观看av | 亚洲九九九九 | 永久国产| 中出少妇 | 人妻一区二区三区视频 | 91久久电影 | 国产亚洲欧美精品久久久久久 | 美女被到爽高潮视频 | 91午夜在线 | 男人捅爽女人 | 国产又黄又骚 | 麻豆免费观看网站 | 日本大尺度做爰呻吟舌吻 | 97视频精品| 成人a在线观看 | 超碰在线a | 亚洲17p| 97超碰在线播放 | 国产伦精品视频一区二区三区 | 封神榜二在线高清免费观看 | 久久久久久久久久久av | 久久久老熟女一区二区三区91 | 日韩亚州 | 亚洲综合自拍偷拍 | 操久久久 | 免费黄网站在线看 | 婷婷在线一区 | 上海毛片 | 卡通动漫精品一区二区三区 | 草草影院在线观看 | 亚洲激情成人网 | 一区二区三区资源 | 理论黄色片 | 中国女人内谢69xxxx | 久久久天堂国产精品女人 | 国产一区二区三区影视 | 欧美在线视频一区二区三区 | 日本一区二区三区成人 | 精品理论片 | 天天尻逼 | 国产乱码视频 | wwwxx国产 | 可以看的黄色网 | 国产美女久久 | 欧美三级视频在线播放 | 狠狠操导航 | 成人欧美视频 | 国产精品久久久久久久久久小说 | 成人tv| 国产乱码精品一区二区三区中文 | 韩日产理伦片在线观看 | 伊人逼逼| 视频久久精品 | 琪琪色av | 色综合久久五月 | 亚洲男人在线天堂 | 夜久久久 | 国产成人精品123区免费视频 | 在线免费观看高清视频 | 黄网站免费在线 | 国产av无码专区亚洲av麻豆 | 在线免费av网址 | 国产无遮掩 | 亚洲国产精品久久 | 嫩草视频网站 | 免费国产黄色 | 毛片毛片毛片毛片毛片毛片毛片毛片 | 亚洲精品视频一区二区 | 国家队动漫免费观看在线观看晨光 | 一区二区视频免费在线观看 | 日韩在线观看 | 亚洲第一偷拍 | 寡妇一级片 |