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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

合工大苍穹战队视觉组培训Day9——相机标定

發布時間:2023/12/15 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 合工大苍穹战队视觉组培训Day9——相机标定 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

學習目標:

學習內容:

學習時間:

學習產出:

一、前期準備

二、采集相關數據

三、進行標定

四、用cv::undistort方法去除畸變

五、效果

?六、心得


學習目標:

  • pnp解算
  • 相機標定
  • 去畸變

學習內容:

? ? ? ? ?直接用電腦的攝像頭標定一個相機,標定完后使用cv::undistort方法去除相機的畸變。

學習時間:

  • 2022年8月1日到2022年8月4日

學習產出:

一、前期準備

這次長話短說吧,網上相關資料很多,可以參考https://blog.csdn.net/LuohenYJ/article/details/104697062

標定板我用的

可以去這個網站:Camera Calibration Pattern Generator – calib.io去生成

攝像頭是電腦的攝像頭。

二、采集相關數據

#include "opencv2/opencv.hpp" #include <string> #include <iostream>using namespace cv; using namespace std;int main() {VideoCapture inputVideo(0);//inputVideo.set(CV_CAP_PROP_FRAME_WIDTH, 320);//inputVideo.set(CV_CAP_PROP_FRAME_HEIGHT, 240);if (!inputVideo.isOpened()){cout << "Could not open the input video " << endl;return -1;}Mat frame;string imgname;int f = 1;while (1) //Show the image captured in the window and repeat{inputVideo >> frame; // readif (frame.empty()) break; // check if at endimshow("Camera", frame);char key = waitKey(1);if (key == 27)break;if (key == 'q' || key == 'Q'){imgname = to_string(f++) + ".jpg";imwrite(imgname, frame);}}cout << "Finished writing" << endl;return 0; }

三、進行標定

