OpenCV 棋盘 相机标定 一
程序员文章站
2022-05-22 11:19:15
...
棋盘下载地址 下载
具体原理参考原理 OpenCV
在相机标定中像素级别操作涉及到比较重要的函数 findChessboardCorners()和cornerSubPix()
一、findChessboardCorners()
功能:在棋盘中找出所有角点
原型:
// 成功return 1 ,失败return 0
int cvFindChessboardCorners(
const void* image, // 输入,棋盘图片
CvSize pattern_size, // 输入,棋盘图片内的角点数量 行X列 如7,8(七行八列) Size(7,8)
CvPoint2D32f* corners, // 结果输出,存放检测到的角点
int* corner_count=NULL, // 结果输出,检测到的角点个数
int flags=CV_CALIB_CB_ADAPTIVE_THRESH //操作标志位
);
操作标志位定义CV_CALIB_CB_ADAPTIVE_THRESH - 使用自适应阈值(通过平均图像亮度计算得到)将图像转换为黑白图,而不是一个固定的阈值。
CV_CALIB_CB_NORMALIZE_IMAGE - 在利用固定阈值或者自适应的阈值进行二值化之前,先使用cvNormalizeHist来均衡化图像亮度。
CV_CALIB_CB_FILTER_QUADS - 使用其他的准则(如轮廓面积,周长,方形形状)来去除在轮廓检测阶段检测到的错误方块
二、cornerSubPix()
原型
void cornerSubPix(
InputArray image, // 输入,图像
InputOutputArray corners, // findChessboardCorners()输出的角点,精准化角点坐标
//搜索窗口边长的一半,例如如果winSize=Size(5,5),则一个大小为:
Size winSize,
// 搜索区域中间的deadregion边长的一半,有时用于避免自相关矩阵的奇异性。
// 如果值设为(-1,-1)则表示没有这个区域
Size zeroZone,
// 角点精准化迭代过程的终止条件。也就是当迭代次数超过criteria.maxCount,
// 或者角点位置变化小于criteria.epsilon时,停止迭代过程
TermCriteria criteria
);
三、CvTermCriteria 类:迭代算法的终止准则
原型:
CvTermCriteria 类:迭代算法的终止准则 类原型:
typedef struct CvTermCriteria
{
int type; /* CV_TERMCRIT_ITER 和CV_TERMCRIT_EPS二值之一,或者二者的组合 */
int max_iter; /* 最大迭代次数 */
double epsilon; /* 结果的精确性 */
}
宏定义
CV_TERMCRIT_ITER:代终止条件为达到最大迭代次数终止
CV_TERMCRIT_EPS:迭代到阈值终止
四、drawChessboardCorners()绘制角点
原型
void cv::drawChessboardCorners(
cv::InputOutputArray image, // 即是输入也是输出 棋盘格图像(8UC3)
cv::Size patternSize, // 棋盘格内部角点的行、列数
cv::InputArray corners, // findChessboardCorners()输出的角点
bool patternWasFound // findChessboardCorners()的返回值
);
五、要检测的棋盘
六、详细代码
C++版本代码
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main()
{
Mat img,gray;
vector<Point2f> corners;// 保存findChessboardCorners输出角点
//Size board_size = Size(9,6);
img = imread("../imges/chessboard_img.jpg");
//转换成灰度图片
cvtColor(img,gray,CV_RGB2GRAY);
bool ret = findChessboardCorners(gray,Size(9,6),corners);
if(ret == 0)
{
std::cout<<"[err] no corners to found!"<<endl;
exit(1);
}
else
{
// 对角点进行亚像素精确化
cornerSubPix(gray,corners,Size(5,5),Size(-1,-1),TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1));
}
bool wasfound;
// 在img上绘制角点
drawChessboardCorners(img,Size(9,6),corners,wasfound);
namedWindow("corners");
imshow("corners",img);
waitKey(10000);
return 0;
}
python版代码:
# -*- coding: UTF-8 -*-
import cv2
import numpy as np
import glob
# 设置寻找亚像素角点的参数,采用的停止准则是最大循环次数30和最大误差容限0.001
criteria = (cv2.TERM_CRITERIA_MAX_ITER | cv2.TERM_CRITERIA_EPS, 30, 0.001)
# 读取图片
# imgpath = glob.glob('')
# img = cv2.imread('static/girl.jpg')
img = cv2.imread('static/chessboard_img.jpg')
# 转换成灰度图
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# 角点检测 (9,6) 行角点个数9 列角点个数6
ret,corners = cv2.findChessboardCorners(gray,(9,6),None)
print corners
# 亚像素精确定位角点位置
corners2 = cv2.cornerSubPix(gray, corners, (5,5), (-1,-1), criteria)
print ret
# 图上绘制检测到的角点
cv2.drawChessboardCorners(img, (9,6), corners, ret) # 记住,OpenCV的绘制函数一般无返回值
cv2.imshow('img', img)
cv2.waitKey(30000)
效果图