簡(jiǎn)介
findChessboardCornersSB是OpenCV4新引入的棋盤格角點(diǎn)檢測(cè)函數(shù),可以直接獲得亞像素角點(diǎn)坐標(biāo),對(duì)噪聲的魯棒性和對(duì)大尺寸圖像的檢測(cè)速度相比之前的findChessboardCorners有很大提升。本文介紹findChessboardCornersSB函數(shù)的算法原理,并給出函數(shù)使用示例。
算法原理
findChessboardCornersSB的實(shí)現(xiàn)主要參考論文Accurate Detection and Localization of Checkerboard Corners for Calibration(2018)。
如上圖所示,棋盤格角點(diǎn)檢測(cè)算法的模型可以分為兩類,一種是中心線模型,一種是邊緣交叉模型。邊緣交叉模型的缺點(diǎn)是易受噪聲影響,論文中提出的是一種基于中心線模型的檢測(cè)算法。文章來源:http://www.zghlxwxcb.cn/news/detail-836994.html
檢測(cè)算法基于Radon變換的思想,對(duì)于任意一個(gè)像素,可以選擇以其為中心的圓形區(qū)域,對(duì)像素灰度沿不同角度進(jìn)行積分。可以畫出積分結(jié)果隨角度的變化曲線,當(dāng)這一像素是角點(diǎn)時(shí),如下圖所示,曲線接近三角函數(shù)曲線,且曲線有較大的變化幅度??梢愿鶕?jù)這一特性判斷像素是否為角點(diǎn)。
使用Radon變換的問題是不同角度的積分計(jì)算較為耗時(shí)。為了加速這一過程,論文中只計(jì)算0、45、90、135這四個(gè)方向。0、90度的積分結(jié)果分別由對(duì)圖像進(jìn)行橫豎兩個(gè)方向的Box濾波獲得,為得到45、135度的積分結(jié)果,先將圖像旋轉(zhuǎn)45°,對(duì)旋轉(zhuǎn)的圖像進(jìn)行橫豎兩個(gè)方向的Box濾波,最后再反向旋轉(zhuǎn)圖像。取四個(gè)濾波結(jié)果中最大值與最小值差值的平方作為角點(diǎn)響應(yīng)值。對(duì)響應(yīng)圖進(jìn)行濾波,找到局部極大值,并進(jìn)行亞像素插值獲得亞像素角點(diǎn)坐標(biāo),最后再使用閾值和非最大值抑制來濾除響應(yīng)弱的角點(diǎn)。原文算法流程如下圖。
下圖是論文中展示的對(duì)實(shí)際圖片進(jìn)行角點(diǎn)檢測(cè)的效果
論文使用仿真數(shù)據(jù)和實(shí)際數(shù)據(jù)對(duì)提出的算法和OpenCV原始的角點(diǎn)檢測(cè)算法效果進(jìn)行了對(duì)比。仿真數(shù)據(jù)中,提出的算法在不同角點(diǎn)角度、低運(yùn)動(dòng)模糊、不同噪聲水平、不同透視角度下都優(yōu)于OpenCV原始方法。實(shí)際數(shù)據(jù)中,提出的算法檢測(cè)成功率更高,同時(shí)重投影誤差也更小。文章來源地址http://www.zghlxwxcb.cn/news/detail-836994.html
函數(shù)使用
#include<opencv2/opencv.hpp>
int main()
{
std::string pattern = "./data/*.png";
std::vector<std::string> files;
cv::glob(pattern, files);
int width = 11;
int height = 8;
cv::Size patternSize(width, height);
// flag參數(shù)
// cv::CALIB_CB_NORMALIZE_IMAGE 調(diào)用cv::equalizeHist對(duì)圖片進(jìn)行直方圖均衡化
// cv::CALIB_CB_EXHAUSTIVE 保留更多的角點(diǎn)用于棋盤格篩選,同時(shí)嘗試更多次數(shù)的棋盤格篩選
// cv::CALIB_CB_ACCURACY 對(duì)圖像進(jìn)行x2放大,提高角點(diǎn)檢查準(zhǔn)確度
// cv::CALIB_CB_LARGER 是否允許檢測(cè)出的標(biāo)定板角點(diǎn)數(shù)量大于標(biāo)定板patternSize
// cv::CALIB_CB_MARKER 標(biāo)定板是否有標(biāo)記點(diǎn)
int flag = cv::CALIB_CB_EXHAUSTIVE | cv::CALIB_CB_ACCURACY;
std::string windowsName = "Chessboard Corners";
for (auto f : files)
{
cv::Mat image = cv::imread(f, cv::IMREAD_UNCHANGED);
std::vector<cv::Point2f> corners;
// 檢測(cè)棋盤格
bool found = cv::findChessboardCornersSB(image, patternSize, corners, flag);
if (found)
{
// 繪制顯示結(jié)果
cv::drawChessboardCorners(image, patternSize, corners, found);
cv::namedWindow(windowsName);
cv::imshow(windowsName, image);
cv::waitKey(0);
cv::destroyWindow(windowsName);
}
}
return 0;
}
到了這里,關(guān)于【OpenCV findChessboardCornersSB 算法原理與函數(shù)使用】的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!