//加載圖片// #include <iostream> #include <opencv2/opencv.hpp>using namespace std; using namespace cv;// 保存多張圖片對象點列表 vector<vector<Point3f>> objectPoints; // 保存多張圖片的角點列表 vector<vector<Point2f>> cornerPoints;int main(){// 圖片像素尺寸Size imgSize;// 圖片路徑cv::String src_path = "./assets/camerargb_*.jpg";std::vector<String> filenames;cv::glob(src_path, filenames);//獲取路徑下所有文件名cout << "filenames.size:" << filenames.size() << endl;for (auto& imgName : filenames) {// 讀取圖片Mat img = imread(imgName, IMREAD_COLOR);// 獲取圖片像素尺寸imgSize = img.size();std::cout << "name: " << imgName<< " imgSize: " << imgSize << std::endl;//...}return 0; }//查找角點// // 棋盤格的尺寸(寬6,高9) const Size patternSize(6, 9); // 黑方格的大小 20mm const int squareSize = 20; /*** 在指定圖片中查找角點,并將結果輸出到corners中* @param img 待檢測圖片* @param corners 檢測到的焦點列表* @return 是否檢測到角點(兩個黑方格的交點)*/ bool findCorners(Mat &img, vector<Point2f> &corners) {Mat gray;// 將圖片轉成灰度圖cvtColor(img, gray, COLOR_RGB2GRAY);// 查找當前圖片所有的角點bool patternWasFound = findChessboardCorners(gray, patternSize, corners);if (patternWasFound) { // 找到角點// 提高角點的精確度// 原理:https://docs.opencv.org/4.1.0/dd/d1a/group__imgproc__feature.html#ga354e0d7c86d0d9da75de9b9701a9a87ecornerSubPix(gray, corners, Size(11, 11), Size(-1, -1),TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 30, 0.1));}// 將所有的焦點在原圖中繪制出來drawChessboardCorners(img, patternSize, corners, patternWasFound);// 繪制完角點之后,顯示原圖imshow("src", img);if (!patternWasFound){cout << "角點檢測失敗!" << endl;}return patternWasFound; }// 保存多張圖片對象點列表 vector<vector<Point3f>> objectPoints; // 保存多張圖片的角點列表 vector<vector<Point2f>> cornerPoints;void calcObjectPoints(vector<Point3f> &objPoint) {// 計算uv空間中角點對應的相機坐標系坐標值,設Z為0for (int i = 0; i < patternSize.height; ++i)for (int j = 0; j < patternSize.width; ++j)objPoint.emplace_back(j * squareSize, i * squareSize, 0); }// 圖片像素尺寸 Size imgSize;int main(){// 圖片路徑cv::String src_path = "./assets/camerargb_*.jpg";std::vector<String> filenames;cv::glob(src_path, filenames);//獲取路徑下所有文件名cout << "filenames.size:" << filenames.size() << endl;for (auto& imgName : filenames) {// 讀取圖片Mat img = imread(imgName, IMREAD_COLOR);// 獲取圖片像素尺寸imgSize = img.size();std::cout << "name: " << imgName<< " imgSize: " << imgSize << std::endl;// 聲明每張圖片的角點vector<Point2f> corners;bool found = findCorners(img, corners);if (found) {vector<Point3f> objPoints;calcObjectPoints(objPoints);// 找到角點,證明這張圖是有效的objectPoints.push_back(objPoints);cornerPoints.push_back(corners);}}return 0; }//執行相機標定// Mat cameraMatrix; // 相機參數矩陣 Mat disCoffes; // 失真系數 distortion coefficients Mat rvecs; // 圖片旋轉向量 Mat tvecs; // 圖片平移向量calibrateCamera(objectPoints, cornerPoints, imgSize, cameraMatrix, disCoffes, rvecs, tvecs);cout << "標定矩陣:" << cameraMatrix << endl; cout << "畸變矩陣:" << disCoffes << endl; // save2xml(cameraMatrix, distCoffes);waitKey();//保存標定結果// void save2xml(const Mat &cameraMatrix, const Mat &disCoffes) {// 獲取當前時間time_t tm;time(&tm);struct tm *t2 = localtime(&tm);char buf[1024];strftime(buf, sizeof(buf), "%c", t2);// 寫出數據String inCailFilePath = "./inCailFilePath.xml";FileStorage inCailFs(inCailFilePath, FileStorage::WRITE);inCailFs << "calibration_time" << buf;inCailFs << "cameraMatrix" << cameraMatrix;inCailFs << "distCoffes" << disCoffes;inCailFs.release(); }//我最后輸出了yml文件,也可以是xml文件格式//

四、用cv::undistort方法去除畸變

#include <iostream> #include <opencv2/opencv.hpp> #include <opencv2/imgproc.hpp>using namespace cv; using namespace std;int main(int argc, char **argv) {// 讀取相機矩陣、畸變系數cv::FileStorage fs("你的yml文件", FileStorage::READ);int image_width{0}, image_height{0};fs["image_width"] >> image_width;fs["image_height"] >> image_height;Size image_size = Size(image_width, image_height);Mat intrinsic_matrix, distortion_coeffs;fs["cameraMatrix"] >> intrinsic_matrix;fs["distCoeffs"] >> distortion_coeffs;fs.release();std::cout << intrinsic_matrix << std::endl;std::cout << distortion_coeffs << std::endl;std::cout << image_size << std::endl;const Mat &image0 = imread("./calib_chess_img/image_0.jpg", IMREAD_COLOR);Mat image;undistort(image0, image, intrinsic_matrix, distortion_coeffs);imshow("original", image0);imshow("undistorted", image);waitKey();return 0; }

PS:代碼僅供參考。

五、效果

?六、心得

我覺得做的不是很好很對,很多東西還是得進一步弄好,等我多學點再后續更新吧。

總結

以上是生活随笔為你收集整理的合工大苍穹战队视觉组培训Day9——相机标定的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。