使用OpenCV库快速求解相机内参

本文主要介绍如何使用OpenCV库函数求解相机内参。具体可查阅官网:https://docs.opencv.org/master/dc/dbb/tutorial_py_calibration.html
关于相机内参的求解还有很多其它的工具,如使用MATLAB求解会更方便,直接调用MATLAB中的APP即可。

1.背景知识

关于相机标定的详细理论可以参考博客:《深入理解张正友相机标定法:数学理论详细推导》
相机内参形式如下,是一个 3 × 3 3\times3 3×3的矩阵,其中 ( f x , f y ) (f_x,f_y) (fx,fy)是相机焦距, ( c x , c y ) (c_x,c_y) (cx,cy)是光学中心。相机内参对于相机而言是唯一的,因此只要计算出了相机内参,就可以在同一相机拍摄的其它图像上重复使用。
K = [ f x 0 c x 0 f y c y 0 0 1 ] (1) K = \left[ \begin{matrix} f_x & 0 & c_x \\ 0 & f_y & c_y \\ 0 & 0 & 1 \end{matrix} \right] \tag{1} K=fx000fy0cxcy1(1)


2.OpenCV库求相机内参

这里使用官方提供的图片来演示如何求解相机内参,目前已有某一相机拍摄的棋盘格图片若干张(20-30张不等),部分图片如下:

image1image2
在这里插入图片描述在这里插入图片描述
使用OpenCV库求解相机内参代码如下,其中mtx为相机内参, dist为畸变系数,
import numpy as np
import cv2
import glob

# extract object points and image points
objp = np.zeros((6*8, 3), np.float32)
objp[:, :2] = np.mgrid[0:8, 0:6].T.reshape(-1, 2)

# Arrays to store object points and image points from all the images.
objpoints = []   
imgpoints = []   

images = glob.glob('calibration_wide/GO*.jpg')

# Step through the list and search for chessboard corners
for idx, fname in enumerate(images):
    img = cv2.imread(fname)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    # Find the chessboard corners
    ret, corners = cv2.findChessboardCorners(gray, (8, 6), None)    
    if ret == True:
        objpoints.append(objp)
        imgpoints.append(corners)

        # Draw and display the corners
        cv2.drawChessboardCorners(img, (8, 6), corners, ret)
        cv2.imshow('img', img)
        cv2.waitKey(500)

# calibrate
img = cv2.imread('test_image.jpg')
img_size = (img.shape[1], img.shape[0])

# Do camera calibration given objects points and image points
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, img_size, None, None)

dst = cv2.undistort(img, mtx, dist, None, mtx)   
cv2.imwrite('test_undist.jpg', dst)

标定是根据查找棋盘格顶点来标定的,如图所示:

image1image2
在这里插入图片描述在这里插入图片描述
最后,根据求得的相机内参畸变系数,可以对失真的图片进行还原,还原效果如下:
undist_imagedist_image
在这里插入图片描述在这里插入图片描述
  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
要求相机内参,你需要使用相机标定技术。标定过程中需要使用一组已知的世界坐标系下的点,通过相机拍摄这些点得到它们在相机坐标系下的像素坐标,进而求解相机内参矩阵。 OpenCV提供了相机标定函数`cv2.calibrateCamera()`来帮助你求解相机内参。具体步骤如下: 1. 准备标定板:通过在标定板上安装黑白相间的棋盘格或者圆点等特征点,确保标定板的二维信息已知。 2. 拍摄标定板:使用相机拍摄多张标定板的照片,注意不同拍摄角度、距离和姿态等的变化。将每张照片中标定板的角点提取出来,用于后续标定。 3. 求解相机内参:将标定板的三维坐标和对应的二维图像坐标输入到`cv2.calibrateCamera()`函数中,该函数会自动求解相机内参矩阵。 以下是一个简单的示例代码: ```python import cv2 import numpy as np # 准备标定板 board_size = (9, 6) square_size = 1 # 代表标定板方格的大小 objp = np.zeros((board_size[0] * board_size[1], 3), np.float32) objp[:, :2] = np.mgrid[0:board_size[0], 0:board_size[1]].T.reshape(-1, 2) * square_size # 拍摄标定板 img_points = [] # 存储每张图片中的角点 obj_points = [] # 存储标定板的三维坐标 img = cv2.imread('calibration.jpg') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ret, corners = cv2.findChessboardCorners(gray, board_size, None) if ret: img_points.append(corners) obj_points.append(objp) # 求解相机内参 ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(obj_points, img_points, gray.shape[::-1], None, None) # 输出相机内参矩阵 print('相机内参矩阵:') print(mtx) ``` 注意,标定板的大小和方格大小需要根据实际情况进行调整。另外,求解相机内参矩阵包含了相机的焦距、主点位置、畸变系数等信息,可以用于后续的相机校正、立体视觉等应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值