前言
對於廣角攝像頭透過相機圖片可以識別出棋盤角點計算相機內參矩陣,透過畸變校準可以得到較好的效果,但是魚眼攝像頭透過這種方式獲得周圍四周的影像效果並不是很好。所以,魚眼攝像頭在校準上與普通攝像頭有一些區別。
本篇透過一張圖片來識別計算得到相機內參矩陣,並魚眼矯正的方式矯正影像畸形。
魚眼方式畸變校準效果
普通畸變校準效果
注意:這裡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, 1.0