[图像]二值化检测角点
Abstract: 做棋盘格的检测——最好是先二值化,然后findchessboard。
简短记一下:
二值化:
cv::Mat binary;
blockSize = 61;
Constvalue = 0;
cv::adaptiveThreshold(SingleChartImage_roi_gray, binary, 255, cv::ADAPTIVE_THRESH_GAUSSIAN_C, cv::THRESH_BINARY, blockSize, Constvalue);
cv::imwrite("../debug/preprocessed_binary.jpg", binary);
cv::adaptiveThreshold是自适应二值化函数,binary是输出结果。最重要的两个超参数是blockSize和Constvalue,constvalue决定了图片的亮暗,blocksize决定了黑色方块的大小。一般这么设置61是ok的,还可以自适应调整,懒得写。
vector<int> flag_combinations = {// 单独尝试
CALIB_CB_ADAPTIVE_THRESH,
CALIB_CB_NORMALIZE_IMAGE,
CALIB_CB_FAST_CHECK,
// 组合尝试
CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE,
CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_FAST_CHECK,
CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_FILTER_QUADS,
// 更多组合
CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE + CALIB_CB_FILTER_QUADS,
CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE + CALIB_CB_CLUSTERING,
// 不使用任何标志(默认)
0};
for (int i = 0; i < flag_combinations.size(); i++) {
vector<cv::Point2f> test_corners;
bool test_found = findChessboardCorners(binary, cv::Size(tag.width, tag.height), test_corners, flag_combinations[i]);
std::cout << "标志组合 " << i << " (值=" << flag_combinations[i] << "): " << (test_found ? "成功" : "失败") << ", 检测到角点: " << test_corners.size() << std::endl;
if (test_found) {
corners = test_corners;
found = true;
// 可视化成功的检测
cv::Mat display = binary.clone();
if (display.channels() == 1) {
cv::cvtColor(display, display, cv::COLOR_GRAY2BGR);
}
cv::drawChessboardCorners(display, cv::Size(tag.width, tag.height), test_corners, test_found);
cv::imwrite("../debug/success_flag_" + std::to_string(i) + ".jpg", display);
std::cout << "使用标志组合 " << i << " 检测成功!" << std::endl;
break;
}
}
结果所示:

这个是进行标志的检测,具体标志的意思,可以查一下,这是debug代码,一般来说找到合适的标志后,就直接改成那个标志来调用就可以了。
Last modified on 2026-01-13