完整项目链接:GitHub - xfliu1998/kinectProject
Kinect V2相机标定
使用张正友标定法对Kinect V2相机标定。原理及参考代码见以下链接:
- 单目相机标定实现–张正友标定法:https://blog.csdn.net/weixin_43763292/article/details/128546103?spm=1001.2014.3001.5506
- python利用opencv进行相机标定(完全版):https://blog.csdn.net/dgut_guangdian/article/details/107467070?spm=1001.2014.3001.5506
- Kinect2.0-Python调用-PyKinect2:https://blog.csdn.net/zcz0101/article/details/115718427?spm=1001.2014.3001.5506
- 导入需要的包
import os
import time
import datetime
import glob as gb
import h5py
import keyboard
import cv2
import numpy as np
from utils.calibration import Calibrator
from utils.kinect import Kinect
- 拍摄不同角度的标定图。取照要求:不同角度不同位置拍摄(10-20)张标定图,棋盘格的视野在整张图的1/4~2/3左右。以下函数默认拍摄20张图,按空格键拍摄照片,按q键结束拍摄,拍的标定图会保存到指定路径。
def get_chess_image(image_num=20):
out_path = './data/chess/'
if not os.path.exists(out_path):
os.makedirs(out_path)
camera = cv2.VideoCapture(0)
i = 0
while 1:
(grabbed, img) = camera.read()
cv2.imshow('img', img)
if cv2.waitKey(1) & keyboard.is_pressed('space'): # press space to save an image
i += 1
firename = str(f'{
out_path}img{
str(i)}.jpg')
cv2.imwrite(firename, img)
print('write: ', firename)
if cv2.waitKey(1) & 0xFF == ord('q') or i == image_num: # press q to finish
break
- 对相机标定。函数将相机的内参和畸变系数输出至指定路径,同时可以获得每张标定图的外参矩阵。函数需要用到标定类,代码在utils包中。
def camera_calibrator(shape_inner_corner=(11, 8), size_grid=0.025):
'''
:param shape_inner_corner: checkerboard size = 12*9
:param size_grid: the length of the sides of the checkerboard = 25mm
'''
chess_dir = "./data/chess"
out_path = "./data/dedistortion/chess"
if not os.path.exists(out_path):
os.makedirs(out_path)
# create calibrator
calibrator = Calibrator(chess_dir, shape_inner_corner, size_grid)
# calibrate the camera
mat_intri, coff_dis = calibrator.calibrate_camera()
np.save('./data/intrinsic_matrix.npy', mat_intri)
np.save('./data/distortion_cofficients.npy', coff_dis)
print("intrinsic matrix: \n {}".format(mat_intri))
print("distortion cofficients: \n {}".format(coff_dis)) # (k_1, k_2, p_1, p_2, k_3)
# dedistortion
calibrator.dedistortion(chess_dir, out_path)
return mat_intri, coff_dis
import os
import glob
import cv2
import numpy as np
class Calibrator(object):
def __init__(self, img_dir, shape_inner_corner, size_grid, visualization=True):
"""
--parameters--
img_dir: the directory that save images for calibration, str
shape_inner_corner: the shape of inner corner, Array of int, (h, w)
size_grid: the real size of a grid in calibrator, float
visualization: whether visualization, bool
"""
self.img_dir = img_dir
self.shape_inner_corner = shape_inner_corner
self.size_grid = size_grid
self.visualization = visualization
self.mat_intri = None # intrinsic matrix
self.coff_dis = None # cofficients of distortion
# create the conner in world space
w, h = shape_inner_corner
# cp_int: save the coordinate of corner points in world space in 'int' form. like (0,0,0), ...., (10,7,0)
cp_int = np.zeros((w * h, 3), np.float32)
cp_int[:, :2] = np.mgrid[0:w, 0:h].T.reshape(-1, 2)
# cp_world: corner point in world space, save the coordinate of corner points in world space
self.cp_world = cp_int * size_grid
# images
self.img_paths = []
for extension in ["jpg", "png", "jpeg"]:
self.img_paths += glob.glob(os.path.join(img_dir, "*.{}".format(extension)))
assert len(self.img_paths), "No images for calibration found!"
def calibrate_camera(self):
w, h = self.shape_inner_corner
# criteria: only for subpix calibration, which is not used here
# criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
points_world = [] # the points in world space
points_pixel = [] # the points in pixel space (relevant to points_world)
for img_path in self.img_paths:
img = cv2.imread(img_path)
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# find the corners, cp_img: corner points in pixel space
ret, cp_img = cv2.findChessboardCorners(gray_img, (w, h), None)
# if ret is True, save
if ret:
# cv2.cornerSubPix(gray_img, cp_img, (11,11), (-1,-1), criteria)
points_world.append(self.cp_world)
points_pixel.append(cp_img)
# view the corners
if self.visualization:
cv2.drawChessboardCorners(img, (w, h), cp_img, ret)
_, img_name = os.path.split(img_path)
cv2.imwrite(os.path.join(self.img_dir, f"dedistortion/coner_detect/{
img_name}"), img)
cv2.imshow('FoundCorners', img)
cv2.waitKey(500)
# calibrate the camera
ret