opencv-python摄像机内外参数标定练习

摘要:使用python语言中的numpy和opencv库,通过棋盘格拍摄(张正友标定法)实现摄像机内外参数标定的练习

主要参考文献:标定相机参数实现
代码如下:

#%%导入库

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import cv2 as cv
import math
import scipy.io as sc
"""
bug记录:
1、不要把可变数据类型当作函数参数的默认数值(会出现莫名其妙的bug,python特性导致的)
2、单应性矩阵求解函数输入参数错误(粗心)
3、标定函数所需要的数据类型必须是列表
"""

#%%数据初始处理

im1_path=r'C:\Users\cz\Desktop\picture\cv\chess2.jpg'
im0 = cv.imread(im1_path)
plt.imshow(im0)
im0_gray=cv.cvtColor(im0,cv.COLOR_BGR2GRAY)#准备图片为灰度浮点数
plt.imshow(im0_gray,cmap='gray')

#%% 定义函数

def chess_address_img(image,size=(6,6)):
    a,b=cv.findChessboardCorners(image,(6,6),None)
    im_show_chessgrid=cv.drawChessboardCorners(image, (6, 6), b, a)
    c=b.reshape(36,2)
    return c,im_show_chessgrid

def chess_address_world(size,lenth):
    l1=[i1*lenth[0] for i1 in range(0,size[0])]*size[1]
    l2=l1.copy()*lenth[1]
    l2.sort()
    l3=[0 for i2 in range(size[0]*size[1])]
    address=np.array([l1,l2,l3]).T
    return address


#%%获取棋盘角点像素地址与标记图像

show_address_1=im0.copy()
address_1_img,show_address_1=chess_address_img(show_address_1,(6,6))
address_1_world=chess_address_world([6,6],[1,1]).astype(np.float32)
l1=[address_1_world]
l2=[address_1_img]

#%%输出标定参数

ret, mtx, dist, rvecs, tvecs =cv.calibrateCamera(l1,l2,imageSize=im0.shape[0:2],cameraMatrix=None,distCoeffs=None)
print("ret:", ret)
print("mtx:\n", mtx) # 内参数矩阵
print("dist:\n", dist)  # 畸变系数
print("rvecs:\n", rvecs)  # 旋转向量  # 外参数
print("tvecs:\n", tvecs ) # 平移向量  # 外参数

#%%显示图像

fig, axs = plt.subplots(3,2, figsize=(40,40))
axs[0,0].imshow(im0[:,:,[2,1,0]],cmap='gray')
# axs[0,0].scatter(address_1[:,0],address_1[:,1],marker='o',color='red',s=100)
axs[0,1].imshow(show_address_1[:,:,[2,1,0]],cmap='gray')
# axs[1,0].imshow(im3,cmap='gray')
# axs[1,1].imshow(im4,cmap='gray')
# axs[2,0].imshow(im5,cmap='gray')
# axs[2,1].imshow(im6,cmap='gray')
plt.show()

练习主要碰到的问题见程序bug描述处

标定结果输出如下:(暂未检验正确性)
ret(): 0.26270271679009355
mtx:(内参矩阵)
[[1.86677861e+03 0.00000000e+00 1.22520189e+03]
[0.00000000e+00 1.83770294e+03 1.65194375e+03]
[0.00000000e+00 0.00000000e+00 1.00000000e+00]]
dist:(畸变系数)
[[ 0.01393336 0.03675153 0.00352456 -0.00619887 -0.04774407]]
rvecs:(旋转向量)
[array([[ 0.02743378],
[-0.02400618],
[-0.14423772]])]
tvecs:(平移向量)
[array([[ 2.75574962],
[-2.81382151],
[12.81295064]])]
标定使用图片
棋盘生成代码如下

#%%导入库
import matplotlib
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import cv2 as cv
import math

#%% 定义函数
def creatchessboard(size):
    board_shape=(100*size[0],100*size[1])
    white=np.zeros(shape=(100,100))
    black=white+255
    board=np.zeros(shape=board_shape)
    l1=np.array([(1+pow(-1,i1+i2))/2 for i1 in range(0,size[0]) for i2 in range(0,size[1])]).reshape(size[0],size[1])
    x,y=np.where(l1==1)
    for i1 in range(0,len(x)):
        board[x[i1]*100:(x[i1]+1)*100,y[i1]*100:(y[i1]+1)*100]=black
    return board

#%%
im1=creatchessboard((7,7))
cv.imwrite(r"C:\Users\cz\Desktop\picture\cv\chessboard.png",im1)

#%% 显示图像
fig, axs = plt.subplots(3,2, figsize=(40,40))
axs[0,0].imshow(im1,cmap='gray')
# axs[0,0].scatter(l1[1,:],l1[0,:],marker='o',color='red',s=200)
# axs[0,1].imshow(im2,cmap='gray')
# axs[0,1].scatter(l2[1,:],l2[0,:],marker='o',color='red',s=200)
# axs[1,0].imshow(im3,cmap='gray')
# axs[1,1].imshow(im4,cmap='gray')
# axs[2,0].imshow(im5,cmap='gray')
# axs[2,1].imshow(H_i_y,cmap='gray')
plt.show()
  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值