示例#1
0
    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
示例#2
0
    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
示例#3
0
    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 )
示例#4
0
    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)