@@ -79,22 +79,69 @@ def process(
79
79
# self.load_points3D() # For now, we do not need the point cloud data.
80
80
81
81
# Assume shared intrinsics between all cameras.
82
- cam = self .cameras [1 ]
82
+ cams = {}
83
+ for cam_id , cam in self .cameras .items ():
84
+ # Extract focal lengths and principal point parameters.
85
+ fx , fy , cx , cy = cam .fx , cam .fy , cam .cx , cam .cy
86
+ pixtocam = np .linalg .inv (camera_utils .intrinsic_matrix (fx , fy , cx , cy ))
87
+
88
+ # Get distortion parameters.
89
+ type_ = cam .camera_type
90
+
91
+ if type_ == 0 or type_ == 'SIMPLE_PINHOLE' :
92
+ params = None
93
+ camtype = camera_utils .ProjectionType .PERSPECTIVE
94
+
95
+ elif type_ == 1 or type_ == 'PINHOLE' :
96
+ params = None
97
+ camtype = camera_utils .ProjectionType .PERSPECTIVE
98
+
99
+ if type_ == 2 or type_ == 'SIMPLE_RADIAL' :
100
+ params = {k : 0. for k in ['k1' , 'k2' , 'k3' , 'p1' , 'p2' ]}
101
+ params ['k1' ] = cam .k1
102
+ camtype = camera_utils .ProjectionType .PERSPECTIVE
103
+
104
+ elif type_ == 3 or type_ == 'RADIAL' :
105
+ params = {k : 0. for k in ['k1' , 'k2' , 'k3' , 'p1' , 'p2' ]}
106
+ params ['k1' ] = cam .k1
107
+ params ['k2' ] = cam .k2
108
+ camtype = camera_utils .ProjectionType .PERSPECTIVE
109
+
110
+ elif type_ == 4 or type_ == 'OPENCV' :
111
+ params = {k : 0. for k in ['k1' , 'k2' , 'k3' , 'p1' , 'p2' ]}
112
+ params ['k1' ] = cam .k1
113
+ params ['k2' ] = cam .k2
114
+ params ['p1' ] = cam .p1
115
+ params ['p2' ] = cam .p2
116
+ camtype = camera_utils .ProjectionType .PERSPECTIVE
117
+
118
+ elif type_ == 5 or type_ == 'OPENCV_FISHEYE' :
119
+ params = {k : 0. for k in ['k1' , 'k2' , 'k3' , 'k4' ]}
120
+ params ['k1' ] = cam .k1
121
+ params ['k2' ] = cam .k2
122
+ params ['k3' ] = cam .k3
123
+ params ['k4' ] = cam .k4
124
+ camtype = camera_utils .ProjectionType .FISHEYE
125
+ cams [cam_id ] = (cam , pixtocam , params , camtype )
83
126
84
- # Extract focal lengths and principal point parameters.
85
- fx , fy , cx , cy = cam .fx , cam .fy , cam .cx , cam .cy
86
- pixtocam = np .linalg .inv (camera_utils .intrinsic_matrix (fx , fy , cx , cy ))
87
127
88
128
# Extract extrinsic matrices in world-to-camera format.
89
129
imdata = self .images
90
130
w2c_mats = []
131
+ pixtocams = []
132
+ all_params = []
133
+ all_camtypes = []
91
134
bottom = np .array ([0 , 0 , 0 , 1 ]).reshape (1 , 4 )
92
135
for k in imdata :
93
136
im = imdata [k ]
94
137
rot = im .R ()
95
138
trans = im .tvec .reshape (3 , 1 )
96
139
w2c = np .concatenate ([np .concatenate ([rot , trans ], 1 ), bottom ], axis = 0 )
97
140
w2c_mats .append (w2c )
141
+ cam , pixtocam , params , camtype = cams [im .camera_id ]
142
+ all_params .append (params )
143
+ all_camtypes .append (camtype )
144
+ pixtocams .append (pixtocam )
98
145
w2c_mats = np .stack (w2c_mats , axis = 0 )
99
146
100
147
# Convert extrinsics to camera-to-world.
@@ -108,45 +155,9 @@ def process(
108
155
# Switch from COLMAP (right, down, fwd) to NeRF (right, up, back) frame.
109
156
poses = poses @ np .diag ([1 , - 1 , - 1 , 1 ])
110
157
111
- # Get distortion parameters.
112
- type_ = cam .camera_type
113
-
114
- if type_ == 0 or type_ == 'SIMPLE_PINHOLE' :
115
- params = None
116
- camtype = camera_utils .ProjectionType .PERSPECTIVE
117
-
118
- elif type_ == 1 or type_ == 'PINHOLE' :
119
- params = None
120
- camtype = camera_utils .ProjectionType .PERSPECTIVE
121
-
122
- if type_ == 2 or type_ == 'SIMPLE_RADIAL' :
123
- params = {k : 0. for k in ['k1' , 'k2' , 'k3' , 'p1' , 'p2' ]}
124
- params ['k1' ] = cam .k1
125
- camtype = camera_utils .ProjectionType .PERSPECTIVE
126
-
127
- elif type_ == 3 or type_ == 'RADIAL' :
128
- params = {k : 0. for k in ['k1' , 'k2' , 'k3' , 'p1' , 'p2' ]}
129
- params ['k1' ] = cam .k1
130
- params ['k2' ] = cam .k2
131
- camtype = camera_utils .ProjectionType .PERSPECTIVE
132
-
133
- elif type_ == 4 or type_ == 'OPENCV' :
134
- params = {k : 0. for k in ['k1' , 'k2' , 'k3' , 'p1' , 'p2' ]}
135
- params ['k1' ] = cam .k1
136
- params ['k2' ] = cam .k2
137
- params ['p1' ] = cam .p1
138
- params ['p2' ] = cam .p2
139
- camtype = camera_utils .ProjectionType .PERSPECTIVE
140
-
141
- elif type_ == 5 or type_ == 'OPENCV_FISHEYE' :
142
- params = {k : 0. for k in ['k1' , 'k2' , 'k3' , 'k4' ]}
143
- params ['k1' ] = cam .k1
144
- params ['k2' ] = cam .k2
145
- params ['k3' ] = cam .k3
146
- params ['k4' ] = cam .k4
147
- camtype = camera_utils .ProjectionType .FISHEYE
158
+ pixtocams = np .stack (pixtocams )
148
159
149
- return names , poses , pixtocam , params , camtype
160
+ return names , poses , pixtocams , all_params , all_camtypes
150
161
151
162
152
163
def load_blender_posedata (data_dir , split = None ):
@@ -288,8 +299,9 @@ def __init__(self,
288
299
self .images : np .ndarray = None
289
300
self .camtoworlds : np .ndarray = None
290
301
self .pixtocams : np .ndarray = None
291
- self .height : int = None
292
- self .width : int = None
302
+ self .height : np .ndarray = None
303
+ self .width : np .ndarray = None
304
+
293
305
294
306
# Load data from disk using provided config parameters.
295
307
self ._load_renderings (config )
@@ -314,11 +326,41 @@ def __init__(self,
314
326
self .height )
315
327
316
328
self ._n_examples = self .camtoworlds .shape [0 ]
329
+ if len (self .pixtocams .shape ) == 2 :
330
+ self .pixtocams = np .repeat (self .pixtocams [None ], self ._n_examples , 0 )
331
+ if not isinstance (self .focal , np .ndarray ):
332
+ self .focal = np .full ((self ._n_examples ,), self .focal , dtype = np .int32 )
333
+ if not isinstance (self .width , np .ndarray ):
334
+ self .width = np .full ((self ._n_examples ,), self .width , dtype = np .int32 )
335
+ if not isinstance (self .height , np .ndarray ):
336
+ self .height = np .full ((self ._n_examples ,), self .height , dtype = np .int32 )
337
+ if not isinstance (self .camtype , list ):
338
+ self .camtype = [self .camtype ] * self ._n_examples
339
+ map_camera = {
340
+ camera_utils .ProjectionType .PERSPECTIVE .value : 1 ,
341
+ camera_utils .ProjectionType .FISHEYE .value : 2
342
+ }
343
+ self .camtype = np .array ([map_camera [x .value ] for x in self .camtype ], dtype = np .int32 )
344
+ distortion_params = np .zeros ((self ._n_examples , 6 ), dtype = np .float32 )
345
+ for i in range (self ._n_examples ):
346
+ k = self .distortion_params
347
+ if isinstance (self .distortion_params , list ):
348
+ try :
349
+ k = self .distortion_params [i ]
350
+ except Exception as e :
351
+ breakpoint ()
352
+ print (e )
353
+ if k is None :
354
+ self .camtype [i ] = 0
355
+ continue
356
+ distortion_params [i ] = np .array ([k [m ] for m in ["k1" , "k2" , "k3" , "k4" , "p1" , "p2" ]], dtype = np .float32 )
357
+ self .distortion_params = distortion_params
317
358
318
359
self .cameras = (self .pixtocams ,
319
360
self .camtoworlds ,
320
361
self .distortion_params ,
321
- self .pixtocam_ndc )
362
+ self .pixtocam_ndc ,
363
+ self .camtype )
322
364
323
365
# Seed the queue with one batch to avoid race condition.
324
366
if self .split == utils .DataSplit .TRAIN :
@@ -456,23 +498,25 @@ def _next_train(self) -> utils.Batch:
456
498
num_patches = self ._batch_size // self ._patch_size ** 2
457
499
lower_border = self ._num_border_pixels_to_mask
458
500
upper_border = self ._num_border_pixels_to_mask + self ._patch_size - 1
501
+
502
+ # Random camera indices.
503
+ if self ._batching == utils .BatchingMethod .ALL_IMAGES :
504
+ cam_idx = np .random .randint (0 , self ._n_examples , (num_patches , 1 , 1 ))
505
+ else :
506
+ cam_idx = np .random .randint (0 , self ._n_examples , (1 ,))
507
+
459
508
# Random pixel patch x-coordinates.
460
- pix_x_int = np .random .randint (lower_border , self .width - upper_border ,
509
+ pix_x_int = np .random .randint (lower_border , self .width [ cam_idx ] - upper_border ,
461
510
(num_patches , 1 , 1 ))
462
511
# Random pixel patch y-coordinates.
463
- pix_y_int = np .random .randint (lower_border , self .height - upper_border ,
512
+ pix_y_int = np .random .randint (lower_border , self .height [ cam_idx ] - upper_border ,
464
513
(num_patches , 1 , 1 ))
465
514
# Add patch coordinate offsets.
466
515
# Shape will broadcast to (num_patches, _patch_size, _patch_size).
467
516
patch_dx_int , patch_dy_int = camera_utils .pixel_coordinates (
468
517
self ._patch_size , self ._patch_size )
469
518
pix_x_int = pix_x_int + patch_dx_int
470
519
pix_y_int = pix_y_int + patch_dy_int
471
- # Random camera indices.
472
- if self ._batching == utils .BatchingMethod .ALL_IMAGES :
473
- cam_idx = np .random .randint (0 , self ._n_examples , (num_patches , 1 , 1 ))
474
- else :
475
- cam_idx = np .random .randint (0 , self ._n_examples , (1 ,))
476
520
477
521
if self ._apply_bayer_mask :
478
522
# Compute the Bayer mosaic mask for each pixel in the batch.
@@ -488,12 +532,12 @@ def generate_ray_batch(self, cam_idx: int) -> utils.Batch:
488
532
if self ._render_spherical :
489
533
camtoworld = self .camtoworlds [cam_idx ]
490
534
rays = camera_utils .cast_spherical_rays (
491
- camtoworld , self .height , self .width , self .near , self .far , xnp = np )
535
+ camtoworld , self .height [ cam_idx ] , self .width [ cam_idx ] , self .near , self .far , xnp = np )
492
536
return utils .Batch (rays = rays )
493
537
else :
494
538
# Generate rays for all pixels in the image.
495
539
pix_x_int , pix_y_int = camera_utils .pixel_coordinates (
496
- self .width , self .height )
540
+ self .width [ cam_idx ] , self .height [ cam_idx ] )
497
541
return self ._make_ray_batch (pix_x_int , pix_y_int , cam_idx )
498
542
499
543
def _next_test (self ) -> utils .Batch :
@@ -593,13 +637,15 @@ def _load_renderings(self, config):
593
637
inds = np .argsort (image_names )
594
638
image_names = [image_names [i ] for i in inds ]
595
639
poses = poses [inds ]
640
+ pixtocam = pixtocam [inds ]
641
+ distortion_params = [distortion_params [i ] for i in inds ]
642
+ camtype = [camtype [i ] for i in inds ]
596
643
597
644
# Scale the inverse intrinsics matrix by the image downsampling factor.
598
645
pixtocam = pixtocam @ np .diag ([factor , factor , 1. ])
599
646
self .pixtocams = pixtocam .astype (np .float32 )
600
- self .focal = 1. / self .pixtocams [0 , 0 ]
647
+ self .focal = 1. / self .pixtocams [..., 0 , 0 ]
601
648
self .distortion_params = distortion_params
602
- self .camtype = camtype
603
649
604
650
raw_testscene = False
605
651
if config .rawnerf_mode :
@@ -706,6 +752,12 @@ def _load_renderings(self, config):
706
752
# All per-image quantities must be re-indexed using the split indices.
707
753
images = images [indices ]
708
754
poses = poses [indices ]
755
+ self .pixtocams = self .pixtocams [indices ]
756
+ self .focal = self .focal [indices ]
757
+ list_indices = np .where (indices )[0 ] if indices .dtype == np .bool_ else indices
758
+ self .distortion_params = [self .distortion_params [i ] for i in list_indices ]
759
+ self .camtype = [camtype [i ] for i in list_indices ]
760
+ assert len (self .camtype ) == len (self .pixtocams )
709
761
if self .exposures is not None :
710
762
self .exposures = self .exposures [indices ]
711
763
if config .rawnerf_mode :
0 commit comments