opencv/apps/python-calibration-generator/utils.py
2024-02-14 15:17:01 +03:00

76 lines
3.3 KiB
Python

# 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()
def writeMatrix(file, label, M):
file.write("%s:\n" % label)
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')
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)
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])):
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.
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'))