当前位置:网站首页>Day9 of Hegong Daqiong team vision team training - camera calibration
Day9 of Hegong Daqiong team vision team training - camera calibration
2022-08-05 06:56:00 【The Electricity Department of the University of Technology】
目录
四、用cv::undistortmethod to remove distortion
学习目标:
- pnp解算
- 相机标定
- 去畸变
学习内容:
Calibrate a camera directly with the camera of the computer,Use after calibrationcv::undistortmethod to remove camera distortion.
学习时间:
- 2022年8月1日到2022年8月4日
学习产出:
一、前期准备
Long story short this time,网上相关资料很多,可以参考https://blog.csdn.net/LuohenYJ/article/details/104697062
I use the calibration board
可以去这个网站:Camera Calibration Pattern Generator – calib.io去生成
The camera is the camera of the computer.
二、采集相关数据
#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;
// Save multiple image object point lists
vector<vector<Point3f>> objectPoints;
// Save a list of corner points for multiple images
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);
// Get image pixel dimensions
imgSize = img.size();
std::cout << "name: " << imgName<< " imgSize: " << imgSize << std::endl;
//...
}
return 0;
}
//查找角点//
// The size of the checkerboard(宽6,高9)
const Size patternSize(6, 9);
// size of black square 20mm
const int squareSize = 20;
/**
* Find corners in the specified image,并将结果输出到corners中
* @param img 待检测图片
* @param corners Detected focus list
* @return Whether to detect corners(The intersection of two black squares)
*/
bool findCorners(Mat &img, vector<Point2f> &corners) {
Mat gray;
// 将图片转成灰度图
cvtColor(img, gray, COLOR_RGB2GRAY);
// Find all corners of the current image
bool patternWasFound = findChessboardCorners(gray, patternSize, corners);
if (patternWasFound) { // 找到角点
// Improve the accuracy of corner points
// 原理: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));
}
// Draw all the focal points in the original image
drawChessboardCorners(img, patternSize, corners, patternWasFound);
// After drawing the corners,显示原图
imshow("src", img);
if (!patternWasFound){
cout << "Corner detection failed!" << endl;
}
return patternWasFound;
}
// Save multiple image object point lists
vector<vector<Point3f>> objectPoints;
// Save a list of corner points for multiple images
vector<vector<Point2f>> cornerPoints;
void calcObjectPoints(vector<Point3f> &objPoint) {
// 计算uvThe coordinate value of the camera coordinate system corresponding to the corner point in the space,设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);
// Get image pixel dimensions
imgSize = img.size();
std::cout << "name: " << imgName<< " imgSize: " << imgSize << std::endl;
// Declare the corners of each image
vector<Point2f> corners;
bool found = findCorners(img, corners);
if (found) {
vector<Point3f> objPoints;
calcObjectPoints(objPoints);
// 找到角点,Prove that this graph is valid
objectPoints.push_back(objPoints);
cornerPoints.push_back(corners);
}
}
return 0;
}
//Perform camera calibration//
Mat cameraMatrix; // 相机参数矩阵
Mat disCoffes; // 失真系数 distortion coefficients
Mat rvecs; // Image rotation vector
Mat tvecs; // Image translation vector
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();
}
//I finally outputyml文件,也可以是xml文件格式//
四、用cv::undistortmethod to remove distortion
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc.hpp>
using namespace cv;
using namespace std;
int main(int argc, char **argv) {
// Read the camera matrix、畸变系数
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:代码仅供参考.
五、效果
六、心得
I don't think it's very good,Many things still need to be improved,Let me learn more and update later.
边栏推荐
猜你喜欢
浮点数基础知识
LaTeX image captioning text column automatic line wrapping
typescript65-映射类型(keyof)
typescript63-索引签名类型
Japan Sanitary Equipment Industry Association: Japan's warm water shower toilet seat shipments reached 100 million sets
txt文件英语单词词频统计
golang-条件语句
typescript62-泛型工具类型(record)
numpy.random usage documentation
Drools规则引擎快速入门(一)
随机推荐
无法导入torchvision.io.read_image
Promise (三) async/await
花花省V5淘宝客APP源码无加密社交电商自营商城系统带抖音接口
【C语言】结构体变量数据通过 void* 传入到函数中
UI刘海屏适配方式
前置++和后置++的区别
《PyTorch深度学习实践》第十一课(卷积神经网络CNN高级版)
lingo入门——河北省第三届研究生建模竞赛B题
【Go】IM系统Centrifugo
文件内音频的时长统计并生成csv文件
ndk编译so库
边缘盒子+时序数据库,美的数字化平台 iBUILDING 背后的技术选型
numpy.random usage documentation
武田公司2022财年第一季度业绩强劲;正稳步实现全年的管理层指引目标
(2022杭电多校六)1012-Loop(单调栈+思维)
2022杭电多校六 1007-Shinobu loves trip(同余方程)
Pytorch distributed parallel processing
export使用
The 25 best free games on mobile in 2020
【2022 DSCTF决赛wp】