欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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()的返回值
	);

五、要检测的棋盘

OpenCV 棋盘 相机标定 一

六、详细代码

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)

效果图

OpenCV 棋盘 相机标定 一