2023-03-23 20:42:41 +08:00
|
|
|
# This file is part of OpenCV project.
|
|
|
|
# It is subject to the license terms in the LICENSE file found in the top-level directory
|
|
|
|
# of this distribution and at http://opencv.org/license.html.
|
|
|
|
|
|
|
|
import numpy as np
|
|
|
|
import math
|
|
|
|
import cv2 as cv
|
|
|
|
import json
|
|
|
|
|
|
|
|
class RandGen:
|
|
|
|
def __init__(self, seed = 0):
|
|
|
|
self.rand_gen = np.random.RandomState(seed)
|
|
|
|
|
|
|
|
def randRange(self, min_v, max_v):
|
|
|
|
return self.rand_gen.rand(1).item() * (max_v - min_v) + min_v
|
|
|
|
|
|
|
|
def project(K, R, t, dist, pts_3d, is_fisheye):
|
|
|
|
if is_fisheye:
|
|
|
|
pts_2d = cv.fisheye.projectPoints(pts_3d.T[None,:], cv.Rodrigues(R)[0], t, K, dist.flatten())[0].reshape(-1,2).T
|
|
|
|
else:
|
|
|
|
pts_2d = cv.projectPoints(pts_3d, R, t, K, dist)[0].reshape(-1,2).T
|
|
|
|
return pts_2d
|
|
|
|
|
|
|
|
def projectCamera(camera, pts_3d):
|
|
|
|
return project(camera.K, camera.R, camera.t, camera.distortion, pts_3d, camera.is_fisheye)
|
|
|
|
|
|
|
|
def eul2rot(theta): # [x y z]
|
|
|
|
# https://learnopencv.com/rotation-matrix-to-euler-angles/
|
|
|
|
R_x = np.array([[1, 0, 0 ],
|
|
|
|
[0, math.cos(theta[0]), -math.sin(theta[0]) ],
|
|
|
|
[0, math.sin(theta[0]), math.cos(theta[0]) ]])
|
|
|
|
R_y = np.array([[math.cos(theta[1]), 0, math.sin(theta[1]) ],
|
|
|
|
[0, 1, 0 ],
|
|
|
|
[-math.sin(theta[1]), 0, math.cos(theta[1]) ]])
|
|
|
|
R_z = np.array([[math.cos(theta[2]), -math.sin(theta[2]), 0],
|
|
|
|
[math.sin(theta[2]), math.cos(theta[2]), 0],
|
|
|
|
[0, 0, 1]])
|
|
|
|
return np.dot(R_z, np.dot(R_y, R_x))
|
|
|
|
|
|
|
|
def insideImageMask(pts, w, h):
|
|
|
|
return np.logical_and(np.logical_and(pts[0] < w, pts[1] < h), np.logical_and(pts[0] > 0, pts[1] > 0))
|
|
|
|
|
|
|
|
def insideImage(pts, w, h):
|
|
|
|
return insideImageMask(pts, w, h).sum()
|
|
|
|
|
|
|
|
def areAllInsideImage(pts, w, h):
|
|
|
|
return insideImageMask(pts, w, h).all()
|
|
|
|
|
2024-02-14 20:17:01 +08:00
|
|
|
def writeMatrix(file, label, M):
|
|
|
|
file.write("%s:\n" % label)
|
2023-03-23 20:42:41 +08:00
|
|
|
for i in range(M.shape[0]):
|
|
|
|
for j in range(M.shape[1]):
|
|
|
|
file.write(str(M[i,j]) + ('\n' if j == M.shape[1]-1 else ' '))
|
|
|
|
|
|
|
|
def saveKDRT(cameras, fname):
|
|
|
|
file = open(fname, 'w')
|
2024-02-14 20:17:01 +08:00
|
|
|
for idx, cam in enumerate(cameras):
|
|
|
|
file.write("camera_%d:\n" % idx)
|
|
|
|
writeMatrix(file, "K", cam.K)
|
|
|
|
writeMatrix(file, "distortion", cam.distortion)
|
|
|
|
writeMatrix(file, "R", cam.R)
|
|
|
|
writeMatrix(file, "T", cam.t)
|
2023-03-23 20:42:41 +08:00
|
|
|
|
|
|
|
def export2JSON(pattern_points, image_points, image_sizes, is_fisheye, json_file):
|
|
|
|
image_points = image_points.transpose(1,0,3,2)
|
|
|
|
image_points_list = [[] for i in range(len(image_sizes))]
|
|
|
|
for c in range(len(image_points)):
|
|
|
|
for f in range(len(image_points[c])):
|
2024-02-14 19:26:18 +08:00
|
|
|
if insideImage(image_points[c][f].T, image_sizes[c][0], image_sizes[c][1]) >= 4:
|
|
|
|
mask = np.logical_not(insideImageMask(image_points[c][f].T, image_sizes[c][0], image_sizes[c][1]))
|
|
|
|
image_points[c][f][mask] = -1.
|
2023-03-23 20:42:41 +08:00
|
|
|
image_points_list[c].append(image_points[c][f].tolist())
|
|
|
|
else:
|
|
|
|
image_points_list[c].append([])
|
|
|
|
json.dump({'object_points': pattern_points.tolist(), 'image_points': image_points_list, 'image_sizes': image_sizes, 'is_fisheye': is_fisheye}, open(json_file, 'w'))
|