OpenCV开发笔记(八十一):通过棋盘格使用鱼眼方式标定相机内参矩阵矫正摄像头图像
前言
对于广角摄像头通过相机图片可以识别出棋盘角点计算相机内参矩阵,通过畸变校准可以得到较好的效果,但是鱼眼摄像头通过这种方式获得周围四周的图像效果并不是很好。所以,鱼眼摄像头在校准上与普通摄像头有一些区别。
本篇通过一张图片来识别计算得到相机内参矩阵,并鱼眼矫正的方式矫正图像畸形。
鱼眼方式畸变校准效果
普通畸变校准效果
注意:这里demo只使用了可识别的两张基本相似的棋盘图作为计算,鱼眼畸变矫正,若是区别大,那么校准的时候会因为计算误差超限而奔溃。
QStringList list;
list.append("D:/qtProject/openCVDemo/openCVDemo/modules/openCVManager/images/34.png");
list.append("D:/qtProject/openCVDemo/openCVDemo/modules/openCVManager/images/35.png");
int chessboardColCornerCount = 8;
int chessboardRowCornerCount = 11;
std::vector<std::vector<cv::Point3f>> vectorObjectPoint;
std::vector<std::vector<cv::Point2f>> vectorImagePoint;
cv::Mat grayMat;
cv::Mat srcMat;
for(int n = 0; n < list.size(); n++)
{
QString str = list.at(n);
std::string srcFilePath = str.toStdString();
// 步骤一:读取文件
cv::Mat mat = cv::imread(srcFilePath);
LOG << mat.cols << mat.rows;
#if 1
srcMat = cv::Mat(mat.rows * 2, mat.cols * 2, CV_8UC3);
cv::Mat matRoi = srcMat(cv::Rect(mat.cols / 2, mat.rows / 2, mat.cols, mat.rows));
cv::addWeighted(mat, 1.0f, matRoi, 0, 0, matRoi);
#else
srcMat = mat.clone();
#endif
// 步骤二:缩放,太大了缩放下(可省略)
cv::resize(srcMat, srcMat, cv::Size(srcMat.cols / 2, srcMat.rows / 2));
cv::Mat srcMat2 = srcMat.clone();
cv::Mat srcMat3 = srcMat.clone();
// 步骤三:灰度化
cv::cvtColor(srcMat, grayMat, cv::COLOR_BGR2GRAY);
cv::imshow("grayMat", grayMat);
// 步骤四:检测角点
std::vector<cv::Point2f> vectorPoint2fCorners;
bool patternWasFound = false;
patternWasFound = cv::findChessboardCorners(grayMat,
cv::Size(chessboardColCornerCount,
chessboardRowCornerCount),
vectorPoint2fCorners,
cv::CALIB_CB_ADAPTIVE_THRESH |
cv::CALIB_CB_FAST_CHECK |
cv::CALIB_CB_NORMALIZE_IMAGE);
if(!patternWasFound)
{
LOG << "not find ChessboardCorners:" << chessboardColCornerCount << chessboardRowCornerCount;
continue;
}
/*
enum { CALIB_CB_ADAPTIVE_THRESH = 1, // 使用自适应阈值将图像转化成二值图像
CALIB_CB_NORMALIZE_IMAGE = 2, // 归一化图像灰度系数(用直方图均衡化或者自适应阈值)
CALIB_CB_FILTER_QUADS = 4, // 在轮廓提取阶段,使用附加条件排除错误的假设
CALIB_CB_FAST_CHECK = 8 // 快速检测
};
*/
cvui::printf(srcMat, 0, 0, 1.0, 0xFF0000, "found = %s", patternWasFound ? "true" : "false");
cvui::printf(srcMat, 0, 24