def get_aligned_copy(self, other): """return copy of self that is scaled, translated, and rotated to best match other""" assert isinstance( other, MultiCameraSystem) orig_names = self.get_names() new_names = other.get_names() names = set(orig_names).intersection( new_names ) if len(names) < 3: raise ValueError('need 3 or more cameras in common to align.') orig_points = np.array([ self._cameras[name].get_camcenter() for name in names ]).T new_points = np.array([ other._cameras[name].get_camcenter() for name in names ]).T s,R,t = estsimt(orig_points,new_points) assert is_rotation_matrix(R) new_cams = [] for name in self.get_names(): orig_cam = self._cameras[name] new_cam = orig_cam.get_aligned_camera(s,R,t) new_cams.append( new_cam ) result = MultiCameraSystem(new_cams) return result
def get_aligned_copy(self, other): """return copy of self that is scaled, translated, and rotated to best match other""" assert isinstance(other, MultiCameraSystem) orig_names = self.get_names() new_names = other.get_names() names = set(orig_names).intersection(new_names) if len(names) < 3: raise ValueError('need 3 or more cameras in common to align.') orig_points = np.array( [self._cameras[name].get_camcenter() for name in names]).T new_points = np.array( [other._cameras[name].get_camcenter() for name in names]).T s, R, t = estsimt(orig_points, new_points) assert is_rotation_matrix(R) new_cams = [] for name in self.get_names(): orig_cam = self._cameras[name] new_cam = orig_cam.get_aligned_camera(s, R, t) new_cams.append(new_cam) result = MultiCameraSystem(new_cams) return result
def from_mcsc(cls, dirname ): '''create MultiCameraSystem from output directory of MultiCamSelfCal''' # FIXME: This is a bit convoluted because it's been converted # from multiple layers of internal code. It should really be # simplified and cleaned up. do_normalize_pmat=True all_Pmat = {} all_Res = {} all_K = {} all_distortion = {} opj = os.path.join with open(opj(dirname,'camera_order.txt'),mode='r') as fd: cam_ids = fd.read().strip().split('\n') with open(os.path.join(dirname,'Res.dat'),'r') as res_fd: for i, cam_id in enumerate(cam_ids): fname = 'camera%d.Pmat.cal'%(i+1) pmat = np.loadtxt(opj(dirname,fname)) # 3 rows x 4 columns if do_normalize_pmat: pmat_orig = pmat pmat = normalize_M(pmat) all_Pmat[cam_id] = pmat all_Res[cam_id] = map(int,res_fd.readline().split()) # load non linear parameters rad_files = [ f for f in os.listdir(dirname) if f.endswith('.rad') ] for cam_id_enum, cam_id in enumerate(cam_ids): filename = os.path.join(dirname, 'basename%d.rad'%(cam_id_enum+1,)) if os.path.exists(filename): K, distortion = parse_radfile(filename) all_K[cam_id] = K all_distortion[cam_id] = distortion else: if len(rad_files): raise RuntimeError( '.rad files present but none named "%s"'%filename) warnings.warn('no non-linear data (e.g. radial distortion) ' 'in calibration for %s'%cam_id) all_K[cam_id] = None all_distortion[cam_id] = None cameras = [] for cam_id in cam_ids: w,h = all_Res[cam_id] Pmat = all_Pmat[cam_id] M = Pmat[:,:3] K,R = my_rq(M) if not is_rotation_matrix(R): # RQ may return left-handed rotation matrix. Make right-handed. R2 = -R K2 = -K assert np.allclose(np.dot(K2,R2), np.dot(K,R)) K,R = K2,R2 P = np.zeros((3,4)) P[:3,:3] = K KK = all_K[cam_id] # from rad file or None distortion = all_distortion[cam_id] # (ab)use PyMVG's rectification to do coordinate transform # for MCSC's undistortion. # The intrinsic parameters used for 3D -> 2D. ex = P[0,0] bx = P[0,2] Sx = P[0,3] ey = P[1,1] by = P[1,2] Sy = P[1,3] if KK is None: rect = np.eye(3) KK = P[:,:3] else: # Parameters used to define undistortion coordinates. fx = KK[0,0] fy = KK[1,1] cx = KK[0,2] cy = KK[1,2] rect = np.array([[ ex/fx, 0, (bx+Sx-cx)/fx ], [ 0, ey/fy, (by+Sy-cy)/fy ], [ 0, 0, 1 ]]).T if distortion is None: distortion = np.zeros((5,)) C = center(Pmat) rot = R t = -np.dot(rot, C)[:,0] d = {'width':w, 'height':h, 'P':P, 'K':KK, 'R':rect, 'translation':t, 'Q':rot, 'D':distortion, 'name':cam_id, } cam = CameraModel.from_dict(d) cameras.append( cam ) return MultiCameraSystem( cameras=cameras )
def from_mcsc(cls, dirname): '''create MultiCameraSystem from output directory of MultiCamSelfCal''' # FIXME: This is a bit convoluted because it's been converted # from multiple layers of internal code. It should really be # simplified and cleaned up. do_normalize_pmat = True all_Pmat = {} all_Res = {} all_K = {} all_distortion = {} opj = os.path.join with open(opj(dirname, 'camera_order.txt'), mode='r') as fd: cam_ids = fd.read().strip().split('\n') with open(os.path.join(dirname, 'Res.dat'), 'r') as res_fd: for i, cam_id in enumerate(cam_ids): fname = 'camera%d.Pmat.cal' % (i + 1) pmat = np.loadtxt(opj(dirname, fname)) # 3 rows x 4 columns if do_normalize_pmat: pmat_orig = pmat pmat = normalize_M(pmat) all_Pmat[cam_id] = pmat all_Res[cam_id] = map(int, res_fd.readline().split()) # load non linear parameters rad_files = [f for f in os.listdir(dirname) if f.endswith('.rad')] for cam_id_enum, cam_id in enumerate(cam_ids): filename = os.path.join(dirname, 'basename%d.rad' % (cam_id_enum + 1, )) if os.path.exists(filename): K, distortion = parse_radfile(filename) all_K[cam_id] = K all_distortion[cam_id] = distortion else: if len(rad_files): raise RuntimeError( '.rad files present but none named "%s"' % filename) warnings.warn('no non-linear data (e.g. radial distortion) ' 'in calibration for %s' % cam_id) all_K[cam_id] = None all_distortion[cam_id] = None cameras = [] for cam_id in cam_ids: w, h = all_Res[cam_id] Pmat = all_Pmat[cam_id] M = Pmat[:, :3] K, R = my_rq(M) if not is_rotation_matrix(R): # RQ may return left-handed rotation matrix. Make right-handed. R2 = -R K2 = -K assert np.allclose(np.dot(K2, R2), np.dot(K, R)) K, R = K2, R2 P = np.zeros((3, 4)) P[:3, :3] = K KK = all_K[cam_id] # from rad file or None distortion = all_distortion[cam_id] # (ab)use PyMVG's rectification to do coordinate transform # for MCSC's undistortion. # The intrinsic parameters used for 3D -> 2D. ex = P[0, 0] bx = P[0, 2] Sx = P[0, 3] ey = P[1, 1] by = P[1, 2] Sy = P[1, 3] if KK is None: rect = np.eye(3) KK = P[:, :3] else: # Parameters used to define undistortion coordinates. fx = KK[0, 0] fy = KK[1, 1] cx = KK[0, 2] cy = KK[1, 2] rect = np.array([[ex / fx, 0, (bx + Sx - cx) / fx], [0, ey / fy, (by + Sy - cy) / fy], [0, 0, 1]]).T if distortion is None: distortion = np.zeros((5, )) C = center(Pmat) rot = R t = -np.dot(rot, C)[:, 0] d = { 'width': w, 'height': h, 'P': P, 'K': KK, 'R': rect, 'translation': t, 'Q': rot, 'D': distortion, 'name': cam_id, } cam = CameraModel.from_dict(d) cameras.append(cam) return MultiCameraSystem(cameras=cameras)