diff --git a/openptv_python/calibration.py b/openptv_python/calibration.py index dcda921..f9f1ff0 100644 --- a/openptv_python/calibration.py +++ b/openptv_python/calibration.py @@ -58,7 +58,6 @@ def rotation_matrix(ext: np.ndarray) -> None: ('kappa', np.float64), ('dm', np.float64, (3, 3)) ]) -# Exterior = np.zeros(1, dtype=exterior_dtype).view(np.recarray) # initialize memory Exterior = np.array((0, 0, 0, 0, 0, 0, np.eye(3)), dtype = exterior_dtype).view(np.recarray) rotation_matrix(Exterior) # rotation should be a unit matrix assert np.allclose(np.eye(3), Exterior['dm']) @@ -70,13 +69,6 @@ def rotation_matrix(ext: np.ndarray) -> None: ]) Interior = np.array( (0, 0, 0), dtype = interior_dtype).view(np.recarray) -# def set_primary_point(point: np.ndarray) -> None: -# """Set the primary point of the camera.""" -# self.xh, self.yh, self.cc = point - -# def set_back_focal_distance(self, cc: float) -> None: -# """Set the back focal distance of the camera.""" -# self.cc = cc ap52_dtype = np.dtype([ ('k1', np.float64), @@ -89,60 +81,27 @@ def rotation_matrix(ext: np.ndarray) -> None: ]) ap_52 = np.array((0, 0, 0, 0, 0, 1, 0), dtype = ap52_dtype).view(np.recarray) - -# class ap_52: -# """Additional parameters for distortion correction.""" - -# def __init__(self, k1=0.0, k2=0.0, k3=0.0, p1=0.0, p2=0.0, scx=1.0, she=0.0): -# self.k1 = k1 -# self.k2 = k2 -# self.k3 = k3 -# self.p1 = p1 -# self.p2 = p2 -# self.scx = scx -# self.she = she - -# def set_radial_distortion(self, dist_array: np.ndarray) -> None: -# """Set the radial distortion parameters k1, k2, k3.""" -# self.k1, self.k2, self.k3 = dist_array - -# def set_decentering(self, decent: np.ndarray) -> None: -# """Set the decentring parameters p1 and p2.""" -# self.p1, self.p2 = decent - -# def set_affine_distortion(self, affine: np.ndarray) -> None: -# """Set the affine distortion parameters scx and she.""" -# self.scx, self.she = affine - mmlut_dtype = np.dtype([ ('origin', np.float64, 3), ('nr', np.int32), ('nz', np.int32), ('rw', np.int32), - ('data', np.float64, (3, 3)) ]) -mm_lut = np.array((np.zeros(3), 0, 0, 0, np.zeros((3, 3))), dtype = mmlut_dtype).view(np.recarray) - -# class mm_lut: -# """Multimedia lookup table data structure.""" - -# def __init__(self, origin=None, nr=3, nz=3, rw=0, data=None): -# if origin is None: -# origin = np.zeros(3, dtype=np.float32) -# # if data is None: -# # data = np.zeros((nr, nz), dtype=np.float32) # Assuming data is a 2D array, adjust as needed -# self.origin = origin -# self.nr = nr -# self.nz = nz -# self.rw = rw -# self.data = data +mm_lut = np.array((np.zeros(3), 0, 0, 0), dtype = mmlut_dtype).view(np.recarray) +mm_lut_data = np.empty((mm_lut['nr'], mm_lut['nz']), dtype=np.float64) class Calibration: """Calibration data structure.""" - def __init__(self, ext_par=None, int_par=None, glass_par=None, added_par=None, mmlut=None): + def __init__(self, + ext_par=None, + int_par=None, + glass_par=None, + added_par=None, + mmlut=None, + mmlut_data=None): if ext_par is None: ext_par = Exterior.copy() if int_par is None: @@ -152,13 +111,17 @@ def __init__(self, ext_par=None, int_par=None, glass_par=None, added_par=None, m if added_par is None: added_par = ap_52.copy() if mmlut is None: - mmlut = mm_lut.copy() # (np.zeros(3), 0, 0, 0, None) + mmlut = mm_lut.copy() # (np.zeros(3), 0, 0, 0) + if mmlut_data is None: + mmlut_data = np.zeros((mmlut.nr, mmlut.nz), dtype=np.float64) + self.ext_par = ext_par self.int_par = int_par self.glass_par = glass_par self.added_par = added_par self.mmlut = mmlut + self.mmlut_data = mmlut_data @classmethod @@ -205,7 +168,7 @@ def from_file(cls, ori_file: str, add_file: str): tmp = [float(x) for x in fp.readline().split()] # xh,yh tmp += [float(x) for x in fp.readline().split()] # cc - ret.int_par.set_primary_point(np.array(tmp)) + ret.set_primary_point(np.array(tmp)) # self.int_par.set_back_focal_distance(float(fp.readline())) # Glass @@ -224,9 +187,9 @@ def from_file(cls, ori_file: str, add_file: str): with open(add_file, "r", encoding="utf-8") as fp: tmp = list(map(float, fp.readline().split())) - ret.added_par.set_radial_distortion(np.array(tmp[:3])) - ret.added_par.set_decentering(np.array(tmp[3:5])) - ret.added_par.set_affine_distortion(np.array(tmp[5:])) + ret.set_radial_distortion(np.array(tmp[:3])) + ret.set_decentering(np.array(tmp[3:5])) + ret.set_affine_distortion(np.array(tmp[5:])) except FileNotFoundError: print("no addpar fallback used") # Waits for proper logging. @@ -324,10 +287,11 @@ def set_primary_point(self, prim_point_pos: np.ndarray) -> None: of point from sensor middle and sensor-point distance, int_par this order. """ - if len(prim_point_pos) != 3: - raise ValueError("Expected a 3-element list") + if prim_point_pos.shape != (3,): + raise ValueError("Expected a 3-element array") - self.int_par.set_primary_point(prim_point_pos) + self.int_par.xh, self.int_par.yh, self.int_par.cc = prim_point_pos + # self.int_par.set_primary_point(prim_point_pos) def get_primary_point(self): """ @@ -349,10 +313,11 @@ def set_radial_distortion(self, dist_coeffs: np.ndarray) -> None: --------- dist_coeffs - length-3 array, holding k_i. """ - if len(dist_coeffs) != 3: + if dist_coeffs.shape != (3,): raise ValueError("Expected a 3-element array") - self.added_par.set_radial_distortion(dist_coeffs) + self.added_par.k1, self.added_par.k2, self.added_par.k3 = dist_coeffs + def get_radial_distortion(self): """ @@ -370,19 +335,16 @@ def set_decentering(self, decent: np.ndarray) -> None: --------- decent - array, holding p_i """ - if len(decent) != 2: + if decent.shape != (2,): raise ValueError("Expected a 2-element list") - self.added_par.set_decentering(decent) + self.added_par.p1, self.added_par.p2 = decent def get_decentering(self): """Return the decentering parameters [1] as a 2 element array, (p_1, p_2).""" - ret = np.empty(2) - ret[0] = self.added_par.p1 - ret[1] = self.added_par.p2 - return ret + return np.r_[self.added_par.p1, self.added_par.p2] - def set_affine_trans(self, affine: np.ndarray) -> None: + def set_affine_distortion(self, affine: np.ndarray) -> None: """ Set the affine transform parameters (x-scale, shear) of the image. @@ -390,9 +352,10 @@ def set_affine_trans(self, affine: np.ndarray) -> None: --------- affine - array, holding (x-scale, shear) int_par order. """ - if len(affine) != 2: + if affine.shape != (2,): raise ValueError("Expected a 2-element list") - self.added_par.set_affine_distortion(affine) + + self.added_par.scx, self.added_par.she = affine def get_affine(self): """Return the affine transform parameters [1] as a 2 element array, (scx, she).""" @@ -419,9 +382,9 @@ def get_glass_vec(self) -> np.ndarray: """Return the glass vector, a 3-element array of float.""" return self.glass_par - def set_added_par(self, listpar: np.ndarray | list): + def set_added_par(self, ap52_array: np.ndarray): """Set added par from an numpy array of parameters.""" - self.added_par = np.array(listpar, dtype=ap52_dtype).view(np.recarray) + self.added_par = np.array(tuple(ap52_array.tolist()), dtype = ap52_dtype).view(np.recarray) def copy(self, new_copy): """Copy the calibration data to a new object.""" @@ -486,7 +449,7 @@ def read_ori(ori_file: str, add_file: str) -> Calibration: return ret -def compare_exterior(e1: np.ndarray, e2: np.ndarray) -> bool: +def compare_exterior(e1: np.recarray, e2: np.recarray) -> bool: """Compare exterior orientation parameters.""" return ( np.allclose(e1['dm'], e2['dm'], atol=1e-6) diff --git a/openptv_python/constants.py b/openptv_python/constants.py index c6795c5..feadd89 100644 --- a/openptv_python/constants.py +++ b/openptv_python/constants.py @@ -29,4 +29,4 @@ NUM_ITER = 80 POS_INF = 1e20 -CONVERGENCE = 0.00001 +CONVERGENCE = 0.0001 diff --git a/openptv_python/multimed.py b/openptv_python/multimed.py index be3e67f..e2df360 100644 --- a/openptv_python/multimed.py +++ b/openptv_python/multimed.py @@ -34,7 +34,7 @@ def multimed_r_nlay(cal: Calibration, mm: MultimediaPar, pos: np.ndarray) -> flo return 1.0 # interpolation using the existing mmlut - if cal.mmlut.data is not None: + if cal.mmlut_data.shape != (0, 0): # print("going into get_mmf_from_mmlut\n") mmf = get_mmf_from_mmlut(cal, pos) if mmf > 0: @@ -273,7 +273,7 @@ def init_mmlut(vpar: VolumePar, cpar: ControlPar, cal: Calibration) -> Calibrati z_max_t = z_max # intersect with image vertices rays - cal_t = Calibration(mmlut=cal.mmlut) + cal_t = Calibration(mmlut = cal.mmlut.copy()) for i in range(2): for j in range(2): @@ -330,8 +330,8 @@ def init_mmlut(vpar: VolumePar, cpar: ControlPar, cal: Calibration) -> Calibrati cal.mmlut.nz = nz cal.mmlut.rw = rw - if cal.mmlut.data is None: - data = np.empty((nr, nz), dtype=np.float64) + if cal.mmlut_data.shape == (0, 0): + cal.mmlut_data = np.empty((nr, nz), dtype=np.float64) Ri = np.arange(nr) * rw Zi = np.arange(nz) * rw + z_min_t @@ -339,10 +339,10 @@ def init_mmlut(vpar: VolumePar, cpar: ControlPar, cal: Calibration) -> Calibrati for j in range(nz): xyz = np.r_[Ri[i] + cal_t.ext_par.x0, cal_t.ext_par.y0, Zi[j]] - data.flat[i * nz + j] = multimed_r_nlay(cal_t, cpar.mm, xyz) + cal.mmlut_data.flat[i * nz + j] = multimed_r_nlay(cal_t, cpar.mm, xyz) # print(f"filled mmlut data with {data}") - cal.mmlut.data = data + # cal.mmlut_data = data return cal @@ -351,15 +351,13 @@ def get_mmf_from_mmlut(cal: Calibration, pos: np.ndarray) -> float: """Get the refractive index of the medium at a given position.""" rw = cal.mmlut.rw origin = cal.mmlut.origin - data = cal.mmlut.data.flatten() # type: ignore + data = cal.mmlut_data.flatten() # type: ignore nz = cal.mmlut.nz nr = cal.mmlut.nr return fast_get_mmf_from_mmlut(rw, origin, data, nz, nr, pos) # @njit - - def fast_get_mmf_from_mmlut( rw: int, origin: np.ndarray, diff --git a/openptv_python/orientation.py b/openptv_python/orientation.py index 6cbd6d2..655f132 100644 --- a/openptv_python/orientation.py +++ b/openptv_python/orientation.py @@ -489,13 +489,13 @@ def orient( ) # Interpret the results - print( - f"Coefficients (beta): {beta} \n \ - Residuals: {residuals} \n \ - singular_values: {singular_values} \n \ - rank: {rank} \n \ - " - ) + # print( + # f"Coefficients (beta): {beta} \n \ + # Residuals: {residuals} \n \ + # singular_values: {singular_values} \n \ + # rank: {rank} \n \ + # " + # ) # stopflag stopflag = True diff --git a/openptv_python/parameters.py b/openptv_python/parameters.py index be59071..eefeec1 100644 --- a/openptv_python/parameters.py +++ b/openptv_python/parameters.py @@ -714,9 +714,10 @@ class OrientPar(Parameters): @classmethod def from_file(cls, filename: str): """Read orientation parameters from file and returns orient_par object.""" + ret = cls() try: with open(filename, "r", encoding="utf-8") as file: - ret = cls() + ret.useflag = int(file.readline().strip()) # /* use every point or every other pt */ ret.ccflag = int(file.readline().strip()) # /* change back focal distance */ ret.xhflag = int(file.readline().strip()) # /* change xh point, 1-yes, 0-no */ @@ -729,10 +730,11 @@ def from_file(cls, filename: str): ret.scxflag = int(file.readline().strip()) # /* scx - scaling */ ret.sheflag = int(file.readline().strip()) # /* she - shearing */ ret.interfflag = int(file.readline().strip()) # /* interface glass vector */ - return ret + except IOError: print(f"Could not open orientation parameters file {filename}.") - return None + + return ret diff --git a/openptv_python/trafo.py b/openptv_python/trafo.py index 42b8dc3..051bc6c 100644 --- a/openptv_python/trafo.py +++ b/openptv_python/trafo.py @@ -5,7 +5,7 @@ from numba import float64, int32, njit from numpy import cos, sin, sqrt -from .calibration import Calibration, ap_52 +from .calibration import Calibration from .parameters import ControlPar @@ -147,7 +147,7 @@ def fast_arr_metric_to_pixel( def distort_brown_affine(x: float, y: float, - ap: ap_52 + ap: np.recarray, ) -> Tuple[float, float]: """Distort a point using the Brown affine model.""" if x == 0 and y == 0: @@ -160,7 +160,9 @@ def distort_brown_affine(x: float, # print(f"x {x}, y {y}") -@njit(float64[:](float64,float64,float64,float64,float64,float64,float64,float64,float64)) +# @njit(float64[:] +# (float64,float64,float64,float64,float64, +# float64,float64,float64,float64)) def fast_distort_brown_affine( x: float, y: float, @@ -198,7 +200,7 @@ def fast_distort_brown_affine( def correct_brown_affine( - x: float, y: float, ap: ap_52, tol: float = 1e-5 + x: float, y: float, ap: np.recarray, tol: float = 1e-5 ) -> Tuple[float, float]: """Correct a distorted point using the Brown affine model.""" return fast_correct_brown_affine(x, y, ap.k1, ap.k2, ap.k3, ap.p1, ap.p2, ap.she, ap.scx, tol) diff --git a/tests/test_calibration_binding.py b/tests/test_calibration_binding.py index 0c94b4e..ad54826 100644 --- a/tests/test_calibration_binding.py +++ b/tests/test_calibration_binding.py @@ -51,17 +51,19 @@ def test_full_instantiate(self): ext['phi'] = 4.0 ext['kappa'] = 6.0 - In = Interior(xh=3.0, yh=9.0, cc=15.0) + In = np.array((3.0, 9.0, 15.0),dtype=Interior.dtype).view(np.recarray) + G = np.array(glass) - addpar = ap_52( - k1=rad_dist[0], - k2=rad_dist[1], - k3=rad_dist[2], - p1=decent[0], - p2=decent[1], - scx=affine[0], - she=affine[1], - ) + + addpar = np.array(( + rad_dist[0], + rad_dist[1], + rad_dist[2], + decent[0], + decent[1], + affine[0], + affine[1]),dtype=ap_52.dtype).view(np.recarray) + cal = Calibration() cal.ext_par = ext @@ -173,11 +175,11 @@ class TestCompareAddpar(unittest.TestCase): def test_compare_addpar(self): """Test compare_addpar() function.""" - a1 = ap_52(1, 2, 3, 4, 5, 6, 7) - a2 = ap_52(1, 2, 3, 4, 5, 6, 7) + a1 = np.array((1, 2, 3, 4, 5, 6, 7),dtype=ap_52.dtype).view(np.recarray) + a2 = np.array((1, 2, 3, 4, 5, 6, 7),dtype=ap_52.dtype).view(np.recarray) self.assertTrue(compare_addpar(a1, a2)) - a3 = ap_52(1, 2, 3, 4, 6, 6, 7) + a3 = np.array((1, 2, 3, 4, 6, 6, 7),dtype=ap_52.dtype).view(np.recarray) self.assertFalse(compare_addpar(a1, a3)) diff --git a/tests/test_calibration_class.py b/tests/test_calibration_class.py index 27da6cd..3644bcf 100644 --- a/tests/test_calibration_class.py +++ b/tests/test_calibration_class.py @@ -47,17 +47,20 @@ def test_mmlut_initialization(self): assert mml.nr == 0 assert mml.nz == 0 assert mml.rw == 0 - assert mml.data is None + assert mml.data.shape == () # assert isinstance(mml.data, np.ndarray) # assert mml.data.shape == (3,) def test_calibration_initialization(self): """Test calibration parameters initialization.""" assert self.cal.ext_par.dtype == Exterior.dtype - assert isinstance(self.cal.int_par, Interior) + assert self.cal.int_par.dtype == Interior.dtype assert isinstance(self.cal.glass_par, np.ndarray) - assert isinstance(self.cal.added_par, ap_52) - assert isinstance(self.cal.mmlut, mm_lut) + assert self.cal.added_par.dtype == ap_52.dtype + assert self.cal.mmlut.dtype == mm_lut.dtype + + assert isinstance(self.cal.added_par, np.recarray) + assert isinstance(self.cal.mmlut, np.recarray) def test_exterior_initialization(self): """Test exterior parameters initialization.""" diff --git a/tests/test_epipolar.py b/tests/test_epipolar.py index ae52a9e..a626432 100644 --- a/tests/test_epipolar.py +++ b/tests/test_epipolar.py @@ -90,9 +90,10 @@ def test_epi_mm_2D(self): test_Ex.z0 = 100.0 - test_I = Interior(0.0, 0.0, 100.0) + test_I = Interior.copy() + test_I.cc = 100.0 test_G = np.array((0.0, 0.0, 50.0)) - test_addp = ap_52(0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0) + test_addp = ap_52.copy()# (0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0) test_cal = Calibration(test_Ex, test_I, test_G, test_addp) test_mm = MultimediaPar(1, 1.0, [1.49, 0.0, 0.0], [ @@ -132,9 +133,10 @@ def test_epi_mm(self): test_Ex.z0 = 100.0 test_Ex.phi = -.01 - test_I = Interior(0.0, 0.0, 100.0) + test_I = Interior.copy() + test_I.cc = 100.0 test_G = np.array((0.0, 0.0, 50.0)) - test_addp = ap_52(0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0) + test_addp = ap_52.copy()# (0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0) test_cal_1 = Calibration(test_Ex, test_I, test_G, test_addp) test_Ex_2 = Exterior.copy() @@ -167,9 +169,10 @@ def test_epi_mm_perpendicular(self): """Test the epi_mm function.""" test_Ex = Exterior.copy() test_Ex.z0 = 100.0 - test_I = Interior(0.0, 0.0, 100.0) + test_I = Interior.copy() + test_I.cc = 100.0 test_G = np.array((0.0, 0.0, 50.0)) - test_addp = ap_52(0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0) + test_addp = ap_52.copy()#(0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0) test_cal_1 = Calibration(test_Ex, test_I, test_G, test_addp) test_Ex_2 = Exterior.copy() @@ -248,9 +251,10 @@ def test_find_candidate(self): test_Ex = Exterior.copy() test_Ex.z0 = 100. - test_I = Interior(0.0, 0.0, 100.0) + test_I = Interior.copy() + test_I.cc = 100.0 test_G = np.array((0.0, 0.0, 50.0)) - test_addp = ap_52(0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0) + test_addp = ap_52.copy()# (0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0) test_cal = Calibration(test_Ex, test_I, test_G, test_addp) test_mm = MultimediaPar(1, 1.0, [1.49, 0.0, 0.0], [ 5.0, 0.0, 0.0], 1.33) diff --git a/tests/test_get_mmlut.py b/tests/test_get_mmlut.py index 920e1a1..296068a 100644 --- a/tests/test_get_mmlut.py +++ b/tests/test_get_mmlut.py @@ -19,7 +19,8 @@ def setUp(self): self.vpar = read_volume_par(self.vol_file) self.cpar = read_control_par(self.ptv_file) self.correct_mmlut = [ - mm_lut(origin=np.array([0.0, 0.0, -250.00001105]), nr=130, nz=177, rw=2) + np.array(( (0.0, 0.0, -250.00001105), 130, 177, 2), + dtype=mm_lut.dtype).view(np.recarray) for _ in range(4) ] diff --git a/tests/test_img_coord.py b/tests/test_img_coord.py index e8af025..af6a124 100644 --- a/tests/test_img_coord.py +++ b/tests/test_img_coord.py @@ -46,12 +46,12 @@ def test_img_coord_typecheck(self): def test_image_coord_regress(self): """Test image coordinates for a simple case.""" self.calibration.set_pos(np.array([0, 0, 40])) - self.calibration.set_angles([0, 0, 0]) + self.calibration.set_angles(np.array([0, 0, 0])) self.calibration.set_primary_point(np.array([0, 0, 10])) self.calibration.set_glass_vec(np.array([0, 0, 20])) self.calibration.set_radial_distortion(np.array([0, 0, 0])) self.calibration.set_decentering(np.array([0, 0])) - self.calibration.set_affine_trans(np.array([1, 0])) + self.calibration.set_affine_distortion(np.array([1, 0])) # self.mult = MultimediaPar(n1=1, n2=np.array([1]), n3=1, d=np.array([1])) diff --git a/tests/test_imgcoord.py b/tests/test_imgcoord.py index f2bd128..2ed5f34 100644 --- a/tests/test_imgcoord.py +++ b/tests/test_imgcoord.py @@ -23,9 +23,9 @@ def test_flat_centered_cam(self): ext_par = np.array((0, 0, 40, 0, 0, 0, [[1, 0, 0], [0, 1, 0], [0, 0, 1]]), dtype = Exterior.dtype).view(np.recarray), - int_par=Interior(0, 0, 10), + int_par = np.array((0,0,10), dtype = Interior.dtype).view(np.recarray), glass_par=np.array((0., 0., 20.)), - added_par=ap_52(0, 0, 0, 0, 0, 1, 0), + added_par=ap_52.copy() # (0, 0, 0, 0, 0, 1, 0), ) mm = MultimediaPar( # All in air, simplest case. nlay=1, n1=1, n2=[1], n3=1, d=[1] diff --git a/tests/test_init_mmlut.py b/tests/test_init_mmlut.py index f27c389..0d46794 100644 --- a/tests/test_init_mmlut.py +++ b/tests/test_init_mmlut.py @@ -1,6 +1,8 @@ import unittest from pathlib import Path +import numpy as np + from openptv_python.calibration import mm_lut, read_calibration from openptv_python.multimed import init_mmlut from openptv_python.parameters import read_control_par, read_volume_par @@ -27,12 +29,14 @@ def test_init_mmLUT(self): self.assertIsNotNone(cpar, "\n control parameter file reading failed\n ") # test_mmlut = [mmlut() for _ in range(cpar.num_cams)] - correct_mmlut = mm_lut( - origin=(0.0, 0.0, -250.00001105), - nr=130, - nz=177, - rw=2, - ) + correct_mmlut = np.array(( + (0.0, 0.0, -250.00001105), + 130, + 177, + 2), + dtype = mm_lut.dtype) + correct_mmlut = correct_mmlut.view(np.recarray) + # run init_mmLUT for one camera only cpar.num_cams = 1 @@ -40,7 +44,7 @@ def test_init_mmLUT(self): # Data[0] Is the radial shift of a point directly on the glass vector - data = cal.mmlut.data.flatten() + data = cal.mmlut_data.flatten() self.assertAlmostEqual(data[0], 1) diff --git a/tests/test_multimedia_r_nlay.py b/tests/test_multimedia_r_nlay.py index f803edf..184ecb5 100644 --- a/tests/test_multimedia_r_nlay.py +++ b/tests/test_multimedia_r_nlay.py @@ -20,9 +20,10 @@ def test_multimedia_r_nlay(self): test_Ex = Exterior.copy() test_Ex['z0'] = 100.0 - test_I = Interior(0.0, 0.0, 100.0) + test_I = Interior.copy() + test_I.cc = 100.0 test_G = np.array((0.0001, 0.00001, 1.0)) - test_addp = ap_52(0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0) + test_addp = ap_52.copy() #(0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0) test_cal = Calibration( test_Ex, test_I, test_G, test_addp ) # note that mmlut is default diff --git a/tests/test_orientation.py b/tests/test_orientation.py index f074906..5e07d2c 100644 --- a/tests/test_orientation.py +++ b/tests/test_orientation.py @@ -61,10 +61,10 @@ def test_match_detection_to_ref(self): target_array[i].set_pos((xy_img_pts_pixel[i][0], xy_img_pts_pixel[i][1])) # create randomized target array - indices = list(range(coords_count)) - shuffled_indices = list(range(coords_count)) + indices = np.arange(coords_count) + shuffled_indices = np.arange(coords_count) - while indices == shuffled_indices: + while np.all(indices == shuffled_indices): np.random.shuffle(shuffled_indices) rand_targ_array = TargetArray(coords_count) @@ -344,6 +344,214 @@ def test_full_calibration(self): self.cal.set_pos(self.cal.get_pos() + np.r_[15.0, -15.0, 15.0]) self.cal.set_angles(self.cal.get_angles() + np.r_[-0.5, 0.5, -0.5]) + + self.orient_par.ccflag=0 + self.orient_par.xhflag=0 + self.orient_par.yhflag=0 + print(f"Calibrating with the following flags: {self.orient_par}") + + _, _, _ = full_calibration( + self.cal, + ref_pts, + target_array, + self.control, + self.orient_par + ) + + np.testing.assert_array_almost_equal( + self.cal.get_angles(), self.orig_cal.get_angles(), decimal=4 + ) + np.testing.assert_array_almost_equal( + self.cal.get_pos(), self.orig_cal.get_pos(), decimal=3 + ) + + print(f"{self.cal.get_pos()}") + print(f"{self.cal.get_angles()}") + print(f"{self.cal.added_par}") + + # Perturb the calibration object, then compore result to original. + self.cal.set_pos(self.cal.get_pos() + np.r_[1.0, -1.0, 1.0]) + self.cal.set_angles(self.cal.get_angles() + np.r_[-0.1, 0.1, -0.1]) + + self.orient_par.ccflag=1 + self.orient_par.xhflag=1 + self.orient_par.yhflag=1 + print(f"Calibrating with the following flags: {self.orient_par}") + + _, _, _ = full_calibration( + self.cal, + ref_pts, + target_array, + self.control, + self.orient_par + ) + + np.testing.assert_array_almost_equal( + self.cal.get_angles(), self.orig_cal.get_angles(), decimal=4 + ) + np.testing.assert_array_almost_equal( + self.cal.get_pos(), self.orig_cal.get_pos(), decimal=3 + ) + + print(f"{self.cal.get_pos()}") + print(f"{self.cal.get_angles()}") + print(f"{self.cal.added_par}") + + # Perturb the calibration object, then compore result to original. + # self.cal.set_pos(self.cal.get_pos() + np.r_[1.0, -1.0, 1.0]) + # self.cal.set_angles(self.cal.get_angles() + np.r_[-0.1, 0.1, -0.1]) + + self.orient_par.ccflag=0 + self.orient_par.xhflag=0 + self.orient_par.yhflag=0 + self.orient_par.k1flag=0 + self.orient_par.k2flag=0 + self.orient_par.k3flag=0 + self.orient_par.scxflag=0 + self.orient_par.sheflag=1 + print(f"Calibrating with the following flags: {self.orient_par}") + + _, _, _ = full_calibration( + self.cal, + ref_pts, + target_array, + self.control, + self.orient_par + ) + + np.testing.assert_array_almost_equal( + self.cal.get_angles(), self.orig_cal.get_angles(), decimal=4 + ) + np.testing.assert_array_almost_equal( + self.cal.get_pos(), self.orig_cal.get_pos(), decimal=3 + ) + print(f"{self.cal.get_pos()}") + print(f"{self.cal.get_angles()}") + print(f"{self.cal.added_par}") + + self.orient_par.ccflag=0 + self.orient_par.xhflag=0 + self.orient_par.yhflag=0 + self.orient_par.k1flag=0 + self.orient_par.k2flag=0 + self.orient_par.k3flag=0 + self.orient_par.scxflag=1 + self.orient_par.sheflag=0 + print(f"Calibrating with the following flags: {self.orient_par}") + + _, _, _ = full_calibration( + self.cal, + ref_pts, + target_array, + self.control, + self.orient_par + ) + + np.testing.assert_array_almost_equal( + self.cal.get_angles(), self.orig_cal.get_angles(), decimal=4 + ) + np.testing.assert_array_almost_equal( + self.cal.get_pos(), self.orig_cal.get_pos(), decimal=3 + ) + print(f"{self.cal.get_pos()}") + print(f"{self.cal.get_angles()}") + print(f"{self.cal.added_par}") + + self.orient_par.ccflag=0 + self.orient_par.xhflag=0 + self.orient_par.yhflag=0 + self.orient_par.k1flag=0 + self.orient_par.k2flag=0 + self.orient_par.k3flag=1 + self.orient_par.scxflag=0 + self.orient_par.sheflag=0 + print(f"Calibrating with the following flags: {self.orient_par}") + + _, _, _ = full_calibration( + self.cal, + ref_pts, + target_array, + self.control, + self.orient_par + ) + + np.testing.assert_array_almost_equal( + self.cal.get_angles(), self.orig_cal.get_angles(), decimal=4 + ) + np.testing.assert_array_almost_equal( + self.cal.get_pos(), self.orig_cal.get_pos(), decimal=3 + ) + print(f"{self.cal.get_pos()}") + print(f"{self.cal.get_angles()}") + print(f"{self.cal.added_par}") + + self.orient_par.ccflag=0 + self.orient_par.xhflag=0 + self.orient_par.yhflag=0 + self.orient_par.k1flag=0 + self.orient_par.k2flag=1 + self.orient_par.k3flag=0 + self.orient_par.scxflag=0 + self.orient_par.sheflag=0 + print(f"Calibrating with the following flags: {self.orient_par}") + + _, _, _ = full_calibration( + self.cal, + ref_pts, + target_array, + self.control, + self.orient_par + ) + + np.testing.assert_array_almost_equal( + self.cal.get_angles(), self.orig_cal.get_angles(), decimal=4 + ) + np.testing.assert_array_almost_equal( + self.cal.get_pos(), self.orig_cal.get_pos(), decimal=3 + ) + print(f"{self.cal.get_pos()}") + print(f"{self.cal.get_angles()}") + print(f"{self.cal.added_par}") + + self.orient_par.ccflag=0 + self.orient_par.xhflag=0 + self.orient_par.yhflag=0 + self.orient_par.k1flag=1 + self.orient_par.k2flag=0 + self.orient_par.k3flag=0 + self.orient_par.scxflag=0 + self.orient_par.sheflag=0 + print(f"Calibrating with the following flags: {self.orient_par}") + + _, _, _ = full_calibration( + self.cal, + ref_pts, + target_array, + self.control, + self.orient_par + ) + + np.testing.assert_array_almost_equal( + self.cal.get_angles(), self.orig_cal.get_angles(), decimal=4 + ) + np.testing.assert_array_almost_equal( + self.cal.get_pos(), self.orig_cal.get_pos(), decimal=3 + ) + print(f"{self.cal.get_pos()}") + print(f"{self.cal.get_angles()}") + print(f"{self.cal.added_par}") + + self.orient_par.ccflag=0 + self.orient_par.xhflag=0 + self.orient_par.yhflag=0 + self.orient_par.k1flag=0 + self.orient_par.k2flag=0 + self.orient_par.k3flag=1 + self.orient_par.scxflag=0 + self.orient_par.sheflag=0 + self.orient_par.p1flag=1 + self.orient_par.p2floag=0 + print(f"Calibrating with the following flags: {self.orient_par}") _, _, _ = full_calibration( @@ -360,7 +568,39 @@ def test_full_calibration(self): np.testing.assert_array_almost_equal( self.cal.get_pos(), self.orig_cal.get_pos(), decimal=3 ) + print(f"{self.cal.get_pos()}") + print(f"{self.cal.get_angles()}") + print(f"{self.cal.added_par}") + + self.orient_par.ccflag=0 + self.orient_par.xhflag=0 + self.orient_par.yhflag=0 + self.orient_par.k1flag=0 + self.orient_par.k2flag=0 + self.orient_par.k3flag=0 + self.orient_par.scxflag=0 + self.orient_par.sheflag=0 + self.orient_par.p1flag=1 + self.orient_par.p2flag=1 + print(f"Calibrating with the following flags: {self.orient_par}") + _, _, _ = full_calibration( + self.cal, + ref_pts, + target_array, + self.control, + self.orient_par + ) + + np.testing.assert_array_almost_equal( + self.cal.get_angles(), self.orig_cal.get_angles(), decimal=4 + ) + np.testing.assert_array_almost_equal( + self.cal.get_pos(), self.orig_cal.get_pos(), decimal=3 + ) + print(f"{self.cal.get_pos()}") + print(f"{self.cal.get_angles()}") + print(f"{self.cal.added_par}") if __name__ == "__main__": unittest.main() diff --git a/tests/test_ray_tracing.py b/tests/test_ray_tracing.py index 6eefa5f..66bc466 100644 --- a/tests/test_ray_tracing.py +++ b/tests/test_ray_tracing.py @@ -39,13 +39,14 @@ def test_ray_tracing_bard(self): test_Ex.dm=np.array(((1.0, 0.2, -0.3), (0.2, 1.0, 0.0), (-0.3, 0.0, 1.0))) # The interior parameters - test_I = Interior(0.0, 0.0, 100.0) + test_I = Interior.copy() + test_I.cc = 100.0 # The glass parameters test_G = np.array((0.0001, 0.00001, 1.0)) # The addp parameters - test_addp = ap_52(0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0) + test_addp = ap_52.copy() # (0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0) # The calibration parameters test_cal = Calibration(test_Ex, test_I, test_G, test_addp) diff --git a/tests/test_trafo.py b/tests/test_trafo.py index 956f16d..bb9f00e 100644 --- a/tests/test_trafo.py +++ b/tests/test_trafo.py @@ -41,7 +41,7 @@ def test_metric_to_pixel(self): output = arr_metric_to_pixel( np.array([[0.0, 0.0], [1.0, 0.0], [0.0, -1.0]]), cpar ) - assert np.allclose(output, [[512, 504], [612, 504], [512, 604]]) + assert np.allclose(output, np.array([[512, 504], [612, 504], [512, 604]])) class TestDistFlatRoundTrip(unittest.TestCase): @@ -79,7 +79,8 @@ def test_round_trip(self): def test_shear_distortion(self): """Test the shear distortion parameter.""" x, y = 1.0, 1.0 - ap = ap_52(she=1.0) + ap = ap_52.copy() + ap.she=1.0 xp, yp = distort_brown_affine(x, y, ap) self.assertAlmostEqual(xp, 0.158529) self.assertAlmostEqual(yp, 0.5403023) @@ -136,7 +137,7 @@ def test_round_trip2(self): """ x, y = 1.0, 1.0 eps = 1e-5 - ap = ap_52() # no distortion + ap = ap_52.copy() # no distortion xres, yres = distort_brown_affine(x, y, ap) xres, yres = correct_brown_affine(xres, yres, ap) @@ -152,7 +153,8 @@ def test_shear_round_trip(self): """ x, y = -1.0, 10.0 eps = 1e-5 - ap = ap_52(she=1.0) # no distortion + ap = ap_52.copy() + # ap.she = 1.0 # no distortion xres, yres = distort_brown_affine(x, y, ap) xres, yres = correct_brown_affine(xres, yres, ap) @@ -343,13 +345,13 @@ def test_brown_affine(self): """Distortion and correction of pixel coordinates.""" # This is all based on values from liboptv/tests/check_imgcoord.c cal = Calibration() - cal.set_pos([0.0, 0.0, 40.0]) - cal.set_angles([0.0, 0.0, 0.0]) + cal.set_pos(np.array([0.0, 0.0, 40.0])) + cal.set_angles(np.array([0.0, 0.0, 0.0])) cal.set_primary_point(np.array([0.0, 0.0, 10.0])) cal.set_glass_vec(np.r_[0.0, 0.0, 20.0]) cal.set_radial_distortion(np.zeros(3,)) cal.set_decentering(np.zeros(2,)) - cal.set_affine_trans(np.array([1,0])) + cal.set_affine_distortion(np.array([1,0])) # reference metric positions: ref_pos = np.array([[0.1, 0.1], [1.0, -1.0], [-10.0, 10.0]]) @@ -382,7 +384,7 @@ def test_full_correction(self): cal.set_glass_vec(np.r_[0.0, 0.0, 20.0]) cal.set_radial_distortion(np.zeros(3,)) cal.set_decentering(np.zeros(2,)) - cal.set_affine_trans(np.array([1, 0])) + cal.set_affine_distortion(np.array([1, 0])) # reference metric positions: # Note the last value is different than in test_brown_affine() because diff --git a/tests/test_trafo_mockup.py b/tests/test_trafo_mockup.py index 93e6908..7364d6a 100644 --- a/tests/test_trafo_mockup.py +++ b/tests/test_trafo_mockup.py @@ -1,6 +1,8 @@ import copy import unittest +import numpy as np + from openptv_python.calibration import Calibration, Interior from openptv_python.parameters import ControlPar from openptv_python.trafo import ( @@ -44,7 +46,7 @@ def test_positive_coordinates(self): def test_distortion(self): cal = copy.copy(self.cal) - cal.set_added_par([1e-5, 0, 0, 0, 0, 1, 0]) + cal.set_added_par(np.array([1e-5, 0, 0, 0, 0, 1, 0])) dist_x, dist_y = flat_to_dist(100, 200, cal) self.assertAlmostEqual(dist_x, 150, places=3) self.assertAlmostEqual(dist_y, 300, places=3) diff --git a/tests/test_trans_cam_point.py b/tests/test_trans_cam_point.py index 04ec000..79c1b5d 100644 --- a/tests/test_trans_cam_point.py +++ b/tests/test_trans_cam_point.py @@ -21,20 +21,7 @@ def test_back_trans_point(self): correct_Ex_t = Exterior.copy() correct_Ex_t.z0 = 99.0 - # ( - # x0=0.0, - # y0=0.0, - # z0=99.0, - # omega=-0.0, - # phi=0.0, - # kappa=0.0, - # dm=np.array([[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]]), - # ) - - # test_I = Interior(0.0, 0.0, 100.0) test_G = np.array((0.0001, 0.00001, 1.0)) - # test_addp = ap_52(0., 0., 0., 0., 0., 1., 0.) - # test_cal = Calibration(test_Ex, test_I, test_G, test_addp) # test_mm = MultimediaPar(1, 1.0, [1.49, 0.0, 0.0], [5.0, 0.0, 0.0], 1.33)