OpenCV之相机畸变矫正

更新时间:2023-05-14 13:24:29 阅读: 评论:0

OpenCV之相机畸变矫正
opencv 4.4
vs2017
代码是借⽤⼈家的,具体哪篇也忘了~
程序运⾏后按Y键持续检测⾓点直到输出
⾓点找不到的原因分析 这⾥设置标定板的⾓点数错误,⾏列应该设置为你标定板最⼤格数-1,我的标定板是7⾏10列这⾥就设置(6,9)另外还有可能标定板离的太近
Size patternsize = Size(6,9); /* 标定板上每⾏、列的⾓点数 */
另外个容易出问题的地⽅在这⾥ COLOR_RGB2GRAY,由于opencv版本的变化这⾥可能会报错,⽼的版本可能是
cv::CV_RGB2GRAY,主体意思就是把传进来的图⽚变成灰度图
月季花和玫瑰花的区别cvtColor(imageInput, gray, COLOR_RGB2GRAY);
#include "pch.h"
#include <iostream>
#include <cstring>
#include "opencv2/opencv_modules.hpp"
#include <opencv2/core/utility.hpp>
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include <opencv2/calib3d/calib3d.hpp>
#include "opencv2/stitching/detail/autocalib.hpp"
#include "opencv2/stitching/detail/blenders.hpp"
#include "opencv2/stitching/detail/timelaprs.hpp"
#include "opencv2/stitching/detail/camera.hpp"
#include "opencv2/stitching/detail/exposure_compensate.hpp"
#include "opencv2/stitching/detail/matchers.hpp"
#include "opencv2/stitching/detail/motion_estimators.hpp"
#include "opencv2/stitching/detail/am_finders.hpp"
#include "opencv2/stitching/detail/warpers.hpp"
#include "opencv2/stitching/warpers.hpp"
#include "opencv2/xfeatures2d.hpp"
打折扣#include <opencv2/stitching.hpp>
#include <iostream>
#include <fstream>
using namespace std;
using namespace cv;
using namespace cuda;
using namespace cv;
using namespace std;
int main() {
int image_count = 1;          /* 图像数量 */
Size image_size;              /* 图像的尺⼨ */
Size patternsize = Size(6,9); /* 标定板上每⾏、列的⾓点数 */
vector<vector<Point2f>> corner_all; /* 保存检测到的所有⾓点 */
VideoCapture capture;
capture.open(0);
// 原图像
Mat imageInput;// = imread("F://fisheye.png");
for (int i = 0; i < image_count;)
{
capture >> imageInput;
if (pty())
{
cout << "empty image\n";
return 0;
}
imshow("src", imageInput);
// 只是为了获得键盘⽽已
switch (waitKey(10))
{
ca 'q':
return 0;
break;
ca 'y':
break;
default:
continue;
弧长的公式
break;
}
i++;
// ⽤于观察检验输出
printf("第%d张图⽚\t", i);
if (i == 1) //读⼊第⼀张图⽚时获取图像宽⾼信息
{
// 列宽,⾏⾼
image_size.width = ls;
image_size.height = ws;
cout << "image_size.width = " << image_size.width << endl;
cout << "image_size.height = " << image_size.height << endl;
}
Mat gray;
cvtColor(imageInput, gray, COLOR_RGB2GRAY);
vector<Point2f> corner_single; /* 缓存每幅图像上检测到的⾓点 */
/* 提取⾓点 */
bool patternfound = findChessboardCornersSB(gray, patternsize, corner_single); //findChessboardCorners(gray, patternsize, corner_single);  // 如果找到了
if (patternfound)
{
/* 亚像素精确化 */
TermCriteria criteria = TermCriteria(TermCriteria::EPS + TermCriteria::MAX_ITER , 100, 0.101);
cornerSubPix(gray, corner_single, Size(10, 10), Size(-1, -1), criteria);
corner_all.push_back(corner_single); //保存亚像素⾓点
/* 在图像上显⽰⾓点位置 */
drawChessboardCorners(gray, patternsize, corner_single, patternfound); //⽤于在图⽚中标记⾓点
imshow("drawChessboardCorners", gray);                                //显⽰图⽚
}
el
el
{
cout << "can not find chessboard corners!\n"; //找不到⾓点
i--;
continue;
开业宣传}
cout << "\n******************\n";
}
int total = corner_all.size();
cout << "已收集的棋盘图个数:" << total << endl;
/***************************** 以下是摄像机标定 ************************************************/
cout << "\n[开始标定]>>>>>>\n";
Size square_size = Size(10, 10); /* 实际测量得到的标定板上每个棋盘格的⼤⼩ */
/* calibrateCamera的参数 */
vector<vector<Point3f>> object_points; /* 保存标定板上⾓点的三维坐标 */
/
/ imagePoints
// imageSize上⾯已经获得
Mat cameraMatrix = Mat(3, 3, CV_32FC1, Scalar::all(0)); /* 摄像机内参数矩阵 */
Mat distCoeffs = Mat(1, 5, CV_32FC1, Scalar::all(0));  /* 摄像机的5个畸变系数:k1,k2,p1,p2,k3 */ vector<Mat> rvecs;                                      /* 每幅图像的旋转向量 */
vector<Mat> tvecs;                                      /* 每幅图像的平移向量 */
/* 初始化标定板上⾓点的三维坐标 */
for (int count = 0; count < image_count; count++)
{
vector<Point3f> single_object_points;
// 每列
for (int i = 0; i < patternsize.height; i++)
{
// 每⾏
for (int j = 0; j < patternsize.width; j++)
{
Point3f realPoint;
/* 假设标定板放在世界坐标系中z=0的平⾯上 */
孕妇可以吃柚子吗realPoint.x = i * square_size.width;
realPoint.y = j * square_size.height;
realPoint.z = 0;
single_object_points.push_back(realPoint);
}
}
object_points.push_back(single_object_points);
}
calibrateCamera(object_points, corner_all, image_size, cameraMatrix, distCoeffs, rvecs, tvecs); cout << "[标定完成]\n";
/*********************************** 对标定结果进⾏评价 **********************************************/
cout << "\n[开始评价标定结果]>>>>>>\n";
//每张图⽚上总的⾓点数
int cornerNum = patternsize.width * patternsize.height;
double err_single = 0.0; /* 每幅图像的误差 */
double err_total = 0.0;  /* 所有图像的误差的总和 */
double err_mean = 0.0;  /* 所有图像的平均误差 */
vector<Point2f> imagePoints2; /* 保存重新计算得到的投影点 */
for (int i = 0; i < image_count; i++)
{会计日常工作
/* 通过得到的摄像机内外参数,对空间的三维点进⾏重新投影计算,得到新的投影点 */
projectPoints(object_points[i], rvecs[i], tvecs[i], cameraMatrix, distCoeffs, imagePoints2);
/* 计算新的投影点和旧的投影点之间的误差*/
// 每张图像的⾓点
vector<Point2f> corner_single = corner_all[i];
// 声明原结果的⾓点矩阵
Mat mat_corner_single = Mat(1, corner_single.size(), CV_32FC2);
// 声明评测结果的⾓点矩阵
Mat mat_imagePoints2 = Mat(1, imagePoints2.size(), CV_32FC2);
// 每个⾓点
for (int j = 0; j < corner_single.size(); j++)
{
// 给原结果的⾓点矩阵赋值
mat_corner_single.at<Vec2f>(0, j) = Vec2f(corner_single[j].x, corner_single[j].y);  // 给评测结果的⾓点矩阵赋值
陈立清mat_imagePoints2.at<Vec2f>(0, j) = Vec2f(imagePoints2[j].x, imagePoints2[j].y);  }
// 取2范数
err_single = norm(mat_imagePoints2, mat_corner_single, NORM_L2);
err_total += err_single;
}
// 平均误差
err_mean = err_total / cornerNum;
cout << "[总体平均误差]:" << err_mean << "像素" << endl;
cout << "[评价完成!]" << endl;
cout << "cameraMatrix:\n"
<< cameraMatrix << endl;
cout << "distCoeffs:\n"
<< distCoeffs << endl;
/************************ 显⽰定标结果 ******************************/
cout << "[矫正图像]>>>>>>" << endl;
Mat result;
undistort(imageInput, result, cameraMatrix, distCoeffs);
imshow("result", result);bj是什么意思
waitKey();
return 0;
}
运⾏结果:
控制台输出结果图
相机原始图像
灰度后取⾓点并画出

本文发布于:2023-05-14 13:24:29,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/89/897354.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:标定   图像   结果   得到   矩阵   输出   可能
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图