当前位置:网站首页>合工大苍穹战队视觉组培训Day9——相机标定
合工大苍穹战队视觉组培训Day9——相机标定
2022-08-05 05:59:00 【工大电科小趴菜】
目录
学习目标:
- 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; // read
if (frame.empty()) break; // check if at end
imshow("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#ga354e0d7c86d0d9da75de9b9701a9a87e
cornerSubPix(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为0
for (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:代码仅供参考。
五、效果
六、心得
我觉得做的不是很好很对,很多东西还是得进一步弄好,等我多学点再后续更新吧。
边栏推荐
猜你喜欢
随机推荐
Source code analysis of Nacos configuration service (full)
字体样式及其分类
获取预训练模型的网络输入尺寸
Email management Filter emails
前置++和后置++的区别
Q 2020, the latest senior interview Laya soul, do you know?
Drools规则引擎快速入门(一)
D39_Eulerian Angles and Quaternions
Tencent Internal Technology: Evolution of Server Architecture of "The Legend of Xuanyuan"
The use of three parameters of ref, out, and Params in Unity3D
Pytorch distributed parallel processing
GetEnumerator method and MoveNext and Reset methods in Unity
The future of cloud gaming
【FAQ】What is Canon CCAPI
Get the network input dimensions of the pretrained model
亚马逊美国站:马术头盔CPC认证标准要求
深入分析若依数据权限@datascope (注解+AOP+动态sql拼接) 【循序渐进,附分析过程】
LaTeX uses frame to make PPT pictures without labels
D39_ coordinate transformation
技术分析模式(七)发挥差距