OpenCV 棋盘 相机标定 一

棋盘下载地址 下载

具体原理参考原理 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)

效果图


猜你喜欢

转载自blog.csdn.net/qq_29796781/article/details/81021844