diff --git a/log/0216/poses_bounds.npy b/log/0216/poses_bounds.npy new file mode 100644 index 0000000..ff801ca Binary files /dev/null and b/log/0216/poses_bounds.npy differ diff --git a/log/0221_correct/poses_bounds.npy b/log/0221_correct/poses_bounds.npy new file mode 100644 index 0000000..4c11834 Binary files /dev/null and b/log/0221_correct/poses_bounds.npy differ diff --git a/poses_bounds.npy b/poses_bounds.npy new file mode 100644 index 0000000..4c11834 Binary files /dev/null and b/poses_bounds.npy differ diff --git a/readnpy.py b/readnpy.py new file mode 100644 index 0000000..a68395d --- /dev/null +++ b/readnpy.py @@ -0,0 +1,6 @@ +import numpy as np + +# 读取.npy文件 +arr = np.load("/root/vmip/myProject/nerf/camera/nerfCalibration/poses_bounds.npy") +print(arr[0]) +print("load .npy done") \ No newline at end of file diff --git a/run.py b/run.py index c979827..740d779 100644 --- a/run.py +++ b/run.py @@ -1,8 +1,9 @@ -from utils.trans import json_write -from utils.calib import set_calibration +from utils.trans import json_write,json_write_llff +from utils.calib0218 import set_calibration if __name__ == '__main__': - set_calibration() - json_write() + f = 612 + c2w_metrix = set_calibration() + json_write_llff(c2w_metrix,f) diff --git a/testdraw.py b/testdraw.py new file mode 100644 index 0000000..67c86df --- /dev/null +++ b/testdraw.py @@ -0,0 +1,124 @@ +import cv2 +import numpy as np +import os +import sys +import glob +import pickle +import math + +import numpy as np +import matplotlib as mpl +from matplotlib import cm +from matplotlib import pyplot as plt +from mpl_toolkits.mplot3d import Axes3D + + +def show(): + # 创建画布 + fig = plt.figure(figsize=(12, 8), + facecolor='lightyellow' + ) + # 创建 3D 坐标系 + ax = fig.gca(fc='whitesmoke', + projection='3d' + ) + + + # -------------------------------- 绘制 3D 图形 -------------------------------- + # # 二元函数定义域平面 + # x = np.linspace(0, 9, 9) + # y = np.linspace(0, 9, 9) + # X, Y = np.meshgrid(x, y) + # # 平面 z=4.5 的部分 + # ax.plot_surface(X, + # Y, + # Z=X*0+4.5, + # color='g', + # alpha=0.6 + # ) + + # # 散点图 + # x = [1,2,3,4,5,6,7,8,9,10] + # y = [5,6,7,8,2,5,6,3,7,2] + # z = [1,2,6,3,2,7,3,3,7,2] + + # ax.scatter(x, y, z, c='g', marker='o') + + +def showquiver(): + # cp = [[1,2,3],[4,5,6]] + ax = plt.figure().add_subplot(projection='3d') + + # Make the grid + # x, y, z = np.meshgrid(np.arange(-0.8, 1, 0.2), + # np.arange(-0.8, 1, 0.2), + # np.arange(-0.8, 1, 0.8)) + x, y, z = np.meshgrid(np.arange(-0.8, 1, 0.2), + np.arange(-0.8, 1, 0.2), + np.arange(-0.8, 1, 0.8)) + + # Make the direction data for the arrows + u = np.sin(np.pi * x) * np.cos(np.pi * y) * np.cos(np.pi * z) + v = -np.cos(np.pi * x) * np.sin(np.pi * y) * np.cos(np.pi * z) + w = (np.sqrt(2.0 / 3.0) * np.cos(np.pi * x) * np.cos(np.pi * y) * + np.sin(np.pi * z)) + + ax.quiver(x, y, z, u, v, w, length=0.1, normalize=True) + plt.show() + +def plot(): + cp = [[1,2,3],[4,5,6]] + fig = plt.figure(figsize=(5, 5), + facecolor='white' + ) + # 创建 3D 坐标系 + ax = fig.gca(fc='white', + projection='3d' + ) + + # x1 = np.linspace(0,2,40) + # y1 = np.linspace(0,2,40) + x1,y1 = np.meshgrid() + x1, y1 = np.meshgrid(x1, y1) + z1 =x1**2+(2-y1)**2 + + ax.plot_surface(x1, y1, z1, rstride=1, cstride=1, cmap='rainbow') + + plt.show() + +def quiver(): + ax = plt.figure().add_subplot(projection='3d') + + # Make the grid + # x, y, z = np.meshgrid(np.arange(-0.8, 1, 0.2), + # np.arange(-0.8, 1, 0.2), + # np.arange(-0.8, 1, 0.8)) + # x,y,z = np.meshgrid([1,2,3],[4,5,6],[7,8,9]) + # u = [1,2,3] + # v = [4,5,6] + # w = [7,8,9] + l = np.array([[1],[4],[7]]) + x,y,z = np.meshgrid([l[0]],[l[1]],[l[2]]) + u = [1] + v = [4] + w = [7] + + print('x',x) + # Make the direction data for the arrows + # u = np.sin(np.pi * x) * np.cos(np.pi * y) * np.cos(np.pi * z) + # v = -np.cos(np.pi * x) * np.sin(np.pi * y) * np.cos(np.pi * z) + # w = (np.sqrt(2.0 / 3.0) * np.cos(np.pi * x) * np.cos(np.pi * y) * + # np.sin(np.pi * z)) + + ax.quiver(x, y, z, u, v, w, length=0.1, normalize=True) + + plt.show() + +def get(): + m = np.eye(3) + focal = m[0:1,0:1] + print(focal) + + +if __name__ == '__main__': + quiver() \ No newline at end of file diff --git a/utils/__init__.py b/utils/__init__.py index c22461f..ce9737e 100644 --- a/utils/__init__.py +++ b/utils/__init__.py @@ -1,3 +1,3 @@ -from .calib import set_calibration + from .utils import arse_config from .trans import json_write,read_pic \ No newline at end of file diff --git a/utils/calib.py b/utils/calib.py old mode 100755 new mode 100644 index 5bd6bc4..ac6fb77 --- a/utils/calib.py +++ b/utils/calib.py @@ -4,119 +4,244 @@ import sys import glob import pickle -import math +# import math from .utils import arse_config from .trans import read_pic, read_pic +import numpy as np +import matplotlib as mpl +from matplotlib import cm +from matplotlib import pyplot as plt +from mpl_toolkits.mplot3d import Axes3D + objpoints=[] imgpoints=[] +def show(c2w,cp): + # 创建画布 + fig = plt.figure(figsize=(5, 5), + facecolor='whitesmoke' + ) + # 创建 3D 坐标系 + ax = fig.gca(fc='whitesmoke', + projection='3d' + ) + # -------------------------------- 绘制 3D 图形 -------------------------------- + # # 二元函数定义域平面 + # x = np.linspace(0, 9, 9) + # y = np.linspace(0, 9, 9) + # X, Y = np.meshgrid(x, y) + # # 平面 z=4.5 的部分 + # ax.plot_surface(X, + # Y, + # Z=X*0+4.5, + # color='g', + # alpha=0.6 + # ) + # # 散点图 + dots = np.array(c2w).astype(int) # list,在画图前必须转为int类型 + print(dots.shape[0]) + for i in range(dots.shape[0]): + dot = dots[i] + print('dot:',dot) + print('i:',i) + print('dot[0][0]:',dot[0][0]) + print('dot[1]:',dot[1][0]) + + + ax.scatter(dot[0],dot[1],dot[2],c='g', marker='o') + ax.text(dot[0][3],dot[1][3],dot[2][3],i,fontsize=12, color = "r", style = "italic") + # -------------------------------- -------------------------------- + # 设置坐标轴标题和刻度 + ax.set(xlabel='X', + ylabel='Y', + zlabel='Z', + xlim=(0, 9), + ylim=(0, 9), + zlim=(0, 9), + xticks=np.arange(-200, 400, 60), + yticks=np.arange(-200, 400, 60), + zticks=np.arange(-600, 0, 60) + ) + + # 调整视角 + ax.view_init(elev=15, # 仰角 + azim=60 # 方位角 + ) + + # 显示图形 + plt.show() + +def showsurface(c2w,cp,rvecs,tvecs): + fig = plt.figure(figsize=(5, 5), + facecolor='whitesmoke' + ) + # 创建 3D 坐标系 + ax = fig.gca(fc='whitesmoke', + projection='3d' + ) + c2w = np.array(c2w) + cp = np.array(cp) + print('shape c2w:',c2w.shape) + print('shape cp:',cp.shape) + print('c2w[0]:',c2w[0]) + print('cp[0]:',cp[0]) + for i in range(cp.shape[0]): + print('i:',i) + print('cp[i][0]:',cp[i][0]) + print('cp.shape[0]:',cp.shape[0] ) + x,y,z = np.meshgrid(list(cp[i][0]),list(cp[i][1]),list(cp[i][2])) + # ax.scatter(x,y,z,c='g', marker='o') + + print('x:',x) + print('y:',y) + print('z:',z) + print('c2w[i]:',i) + # u = c2w[i][0] + # v = c2w[i][1] + # w = c2w[i][2] + # u, v, w = np.meshgrid(np.dot(cp[i],c2w[i])) + # u = np.dot(cp[i],c2w[i])[0] + # print('u:',u) + print('(np.dot(cp[i],c2w[i]):',(cp[i]*rvecs[i])+tvecs[i]) + w2c = (cp[i]*rvecs[i])+tvecs[i] + u = w2c*cp[i][0][0] + v = w2c*cp[i][1][0] + w = w2c*cp[i][2][0] + print('w2c*cp[i]:',w2c*cp[i] ) + print('type:',type(w2c*cp[i])) + print('w2c*cp[i][0][0]:',w2c*cp[i][0][0] ) + + # ax.scatter(u, v, w,c='g', marker='o') + + ax.quiver(x, y, z, u, v, w, length=0.1, normalize=True) + + plt.show() + -def draw(img, corners, imgpts): - corner = tuple(corners[0].ravel()) - img = cv2.line(img, corner, tuple(imgpts[0].ravel()), (255, 0, 0), 5) - img = cv2.line(img, corner, tuple(imgpts[1].ravel()), (0, 255, 0), 5) - img = cv2.line(img, corner, tuple(imgpts[2].ravel()), (0, 0, 255), 5) - return img # 获得像素坐标 -def calibration_photo(rvecs,tvecs,w1,h1): - tvecs = np.array(tvecs).reshape(3,1) - rvecs = np.array(rvecs).reshape(3,1) - objp = np.zeros((w1*h1,3), np.float32) - objp[:,:2] = np.mgrid[0:w1,0:h1].T.reshape(-1,2) - objp = objp*18.1 # 18.1 mm - - list1 = rvecs - in_site=np.mat(list1) - in_rr=in_site/180*math.pi - - #旋转向量转化为旋转矩阵 - in_r=cv2.Rodrigues(in_rr,jacobian=0)[0] - - #获得外参数矩阵 - list2 = tvecs - list2 = np.vstack((in_r,list2.reshape(1,3))) - - #列合并 - yi=np.mat([0,0,0,1]) - c2w_metrix=np.hstack((list2,yi.T)) - print('c2w_metrix:',c2w_metrix) - return(c2w_metrix) - -# # 计算位姿 -# def calibration(ret,mtx,dist,rvecs,tvecs,corners,w1,h1): -# tvecs = np.array(tvecs).reshape(3,1) -# rvecs = np.array(rvecs).reshape(3,1) -# objp = np.zeros((w1*h1,3), np.float32) -# objp[:,:2] = np.mgrid[0:w1,0:h1].T.reshape(-1,2) -# objp = objp*18.1 # 18.1 mm - -# list1 = rvecs -# in_site=np.mat(list1) -# in_rr=in_site/180*math.pi - -# # 找到图像平面点角点坐标 +def calibration_photo(inter_corner_shape, size_per_grid, img_dir,img_type): + # criteria: only for subpix calibration, which is not used here. + # criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001) + w,h = inter_corner_shape + # cp_int: corner point in int form, save the coordinate of corner points in world sapce in 'int' form + # like (0,0,0), (1,0,0), (2,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. + cp_world = cp_int*size_per_grid + + obj_points = [] # the points in world space + img_points = [] # the points in image space (relevant to obj_points) + images = glob.glob(img_dir + os.sep + '**.' + img_type) + for fname in images: + img = cv2.imread(fname) + gray_img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) + print("draw") + # 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 == True: + # cv2.cornerSubPix(gray_img,cp_img,(11,11),(-1,-1),criteria) + obj_points.append(cp_world) + img_points.append(cp_img) + # view the corners + cv2.drawChessboardCorners(img, (w,h), cp_img, ret) + cv2.imshow('FoundCorners',img) + cv2.waitKey(1) + cv2.destroyAllWindows() + # calibrate the camera,cv2.calibrateCamera() renturn the calibrate results + ret, mat_inter, coff_dis, v_rot, v_trans = cv2.calibrateCamera(obj_points, img_points, gray_img.shape[::-1], None, None) + # uv is image.shape[:2] + # calculate the error of reproject + + # newcameramtx, roi = cv2.getOptimalNewCameraMatrix(mat_inter, coff_dis,(480,640), 0, (480,640)) + total_error = 0 + for i in range(len(obj_points)): + img_points_repro, _ = cv2.projectPoints(obj_points[i], v_rot[i], v_trans[i], mat_inter, coff_dis) + error = cv2.norm(img_points[i], img_points_repro, cv2.NORM_L2)/len(img_points_repro) + total_error += error + print(("Average Error of Reproject: "), total_error/len(obj_points)) + + v_rot = np.array(v_rot) + v_trans = np.array(v_trans) + return v_rot,v_trans + + + +def get_c2w(v_rot,v_trans): + # print('shape v_rot:',v_rot[0].shape) + rotation_m, _ = cv2.Rodrigues(v_rot) #罗德里格斯变换 + # print("rotation_matrix:",rotation_m) + rotation_t = np.hstack([rotation_m,v_trans]) + rotation_t_Homogeneous_matrix = np.vstack([rotation_t,np.array([[0, 0, 0, 1]])]) + print('w2c:',rotation_t_Homogeneous_matrix) + c2w = np.linalg.inv(rotation_t_Homogeneous_matrix) + print('c2w:',c2w) + + + v_rot = np.array(v_rot,dtype = float) + v_trans = np.array(v_trans,dtype = float) + + return c2w + + +def get_pose(c2w,w1,h1,focal): + poses = c2w[:, :3, :4].transpose([1,2,0]) + hwf = np.array([h1,w1,focal]).reshape([3,1]) + poses = np.concatenate([poses, np.tile(hwf[..., np.newaxis], [1,1,poses.shape[-1]])], 1) -# ret =True - -# if ret: -# _,R,T=cv2.solvePnP(objp,corners,mtx,dist) -# print('所求结果:') -# print("旋转向量",R) -# print("平移向量",T) - - - -def get_inner_mtx(photo_path,w1,h1): - # number of coners - criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001) # 阈值 - objp = np.zeros((w1*h1,3), np.float32) - objp[:,:2] = np.mgrid[0:w1,0:h1].T.reshape(-1,2) - objp = objp*18.1 # 18.1 mm - img = cv2.imread(photo_path) - # print(img.shape) - #获取画面中心点 - #图像的长宽(480, 640, 3) - print() - h, w = img.shape[0], img.shape[1] - gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) - u, v = img.shape[:2] - # 找到棋盘格角点 - ret, corners = cv2.findChessboardCorners(gray, (w1,h1), None) - # 如果找到足够点对,将其存储起来 - if ret == True: - objpoints.append(objp) - imgpoints.append(corners) - - #标定 - ret, mtx, dist, rvecs, tvecs = \ - cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None) - return(ret,mtx,dist,rvecs,tvecs,corners) + # must switch to [-u, r, -t] from [r, -u, t], NOT [r, u, -t] + poses = np.concatenate([poses[:, 1:2, :], poses[:, 0:1, :], -poses[:, 2:3, :], poses[:, 3:4, :], poses[:, 4:5, :]], 1) + print('poses:',poses) + return poses + + +def saveBlender(c2w_metrix,camera_angle_x_metrix,rvecs): + os.makedirs(os.path.join(os.getcwd(),'log'),exist_ok=True) + f = os.path.join(os.getcwd(),'log','c2w_metrix.pkl') + log = {'c2w_metrix':c2w_metrix,'camera_angle_x':camera_angle_x_metrix,'rvecs':rvecs} + with open(f, 'wb') as file: + pickle.dump(log, file) + print('finish calibrating') def set_calibration(): + args = arse_config() read_pic(args.folder) - root = os.path.join(args.folder,'*.png') # 标定图像保存路径 - photos_path = glob.glob(root) - w1 = args.config[0] - h1 = args.config[1] + root = args.folder # 标定图像保存路径 + size_per_grid = args.size_per_grid + inter_corner_shape = args.inter_corner_shape + photos_path = glob.glob(os.path.join(root,'*.png')) c2w_metrix = [] + camera_angle_x_metrix = [] print('calibrating') - for photo_path in photos_path: - # mtx相机内参,dist相机畸变 - ret,mtx,dist,rvecs,tvecs,corners = get_inner_mtx(photo_path,w1,h1) - c2w = calibration_photo(rvecs[-1],tvecs[-1],w1,h1) - # c2w = calibration(ret,mtx,dist,rvecs[-1],tvecs[-1],corners,w1,h1) + v_rot,v_trans= calibration_photo(inter_corner_shape, size_per_grid, root,'png') + print('shape rot:',v_rot.shape) + print('trans rot:',v_trans.shape) + + print('photo_path',photos_path) + print('len(photos_path)',len(photos_path)) + for i in range(len(photos_path)): + print('i:',i) + # ret相机?? mtx相机内参,dist相机畸变,rvecs旋转向量,tvecs平移向量,focal焦距 + c2w = get_c2w(v_rot[i],v_trans[i]) + # pose = get_pose(c2w,cp,w1,h1,focal) c2w_metrix.append(c2w) + # pose_metrix.append(pose) + # showsurface(c2w_metrix,cp_mertix,rvecs,tvecs) + + print('camera_angle_x_metrix:',camera_angle_x_metrix) + + return c2w_metrix + + # saveBlender(c2w_metrix,camera_angle_x_metrix,rvecs) + + + - os.makedirs(os.path.join(os.getcwd(),'log'),exist_ok=True) - f = os.path.join(os.getcwd(),'log','c2w_metrix.pkl') - log = {'c2w_metrix':c2w_metrix,'ret':ret,'rvecs':rvecs} - with open(f, 'wb') as file: - pickle.dump(log, file) - print('finish calibrating') diff --git a/utils/calib0218.py b/utils/calib0218.py new file mode 100755 index 0000000..4566822 --- /dev/null +++ b/utils/calib0218.py @@ -0,0 +1,258 @@ +import cv2 +import numpy as np +import os +import sys +import glob +import pickle +# import math +from .utils import arse_config +from .trans import read_pic, read_pic + +import numpy as np +import matplotlib as mpl +from matplotlib import cm +from matplotlib import pyplot as plt +from mpl_toolkits.mplot3d import Axes3D + + +objpoints=[] +imgpoints=[] + +def show(c2w,cp): + # 创建画布 + fig = plt.figure(figsize=(5, 5), + facecolor='whitesmoke' + ) + # 创建 3D 坐标系 + ax = fig.gca(fc='whitesmoke', + projection='3d' + ) + # -------------------------------- 绘制 3D 图形 -------------------------------- + # # 二元函数定义域平面 + # x = np.linspace(0, 9, 9) + # y = np.linspace(0, 9, 9) + # X, Y = np.meshgrid(x, y) + # # 平面 z=4.5 的部分 + # ax.plot_surface(X, + # Y, + # Z=X*0+4.5, + # color='g', + # alpha=0.6 + # ) + # # 散点图 + dots = np.array(c2w).astype(int) # list,在画图前必须转为int类型 + print(dots.shape[0]) + for i in range(dots.shape[0]): + dot = dots[i] + print('dot:',dot) + print('i:',i) + print('dot[0][0]:',dot[0][0]) + print('dot[1]:',dot[1][0]) + + + ax.scatter(dot[0],dot[1],dot[2],c='g', marker='o') + ax.text(dot[0][3],dot[1][3],dot[2][3],i,fontsize=12, color = "r", style = "italic") + # -------------------------------- -------------------------------- + # 设置坐标轴标题和刻度 + ax.set(xlabel='X', + ylabel='Y', + zlabel='Z', + xlim=(0, 9), + ylim=(0, 9), + zlim=(0, 9), + xticks=np.arange(-200, 400, 60), + yticks=np.arange(-200, 400, 60), + zticks=np.arange(-600, 0, 60) + ) + + # 调整视角 + ax.view_init(elev=15, # 仰角 + azim=60 # 方位角 + ) + + # 显示图形 + plt.show() + +def showsurface(c2w,cp,rvecs,tvecs): + fig = plt.figure(figsize=(5, 5), + facecolor='whitesmoke' + ) + # 创建 3D 坐标系 + ax = fig.gca(fc='whitesmoke', + projection='3d' + ) + c2w = np.array(c2w) + cp = np.array(cp) + print('shape c2w:',c2w.shape) + print('shape cp:',cp.shape) + print('c2w[0]:',c2w[0]) + print('cp[0]:',cp[0]) + for i in range(cp.shape[0]): + print('i:',i) + print('cp[i][0]:',cp[i][0]) + print('cp.shape[0]:',cp.shape[0] ) + x,y,z = np.meshgrid(list(cp[i][0]),list(cp[i][1]),list(cp[i][2])) + # ax.scatter(x,y,z,c='g', marker='o') + + print('x:',x) + print('y:',y) + print('z:',z) + print('c2w[i]:',i) + # u = c2w[i][0] + # v = c2w[i][1] + # w = c2w[i][2] + # u, v, w = np.meshgrid(np.dot(cp[i],c2w[i])) + # u = np.dot(cp[i],c2w[i])[0] + # print('u:',u) + print('(np.dot(cp[i],c2w[i]):',(cp[i]*rvecs[i])+tvecs[i]) + w2c = (cp[i]*rvecs[i])+tvecs[i] + u = w2c*cp[i][0][0] + v = w2c*cp[i][1][0] + w = w2c*cp[i][2][0] + print('w2c*cp[i]:',w2c*cp[i] ) + print('type:',type(w2c*cp[i])) + print('w2c*cp[i][0][0]:',w2c*cp[i][0][0] ) + + # ax.scatter(u, v, w,c='g', marker='o') + + ax.quiver(x, y, z, u, v, w, length=0.1, normalize=True) + + plt.show() + + + + +# 获得像素坐标 +def calibration_photo(photo_path,mtx,dist): + # 设置要标定的角点个数 + x_nums = 11 # x方向上的角点个数 + y_nums = 8 + # 设置(生成)标定图在世界坐标中的坐标 + world_point = np.zeros((x_nums * y_nums, 3), np.float32) # 生成x_nums*y_nums个坐标,每个坐标包含x,y,z三个元素 + world_point[:, :2] = 15 * np.mgrid[:x_nums, :y_nums].T.reshape(-1, 2) # mgrid[]生成包含两个二维矩阵的矩阵,每个矩阵都有x_nums列,y_nums行 + # print('world point:',world_point) + # .T矩阵的转置 + # reshape()重新规划矩阵,但不改变矩阵元素 + # 设置世界坐标的坐标 + axis = 15* np.float32([[3, 0, 0], [0, 3, 0], [0, 0, -3]]).reshape(-1, 3) + # 设置角点查找限制 + criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001) + + image = cv2.imread(photo_path) + + gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) + # 查找角点 + ok, corners = cv2.findChessboardCorners(gray, (x_nums, y_nums), ) + # print(ok) + if ok: + # 获取更精确的角点位置 + exact_corners = cv2.cornerSubPix(gray, corners, (11, 11), (-1, -1), criteria) + + # 获取外参 + _, rvec, tvec, inliers = cv2.solvePnPRansac(world_point, exact_corners, mtx, dist) + #获得的旋转矩阵是向量,是3×1的矩阵,想要还原回3×3的矩阵,需要罗德里格斯变换Rodrigues, + + rotation_m, _ = cv2.Rodrigues(rvec)#罗德里格斯变换 + print("rotation_matrix:",rotation_m) + print('旋转矩阵是:\n', rvec) + print('平移矩阵是:\n', tvec) + rotation_t = np.hstack([rotation_m,tvec]) + rotation_t_Homogeneous_matrix = np.vstack([rotation_t,np.array([[0, 0, 0, 1]])]) + print('w2c',rotation_t_Homogeneous_matrix) + imgpts, jac = cv2.projectPoints(axis, rvec, tvec, mtx, dist) + # # 可视化角点 + # img = draw(image, corners, imgpts) + # cv2.imshow('img', img) + cameraPosition = -np.matrix(rotation_m).T * np.matrix(tvec) + # c2w = np.linalg.inv(rotation_t_Homogeneous_matrix) + c2w = np.linalg.inv(rotation_t_Homogeneous_matrix) + print('c2w',c2w) + print('cp',cameraPosition) + return c2w,cameraPosition # 返回旋转矩阵和平移矩阵组成的齐次矩阵 + +def get_pose(c2w,w1,h1,focal): + poses = c2w[:, :3, :4].transpose([1,2,0]) + hwf = np.array([h1,w1,focal]).reshape([3,1]) + poses = np.concatenate([poses, np.tile(hwf[..., np.newaxis], [1,1,poses.shape[-1]])], 1) + + # must switch to [-u, r, -t] from [r, -u, t], NOT [r, u, -t] + poses = np.concatenate([poses[:, 1:2, :], poses[:, 0:1, :], -poses[:, 2:3, :], poses[:, 3:4, :], poses[:, 4:5, :]], 1) + print('poses:',poses) + return poses + + +def get_inner_mtx(photo_path,w1,h1): + # number of coners + criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001) # 阈值 + objp = np.zeros((w1*h1,3), np.float32) + objp[:,:2] = np.mgrid[0:w1,0:h1].T.reshape(-1,2) + objp = objp*18.1 # 18.1 mm + img = cv2.imread(photo_path) + # print(img.shape) + #获取画面中心点 + #图像的长宽(480, 640, 3) + h, w = img.shape[0], img.shape[1] + gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) + u, v = img.shape[:2] + # 找到棋盘格角点 + ret, corners = cv2.findChessboardCorners(gray, (w1,h1), None) + # 如果找到足够点对,将其存储起来 + if ret == True: + objpoints.append(objp) + imgpoints.append(corners) + + #标定 + ret, mtx, dist, rvecs, tvecs = \ + cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None) + print('rvecs:',rvecs[0]) + print('tvecs:',tvecs[0]) + + print('mtx:',mtx) + focal = mtx[0:1,0:1] + print('focal:',focal) + camera_angle_x = np.arctan((focal/.5*w1))/0.5 + print('camera_angle_x:',camera_angle_x) + return(ret,mtx,dist,rvecs,tvecs,corners,focal,camera_angle_x,h,w) + +def saveBlender(c2w_metrix,camera_angle_x_metrix,rvecs): + os.makedirs(os.path.join(os.getcwd(),'log'),exist_ok=True) + f = os.path.join(os.getcwd(),'log','c2w_metrix.pkl') + log = {'c2w_metrix':c2w_metrix,'camera_angle_x':camera_angle_x_metrix,'rvecs':rvecs} + with open(f, 'wb') as file: + pickle.dump(log, file) + print('finish calibrating') + + +def set_calibration(): + + args = arse_config() + read_pic(args.folder) + root = os.path.join(args.folder,'*.png') # 标定图像保存路径 + photos_path = glob.glob(root) + w1 = args.config[0] + h1 = args.config[1] + c2w_metrix = [] + cp_mertix = [] + camera_angle_x_metrix = [] + print('calibrating') + for photo_path in photos_path: + # ret相机?? mtx相机内参,dist相机畸变,rvecs旋转向量,tvecs平移向量,focal焦距 + ret,mtx,dist,rvecs,tvecs,corners,focal,camera_angle_x,h,w = get_inner_mtx(photo_path,w1,h1) + c2w,cp = calibration_photo(photo_path,mtx,dist) + # pose = get_pose(c2w,cp,w1,h1,focal) + c2w_metrix.append(c2w) + cp_mertix.append(cp) + camera_angle_x_metrix.append(camera_angle_x) + # pose_metrix.append(pose) + showsurface(c2w_metrix,cp_mertix,rvecs,tvecs) + + print('camera_angle_x_metrix:',camera_angle_x_metrix) + + return c2w_metrix,h,w + + # saveBlender(c2w_metrix,camera_angle_x_metrix,rvecs) + + + + + diff --git a/utils/calibNot.py b/utils/calibNot.py new file mode 100755 index 0000000..3a126bd --- /dev/null +++ b/utils/calibNot.py @@ -0,0 +1,191 @@ +import cv2 +import numpy as np +import os +import sys +import glob +import pickle +import math +from .utils import arse_config +from .trans import read_pic, read_pic + + +objpoints=[] +imgpoints=[] + +def show(c2w,cp): + # 创建画布 + fig = plt.figure(figsize=(5, 5), + facecolor='whitesmoke' + ) + # 创建 3D 坐标系 + ax = fig.gca(fc='whitesmoke', + projection='3d' + ) + # -------------------------------- 绘制 3D 图形 -------------------------------- + # # 二元函数定义域平面 + # x = np.linspace(0, 9, 9) + # y = np.linspace(0, 9, 9) + # X, Y = np.meshgrid(x, y) + # # 平面 z=4.5 的部分 + # ax.plot_surface(X, + # Y, + # Z=X*0+4.5, + # color='g', + # alpha=0.6 + # ) + # # 散点图 + dots = np.array(c2w).astype(int) # list,在画图前必须转为int类型 + print(dots.shape[0]) + for i in range(dots.shape[0]): + dot = dots[i] + print('dot:',dot) + print('i:',i) + print('dot[0][0]:',dot[0][0]) + print('dot[1]:',dot[1][0]) + + + ax.scatter(dot[0],dot[1],dot[2],c='g', marker='o') + ax.text(dot[0][3],dot[1][3],dot[2][3],i,fontsize=12, color = "r", style = "italic") + # -------------------------------- -------------------------------- + # 设置坐标轴标题和刻度 + ax.set(xlabel='X', + ylabel='Y', + zlabel='Z', + xlim=(0, 9), + ylim=(0, 9), + zlim=(0, 9), + xticks=np.arange(-200, 400, 60), + yticks=np.arange(-200, 400, 60), + zticks=np.arange(-600, 0, 60) + ) + + # 调整视角 + ax.view_init(elev=15, # 仰角 + azim=60 # 方位角 + ) + + # 显示图形 + plt.show() + +def showsurface(c2w,cp,rvecs,tvecs): + fig = plt.figure(figsize=(5, 5), + facecolor='whitesmoke' + ) + # 创建 3D 坐标系 + ax = fig.gca(fc='whitesmoke', + projection='3d' + ) + c2w = np.array(c2w) + cp = np.array(cp) + print('shape c2w:',c2w.shape) + print('shape cp:',cp.shape) + print('c2w[0]:',c2w[0]) + print('cp[0]:',cp[0]) + for i in range(cp.shape[0]): + print('i:',i) + print('cp[i][0]:',cp[i][0]) + print('cp.shape[0]:',cp.shape[0] ) + x,y,z = np.meshgrid(list(cp[i][0]),list(cp[i][1]),list(cp[i][2])) + # ax.scatter(x,y,z,c='g', marker='o') + + print('x:',x) + print('y:',y) + print('z:',z) + print('c2w[i]:',i) + # u = c2w[i][0] + # v = c2w[i][1] + # w = c2w[i][2] + # u, v, w = np.meshgrid(np.dot(cp[i],c2w[i])) + # u = np.dot(cp[i],c2w[i])[0] + # print('u:',u) + print('(np.dot(cp[i],c2w[i]):',(cp[i]*rvecs[i])+tvecs[i]) + w2c = (cp[i]*rvecs[i])+tvecs[i] + u = w2c*cp[i][0][0] + v = w2c*cp[i][1][0] + w = w2c*cp[i][2][0] + print('w2c*cp[i]:',w2c*cp[i] ) + print('type:',type(w2c*cp[i])) + print('w2c*cp[i][0][0]:',w2c*cp[i][0][0] ) + + # ax.scatter(u, v, w,c='g', marker='o') + + ax.quiver(x, y, z, u, v, w, length=0.1, normalize=True) + + plt.show() + + + +# 获得像素坐标 +def calibration_photo(rvecs,tvecs,w1,h1): + tvecs = np.array(tvecs).reshape(3,1) + rvecs = np.array(rvecs).reshape(3,1) + objp = np.zeros((w1*h1,3), np.float32) + objp[:,:2] = np.mgrid[0:w1,0:h1].T.reshape(-1,2) + objp = objp*18.1 # 18.1 mm + + list1 = rvecs + in_site=np.mat(list1) + in_rr=in_site/180*math.pi + + #旋转向量转化为旋转矩阵 + in_r=cv2.Rodrigues(in_rr,jacobian=0)[0] + + R=in_r + t=tvecs + bottom = np.array([0,0,0,1.]).reshape([1,4]) + w2c_metrix=np.concatenate([np.concatenate([R, t], 1), bottom], 0) + print('w2c_metrix:',w2c_metrix) + c2w_metrix = np.linalg.inv(w2c_metrix) + print('c2w_metrix:',c2w_metrix) + return(c2w_metrix) + + +def get_inner_mtx(photo_path,w1,h1): + # number of coners + criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001) # 阈值 + objp = np.zeros((w1*h1,3), np.float32) + objp[:,:2] = np.mgrid[0:w1,0:h1].T.reshape(-1,2) + objp = objp*18.1 # 18.1 mm + img = cv2.imread(photo_path) + # print(img.shape) + #获取画面中心点 + #图像的长宽(480, 640, 3) + print() + h, w = img.shape[0], img.shape[1] + gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) + u, v = img.shape[:2] + # 找到棋盘格角点 + ret, corners = cv2.findChessboardCorners(gray, (w1,h1), None) + # 如果找到足够点对,将其存储起来 + if ret == True: + objpoints.append(objp) + imgpoints.append(corners) + + #标定 + ret, mtx, dist, rvecs, tvecs = \ + cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None) + return(ret,mtx,dist,rvecs,tvecs,corners,h,w) + + +def set_calibration(): + args = arse_config() + read_pic(args.folder) + root = os.path.join(args.folder,'*.png') # 标定图像保存路径 + photos_path = glob.glob(root) + w1 = args.config[0] + h1 = args.config[1] + c2w_metrix = [] + print('calibrating') + for photo_path in photos_path: + # mtx相机内参,dist相机畸变 + ret,mtx,dist,rvecs,tvecs,corners,h,w= get_inner_mtx(photo_path,w1,h1) + c2w = calibration_photo(rvecs[-1],tvecs[-1],w1,h1) + # c2w = calibration(ret,mtx,dist,rvecs[-1],tvecs[-1],corners,w1,h1) + c2w_metrix.append(c2w) + + + os.makedirs(os.path.join(os.getcwd(),'log'),exist_ok=True) + f = os.path.join(os.getcwd(),'log','c2w_metrix.pkl') + log = {'c2w_metrix':c2w_metrix,'ret':ret,'rvecs':rvecs,'h:':h,'w:':w} + return c2w_metrix,h,w + diff --git a/utils/load_blender.py b/utils/load_blender.py new file mode 100644 index 0000000..852a605 --- /dev/null +++ b/utils/load_blender.py @@ -0,0 +1,87 @@ +import os +import tensorflow as tf +import numpy as np +import imageio +import json + + + + +trans_t = lambda t : tf.convert_to_tensor([ + [1,0,0,0], + [0,1,0,0], + [0,0,1,t], + [0,0,0,1], +], dtype=tf.float32) + +rot_phi = lambda phi : tf.convert_to_tensor([ + [1,0,0,0], + [0,tf.cos(phi),-tf.sin(phi),0], + [0,tf.sin(phi), tf.cos(phi),0], + [0,0,0,1], +], dtype=tf.float32) + +rot_theta = lambda th : tf.convert_to_tensor([ + [tf.cos(th),0,-tf.sin(th),0], + [0,1,0,0], + [tf.sin(th),0, tf.cos(th),0], + [0,0,0,1], +], dtype=tf.float32) + + +def pose_spherical(theta, phi, radius): + c2w = trans_t(radius) + c2w = rot_phi(phi/180.*np.pi) @ c2w + c2w = rot_theta(theta/180.*np.pi) @ c2w + c2w = np.array([[-1,0,0,0],[0,0,1,0],[0,1,0,0],[0,0,0,1]]) @ c2w + return c2w + + + +def load_blender_data(basedir, half_res=False, testskip=1): + splits = ['train', 'val', 'test'] + metas = {} + for s in splits: + with open(os.path.join(basedir, 'transforms_{}.json'.format(s)), 'r') as fp: + metas[s] = json.load(fp) + + all_imgs = [] + all_poses = [] + counts = [0] + for s in splits: + meta = metas[s] + imgs = [] + poses = [] + if s=='train' or testskip==0: + skip = 1 + else: + skip = testskip + + for frame in meta['frames'][::skip]: + fname = os.path.join(basedir, frame['file_path'] + '.png') + imgs.append(imageio.imread(fname)) + poses.append(np.array(frame['transform_matrix'])) + imgs = (np.array(imgs) / 255.).astype(np.float32) # keep all 4 channels (RGBA) + poses = np.array(poses).astype(np.float32) + counts.append(counts[-1] + imgs.shape[0]) + all_imgs.append(imgs) + all_poses.append(poses) + + i_split = [np.arange(counts[i], counts[i+1]) for i in range(3)] + + imgs = np.concatenate(all_imgs, 0) + poses = np.concatenate(all_poses, 0) + + H, W = imgs[0].shape[:2] + camera_angle_x = float(meta['camera_angle_x']) + focal = .5 * W / np.tan(.5 * camera_angle_x) + + render_poses = tf.stack([pose_spherical(angle, -30.0, 4.0) for angle in np.linspace(-180,180,40+1)[:-1]],0) + + if half_res: + imgs = tf.image.resize_area(imgs, [400, 400]).numpy() + H = H//2 + W = W//2 + focal = focal/2. + + return imgs, poses, render_poses, [H, W, focal], i_split \ No newline at end of file diff --git a/utils/trans.py b/utils/trans.py index 8663d4c..7bc11ae 100755 --- a/utils/trans.py +++ b/utils/trans.py @@ -1,4 +1,5 @@ import argparse +from ctypes import sizeof import json import numpy as np import os @@ -11,12 +12,45 @@ def read_pic(root): # 重命名原图 i=0 - for item in os.listdir(root): + filenames=os.listdir(root) + print(filenames) + filenames.sort(key=lambda x:int(x[:-4])) + for item in filenames: pname = os.path.join(root,item) nname = os.path.join(root,'{:0>2d}'.format(i)+'.png') os.rename(pname,nname) i+=1 +def json_write_llff(c2w_metrix,f): + args = arse_config() + print(type(c2w_metrix)) # list + print(c2w_metrix[0]) + print(len(c2w_metrix)) + hw = args.inter_corner_shape + hwf = np.array([hw[1],hw[0],f]).reshape(3,1) + # print("hwf:",hwf) + # print((hwf).shape) + c2w_metrix = np.array(c2w_metrix) + print((c2w_metrix).shape) + poses = c2w_metrix[:, :3, :4].transpose([1,2,0]) + poses = np.concatenate([poses, np.tile(hwf[..., np.newaxis], [1,1,poses.shape[-1]])], 1) + poses = np.concatenate([poses[:, 1:2, :], poses[:, 0:1, :], -poses[:, 2:3, :], poses[:, 3:4, :], poses[:, 4:5, :]], 1) + + ## 不计算深度 + # poses = poses.transpose([2,0,1]) + # poses = np.reshape(poses,(-1,15)) + + save_arr = [] + for i in range(len(c2w_metrix)): + close_depth, inf_depth = 0,0 + # print( i, close_depth, inf_depth ) + save_arr.append(np.concatenate([poses[..., i].ravel(), np.array([close_depth, inf_depth])], 0)) + save_arr = np.array(save_arr) + print(save_arr[0]) + + np.save(os.path.join(os.getcwd(),'poses_bounds.npy'), save_arr) + print(".npy has been written") + def json_write(): args = arse_config() @@ -31,24 +65,25 @@ def json_write(): for file in files: s = str(os.path.join(args.folder,os.path.splitext(file)[0])) name.append(s) - #读取 - frames = [] for i in range(len(name)): dic = {} dic['file_path'] = name[i] # rot = np.array(data.get('rvecs'))[i] # dic['rotation'] = rot.tolist() - np_s = np.array(data.get('c2w_metrix'))[i].T + np_s = np.array(data.get('c2w_metrix'))[i] dic['transform_matrix'] = np_s.tolist() # print(dic) frames.append(dic) - print(frames) + # print(frames) + print("c2w_metrix:",np_s) - ca = np.array(data.get('ret')).tolist() - s = {'camera_angle_x':ca,'frames':frames} + # ca = np.array(data.get('camera_angle_x')).tolist()[0] + # print('ca:',data.get('camera_angle_x')[0]) + # s = {'camera_angle_x':float(ca[0][0]),'frames':frames} + s = {'frames':frames} js = json.dumps(s,indent=4) with open('./jsontrans.json', 'w') as f: diff --git a/utils/utils.py b/utils/utils.py index 3d6ee0c..ac76d51 100755 --- a/utils/utils.py +++ b/utils/utils.py @@ -3,9 +3,10 @@ def arse_config(): parser = argparse.ArgumentParser(description='') parser.add_argument('--folder', type=str, \ - default='./chess/train',\ + default='./chess/images',\ help="图片所在文件位置") - parser.add_argument('--config', type=format, default=[11,8],help="格子长宽数") + parser.add_argument('--inter_corner_shape', type=format, default=(11,8),help="格子长宽数") + parser.add_argument('--size_per_grid', type=format, default=0.02) args = parser.parse_args() return args \ No newline at end of file