CTPv 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- CTPv/Camera/Intrinsics.py +205 -0
- CTPv/Camera/__init__.py +0 -0
- CTPv/Plucker/Line.py +526 -0
- CTPv/Plucker/__init__.py +0 -0
- CTPv/Transformation/TransformationMatrix.py +381 -0
- CTPv/Transformation/__init__.py +0 -0
- CTPv/__init__.py +0 -0
- ctpv-0.1.0.dist-info/METADATA +474 -0
- ctpv-0.1.0.dist-info/RECORD +12 -0
- ctpv-0.1.0.dist-info/WHEEL +5 -0
- ctpv-0.1.0.dist-info/licenses/LICENSE +7 -0
- ctpv-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,205 @@
|
|
1
|
+
import numpy as np
|
2
|
+
import os
|
3
|
+
from ..Plucker.Line import Line
|
4
|
+
|
5
|
+
class RadialDistortion:
|
6
|
+
"""Handles radial distortion parameters for a camera model."""
|
7
|
+
|
8
|
+
def __init__(self, k1=0, k2=0, k3=0):
|
9
|
+
self.k1 = k1
|
10
|
+
self.k2 = k2
|
11
|
+
self.k3 = k3
|
12
|
+
|
13
|
+
def set_from_list(self, coeffs):
|
14
|
+
if len(coeffs) != 3:
|
15
|
+
raise ValueError("List must contain exactly three elements.")
|
16
|
+
self.k1, self.k2, self.k3 = coeffs
|
17
|
+
|
18
|
+
|
19
|
+
class IntrinsicMatrix:
|
20
|
+
"""Encapsulates intrinsic parameters of a pinhole camera model."""
|
21
|
+
|
22
|
+
def __init__(self):
|
23
|
+
self.fx = None
|
24
|
+
self.fy = None
|
25
|
+
self.cx = None
|
26
|
+
self.cy = None
|
27
|
+
self.s = 0
|
28
|
+
self.width = None
|
29
|
+
self.height = None
|
30
|
+
self.RadialDistortion = RadialDistortion()
|
31
|
+
self._MatlabIntrinsics = np.zeros((3, 3))
|
32
|
+
self._OpenCVIntrinsics = np.zeros((3, 3))
|
33
|
+
self.pixel_size = None # e.g., 0.0034 mm
|
34
|
+
self.info = None # e.g., camera ID or lens metadata
|
35
|
+
|
36
|
+
@property
|
37
|
+
def MatlabIntrinsics(self):
|
38
|
+
"""
|
39
|
+
generation call method for returning Matlab matrix format of intrinsic parameters of a camera
|
40
|
+
Returns:
|
41
|
+
I = 3x3 matrix
|
42
|
+
[ fx 0 cx ]
|
43
|
+
[ 0 fy cy ]
|
44
|
+
[ 0 0 1 ]
|
45
|
+
|
46
|
+
"""
|
47
|
+
I = np.zeros((3, 3))
|
48
|
+
I[0, 0] = self.fx
|
49
|
+
I[1, 1] = self.fy
|
50
|
+
I[2, 0] = self.cx
|
51
|
+
I[2, 1] = self.cy
|
52
|
+
I[2, 2] = 1
|
53
|
+
return I
|
54
|
+
|
55
|
+
@MatlabIntrinsics.setter
|
56
|
+
def MatlabIntrinsics(self, I):
|
57
|
+
"""
|
58
|
+
Extraction call method for extracting Matlab matrix format of intrinsic parameters of a camera to local class,
|
59
|
+
parameters are registered to every parameter as per the following structure.
|
60
|
+
I = [ fx 0 cx ]
|
61
|
+
[ 0 fy cy ]
|
62
|
+
[ 0 0 1 ]
|
63
|
+
|
64
|
+
"""
|
65
|
+
self.fx = I[0, 0]
|
66
|
+
self.fy = I[1, 1]
|
67
|
+
self.cx = I[2, 0]
|
68
|
+
self.cy = I[2, 1]
|
69
|
+
self.s = I[1, 0]
|
70
|
+
|
71
|
+
@property
|
72
|
+
def OpenCVIntrinsics(self):
|
73
|
+
"""
|
74
|
+
generation call method for returning OpenCV matrix format of intrinsic parameters of a camera
|
75
|
+
Returns:
|
76
|
+
I = 3x3 matrix
|
77
|
+
[ fx 0 cx ]
|
78
|
+
[ 0 fy cy ]
|
79
|
+
[ 0 0 1 ]
|
80
|
+
|
81
|
+
"""
|
82
|
+
I = np.zeros((3, 3))
|
83
|
+
I[0, 0] = self.fx
|
84
|
+
I[1, 1] = self.fy
|
85
|
+
I[0, 2] = self.cx
|
86
|
+
I[1, 2] = self.cy
|
87
|
+
I[2, 2] = 1
|
88
|
+
return I
|
89
|
+
|
90
|
+
@OpenCVIntrinsics.setter
|
91
|
+
def OpenCVIntrinsics(self, I):
|
92
|
+
"""
|
93
|
+
Extraction call method for extracting OpenCV matrix format of intrinsic parameters of a camera to local class,
|
94
|
+
parameters are registered to every parameter as per the following structure.
|
95
|
+
I = [ fx 0 cx ]
|
96
|
+
[ 0 fy cy ]
|
97
|
+
[ 0 0 1 ]
|
98
|
+
|
99
|
+
"""
|
100
|
+
self.fx = I[0, 0]
|
101
|
+
self.fy = I[1, 1]
|
102
|
+
self.cx = I[0, 2]
|
103
|
+
self.cy = I[1, 2]
|
104
|
+
self.s = 0
|
105
|
+
|
106
|
+
@property
|
107
|
+
def focal_length_mm(self):
|
108
|
+
"""Returns focal length in mm."""
|
109
|
+
if self.pixel_size is None:
|
110
|
+
raise ValueError('Pixel size not set!')
|
111
|
+
return self.fx * self.pixel_size, self.fy * self.pixel_size
|
112
|
+
|
113
|
+
@property
|
114
|
+
def PerspectiveAngle(self):
|
115
|
+
"""Returns horizontal or vertical perspective angle in degrees."""
|
116
|
+
if self.width is None:
|
117
|
+
raise ValueError('Set width first.')
|
118
|
+
|
119
|
+
aspectRatio = self.width / self.height
|
120
|
+
if aspectRatio > 1:
|
121
|
+
return 2 * np.arctan(self.width / (2 * self.fx)) * 180 / np.pi
|
122
|
+
else:
|
123
|
+
return 2 * np.arctan(self.height / (2 * self.fy)) * 180 / np.pi
|
124
|
+
|
125
|
+
@PerspectiveAngle.setter
|
126
|
+
def PerspectiveAngle(self, p):
|
127
|
+
if self.width is None:
|
128
|
+
raise ValueError('Set width first.')
|
129
|
+
|
130
|
+
aspectRatio = self.width / self.height
|
131
|
+
if aspectRatio > 1:
|
132
|
+
self.fx = (self.width / 2) / np.tan(p / 2)
|
133
|
+
self.fy = self.fx
|
134
|
+
else:
|
135
|
+
self.fy = (self.height / 2) / np.tan(p / 2)
|
136
|
+
self.fx = self.fy
|
137
|
+
|
138
|
+
self.cx = self.width / 2
|
139
|
+
self.cy = self.height / 2
|
140
|
+
|
141
|
+
def CameraParams2Intrinsics(self, CameraParams):
|
142
|
+
try:
|
143
|
+
self.width = CameraParams.ImageSize[1]
|
144
|
+
self.height = CameraParams.ImageSize[0]
|
145
|
+
except AttributeError:
|
146
|
+
print('Camera not open, set resolution manually.')
|
147
|
+
self.MatlabIntrinsics = CameraParams.IntrinsicMatrix
|
148
|
+
|
149
|
+
def Intrinsics2CameraParams(self):
|
150
|
+
P = {
|
151
|
+
'IntrinsicMatrix': self.MatlabIntrinsics,
|
152
|
+
'ImageSize': [self.height, self.width]
|
153
|
+
}
|
154
|
+
if self.RadialDistortion:
|
155
|
+
P['RadialDistortion'] = self.RadialDistortion
|
156
|
+
return P
|
157
|
+
|
158
|
+
def ScaleIntrinsics(self, Scale):
|
159
|
+
"""Scales all intrinsic parameters and image size by a given factor."""
|
160
|
+
self.fx *= Scale
|
161
|
+
self.fy *= Scale
|
162
|
+
self.cx *= Scale
|
163
|
+
self.cy *= Scale
|
164
|
+
self.width *= Scale
|
165
|
+
self.height *= Scale
|
166
|
+
|
167
|
+
def save_intrinsics_to_json(self, filename):
|
168
|
+
"""Serialize camera intrinsics to a JSON file."""
|
169
|
+
import json
|
170
|
+
directory = os.path.dirname(filename)
|
171
|
+
if directory:
|
172
|
+
os.makedirs(directory, exist_ok=True)
|
173
|
+
|
174
|
+
data = {
|
175
|
+
'OpenCVIntrinsics': self.OpenCVIntrinsics.tolist(),
|
176
|
+
'RadialDistortion': {
|
177
|
+
'k1': self.RadialDistortion.k1,
|
178
|
+
'k2': self.RadialDistortion.k2,
|
179
|
+
'k3': self.RadialDistortion.k3
|
180
|
+
},
|
181
|
+
'width': self.width,
|
182
|
+
'height': self.height,
|
183
|
+
'pixel_size': self.pixel_size,
|
184
|
+
'info': self.info
|
185
|
+
}
|
186
|
+
with open(filename, 'w') as f:
|
187
|
+
json.dump(data, f, indent=4)
|
188
|
+
|
189
|
+
def load_intrinsics_from_json(self, filename):
|
190
|
+
"""Load camera intrinsics from a JSON file."""
|
191
|
+
import json
|
192
|
+
with open(filename, 'r') as f:
|
193
|
+
data = json.load(f)
|
194
|
+
|
195
|
+
self.OpenCVIntrinsics = np.array(data['OpenCVIntrinsics'])
|
196
|
+
self.RadialDistortion.set_from_list([
|
197
|
+
data['RadialDistortion']['k1'],
|
198
|
+
data['RadialDistortion']['k2'],
|
199
|
+
data['RadialDistortion']['k3']
|
200
|
+
])
|
201
|
+
self.width = data['width']
|
202
|
+
self.height = data['height']
|
203
|
+
self.pixel_size = data['pixel_size']
|
204
|
+
self.info = data['info']
|
205
|
+
return self
|
CTPv/Camera/__init__.py
ADDED
File without changes
|