Пример #1
0
 def cal_cameras_graph(self):
     camera_groups = tuple(itertools.combinations(self.camera_list, 2))
     for group in camera_groups:
         c1_idx = camera_list.index(group[0])
         c2_idx = camera_list.index(group[1])
         common_pts_m = np.row_stack(
             (self.mask[c1_idx, :], self.mask[c2_idx, :]))
         common_pts_num = len(
             np.where((common_pts_m[0, :] == 1)
                      & (common_pts_m[1, :] == 1))[0])
         # print("camera%d camera%d common pts %d"%(c1_idx, c2_idx, common_pts_num))
         weight = 1 / common_pts_num
         self.cameras_graph.add_edge(group[0], group[1], weight)
Пример #2
0
    def reconstruct_ref_pts(self, bridge_camera):
        self.ref_re_cameras = np.zeros((3, self.sample_num))

        params_db = camerasParamsDatabase()
        for camera in self.camera_list:
            c_idx = camera_list.index(camera)  #camera index
            if bridge_camera == camera:
                key = bridge_camera + "_params_world_csys"
            else:
                key = bridge_camera + "_" + camera + "_params_world_csys"

            proj = params_db.get_data(key)

            if proj:
                proj = np.array(proj).reshape((3, 4))
                self.proj_cameras_M[c_idx, :, :] = proj
        self.proj_cameras_list = \
            self.proj_cameras_M.reshape((1,12*self.cameras_num)).tolist()[0]
        for p_idx in np.arange(self.sample_num):
            X = []
            P = []
            c_list = []
            for c_idx in np.arange(self.cameras_num):
                if self.mask[c_idx, p_idx] == 1:
                    X.append(self.img_filter_cameras[c_idx, :, p_idx])
                    P.append(self.proj_cameras_M[c_idx, :, :])
                    c_list.append(c_idx)
            if len(X) > 1:
                ref_re_pts = triangulate_multi_cameras(X, P)
                self.ref_re_cameras[:, p_idx] = ref_re_pts
                #ref_pts = self.ref_filter_cameras[c_idx,:,p_idx]
                #print("Camera", c_list)
                #print(np.abs(ref_re_pts - ref_pts))
        self.ref_re_cameras_list = \
            self.ref_re_cameras.reshape((1,3*self.sample_num)).tolist()[0]
Пример #3
0
def get_op_params(camera1,
                  camera2,
                  camera_list,
                  multi_c_p,
                  params_db,
                  is_get_f_from_db=False):
    """
    get optimize params, 
    R_T: camera2 coordinate system to camera1 coordinate system 
    """
    c1_idx, c2_idx = camera_list.index(camera1), camera_list.index(camera2)

    common_pts_m = np.row_stack(
        (multi_c_p.mask[c1_idx, :], multi_c_p.mask[c2_idx, :]))
    common_pts = np.where((common_pts_m[0, :] == 1)
                          & (common_pts_m[1, :] == 1))[0]
    img_data1 = multi_c_p.img_filter_cameras[c1_idx, :, common_pts].T
    img_data2 = multi_c_p.img_filter_cameras[c2_idx, :, common_pts].T
    if is_get_f_from_db:
        f0 = params_db.get_data(camera1 + "_int")
        f1 = params_db.get_data(camera2 + "_int")
        if f0 and f1:
            op_x = get_params_from_stereo_vision(img_data1, img_data2, \
                                                 (f0, f1))
        else:
            op_x = get_params_from_stereo_vision(img_data1, img_data2)
            params_db.store_data(camera2 + "_int", op_x[1])
#           print("store int params:", camera2, op_x[1])
    else:
        op_x = get_params_from_stereo_vision(img_data1, img_data2)
        params_db.store_data(camera2 + "_int", op_x[1])


#        print("store int params:", camera2, op_x[1])
    f0 = op_x[0]
    f1 = op_x[1]
    R_M = Rodrigues(np.array(op_x[2:5]))[0]
    t = np.array(np.array(op_x[5:]))
    R_T = np.column_stack((R_M, t))

    return op_x, f0, f1, R_T
Пример #4
0
def update_proj_matrix(bridge_camera, transfer_m, camera_list):
    params_db = camerasParamsDatabase()  
    camera1_idx = camera_list.index(bridge_camera)
    other_cameras = camera_list[:camera1_idx] + camera_list[camera1_idx+1:]
    for camera2_flag in other_cameras:    
        rt_key = bridge_camera+"_"+camera2_flag     
        ext_camera_csys = get_ext_params_from_db(bridge_camera, camera2_flag, params_db)
        f = params_db.get_data(camera2_flag+"_int")        
        if ext_camera_csys is not None and f:
            K = np.array([[f, 0, 0], [0, f, 0], [0, 0, 1]])
            proj_M2 = K.dot(ext_camera_csys).dot(transfer_m)
            params_db.store_data(rt_key +"_params_world_csys", proj_M2.tolist())   
Пример #5
0
    def load(self, start_idx):
        for camera in self.camera_list:
            c_idx = camera_list.index(camera)  #camera index
            camera_db = CameraCalDatabase(camera)
            keys = list(camera_db.db.getall())
            if len(keys) >= self.sample_num / 3:
                p_idx = 0  #point idx
                for i in np.arange(int(self.sample_num / 3)):
                    key = keys[i]
                    if int(key) > start_idx:
                        img_coord_camera = camera_db.get_cal_data(key)['2d']
                        ref_coord_camera = camera_db.get_cal_data(key)['3d']
                        #make sure the data is not empty dict
                        # if the image contains required three points
                        if (len(set(img_coord_camera.keys()))==4) and \
                            set(self.points_flag).issubset(set(img_coord_camera.keys())):

                            for point_flag in img_coord_camera.keys():
                                c1 = coordinate_sys_move(img_coord_camera[point_flag], \
                                                         accuracy = self.img_accuracy)
                                if point_flag in self.points_flag:
                                    #red blue green
                                    self.mask[c_idx, p_idx] = 1
                                    self.img_filter_cameras[c_idx, :,
                                                            p_idx] = c1
                                    self.ref_filter_cameras[
                                        c_idx, :,
                                        p_idx] = ref_coord_camera[point_flag]
                                    p_idx += 1
                        else:
                            p_idx += 3
        for p_idx in np.arange(self.sample_num):

            if (np.count_nonzero(self.mask[:, p_idx]) < 2):
                self.mask[:, p_idx] = np.zeros((1, self.cameras_num))

        cols_allzero = np.where(~self.mask.any(axis=0))[0]
        #remove outliers, the pts not in any images
        self.mask = np.delete(self.mask, cols_allzero, axis=1)
        self.img_filter_cameras = np.delete(self.img_filter_cameras, \
                                            cols_allzero, axis=2)
        self.ref_filter_cameras = np.delete(self.ref_filter_cameras, \
                                            cols_allzero, axis=2)

        self.sample_num = self.mask.shape[1]
Пример #6
0
def get_scale_cameras(bridge_camera, camera_list, cameras_graph):
    """
    get the scales of other camera's coordinates during compute the 
    transfer matrix
    
    """
    cameras_graph.get_border_cost(bridge_camera)
    if bridge_camera in camera_list:
        camera1_idx = camera_list.index(bridge_camera)
        other_cameras = camera_list[:camera1_idx] + camera_list[camera1_idx+1:]
    else:
        other_cameras = camera_list
    cost_list = []
    cost_sum = 0
    for camera2_flag in other_cameras:
        cost = 1/cameras_graph.dijkstra(camera2_flag, bridge_camera)[0]    
        cost_list.append(cost)
        cost_sum += cost
        
    scales = [x/cost_sum for x in cost_list]
    return scales
Пример #7
0
def verify_BA(bridge_camera, camera_list, img_filter_cameras, ref_filter_cameras,\
              ref_re_cameras, mask, pts_num):
    """
    Verify the calibration effect after bundle adjustment
    """
    error_ref_pts = np.zeros((3, pts_num))
    dist_error_pts = np.zeros((3, int(pts_num / 3)))
    cameras_num = len(camera_list)
    proj_cameras_M = np.zeros((cameras_num, 3, 4))
    params_BA = camerasParamsDatabase(bridge_camera + "_Params_BA.db")
    for camera in camera_list:
        c_idx = camera_list.index(camera)  #camera index

        proj = params_BA.get_data(camera)
        if proj:
            proj = np.array(proj).reshape((3, 4))
            proj_cameras_M[c_idx, :, :] = proj

    for p_idx in np.arange(pts_num):
        X = []
        P = []

        for c_idx in np.arange(cameras_num):
            if mask[c_idx, p_idx] == 1:
                last_c_idx = c_idx
                X.append(img_filter_cameras[c_idx, :, p_idx])
                P.append(proj_cameras_M[c_idx, :, :])
        if len(X) > 1:
            ref_re_pts_BA = triangulate_multi_cameras(X, P)
            ref_pts = ref_filter_cameras[last_c_idx, :, p_idx]
            error_ref_pts[:, p_idx] = np.abs(ref_re_pts_BA - ref_pts)

        if p_idx % 3 == 0:
            counter_3 = 0
            red_res = ref_re_pts_BA
        elif p_idx % 3 == 1 and counter_3 == 0:
            counter_3 += 1
            blue_res = ref_re_pts_BA
        elif p_idx % 3 == 2 and counter_3 == 1:
            counter_3 += 1
            green_res = ref_re_pts_BA
        if counter_3 == 2:
            len_RtoG = abs(
                np.linalg.norm(red_res - green_res) -
                len_relation["Red_Green"])
            len_RtoB = abs(
                np.linalg.norm(red_res - blue_res) - len_relation["Red_Blue"])
            len_GtoB = abs(
                np.linalg.norm(green_res - blue_res) -
                len_relation["Blue_Green"])

            dist_error_pts[:, int(p_idx / 3)] = np.array(
                [len_RtoG, len_RtoB, len_GtoB])
            counter_3 = 0

    error_plot(dist_error_pts,
               titles=["GreenToRed", "RedToBlue", "GreenToBlue"])

    error_plot(error_ref_pts)
    print("<Mean> Fig1:%f  Fig2:%f  Fig3:%f"% \
          (np.mean(error_ref_pts[0,:]),np.mean(error_ref_pts[1,:]),np.mean(error_ref_pts[2,:])))
    print("<Std> Fig1:%f  Fig2:%f  Fig3:%f"% \
          (np.std(error_ref_pts[0,:]),np.std(error_ref_pts[1,:]),np.std(error_ref_pts[2,:])))
    result = [np.mean(error_ref_pts[0,:]),\
            np.mean(error_ref_pts[1,:]),\
            np.mean(error_ref_pts[2,:]),\
            np.std(error_ref_pts[0,:]),\
            np.std(error_ref_pts[1,:]),\
            np.std(error_ref_pts[2,:])]
    return result
Пример #8
0
def get_params_from_muti_cameras(data_processor, bridge_camera, camera_list):
    """
    multiple cameras calibration.
    1. get the focal length based on the 
    """
    t0 = time.time()
    params_db = camerasParamsDatabase()
    if bridge_camera in camera_list:
        bridge_camera_idx = camera_list.index(bridge_camera)
        other_cameras = camera_list[:bridge_camera_idx] + camera_list[
            bridge_camera_idx + 1:]
    else:
        other_cameras = camera_list
    p = data_processor
    #    for camera in camera_list:
    for camera in [bridge_camera]:
        best_group = list(p.get_best_group(camera))

        if not params_db.get_data(camera + "_int"):
            if bridge_camera in best_group:
                b_idx = best_group.index(bridge_camera)
                best_group = best_group[b_idx], best_group[1 - b_idx]
            print("best_group", best_group)
            camera1, camera2 = best_group
            key = camera1 + "_" + camera2
            print("Int param key:", key)
            if not params_db.get_data(key):
                op_x, f0, f1, R_T = get_op_params(camera1, camera2,
                                                  camera_list, p, params_db)
                if camera == camera1:
                    params_db.store_data(camera + "_int", f0)
                else:
                    params_db.store_data(camera + "_int", f1)
                params_db.store_data(key, op_x)

    for camera in other_cameras:
        Best_RT = np.eye(4, 4)
        key = bridge_camera + "_" + camera
        key_inv = camera + "_" + bridge_camera
        path = p.cameras_graph.dijkstra(camera, bridge_camera)[1]
        RT_list = []
        groups = gen_group(path, 2)
        print("Ext groups:", groups)

        if (get_ext_params_from_db(bridge_camera, camera, params_db) is None):
            for group in groups:
                group_key = group[1] + "_" + group[0]
                if not params_db.get_data(group_key):
                    op_x, f0, f1, R_T = get_op_params(group[1], group[0],\
                                                      camera_list, p, params_db, True)

                    params_db.store_data(group_key, op_x)
                else:
                    op_x = params_db.get_data(group_key)
                    R_M = Rodrigues(np.array(op_x[2:5]))[0]
                    t = np.array(np.array(op_x[5:]))
                    R_T = np.column_stack((R_M, t))
                RT_list.append(np.row_stack((R_T, np.array([0, 0, 0, 1]))))
            for R_T in RT_list:
                Best_RT = Best_RT.dot(R_T)
            Best_RT_inv = inv(Best_RT)[0:3, :]
            Best_RT = Best_RT[0:3, :]
            params_db.store_data(key + "_ext_camera_csys", Best_RT.tolist())
            params_db.store_data(key_inv + "_ext_camera_csys",
                                 Best_RT_inv.tolist())
    t1 = time.time()
    print("Mutiple calibrate take {0:.0f} seconds".format(t1 - t0))
Пример #9
0
def get_other_cameras_coord(bridge_camera, camera2_flag=None, \
                            camera_list = None, img_accuracy=None):
    """
    get cameras origin coordinates in bridge_camera coordinate system
    """
    params_db = camerasParamsDatabase()  
    if camera2_flag:
        other_cameras = [camera2_flag]
    elif camera_list:
        if bridge_camera in camera_list:
            camera1_idx = camera_list.index(bridge_camera)
            other_cameras = camera_list[:camera1_idx] + camera_list[camera1_idx+1:]
        else:
            other_cameras = camera_list
    proj_list = []    
    flags = ("Green", "Blue", "Yellow")
    img_pts_data = {"Green":[], "Blue":[], "Yellow":[]}
    res_pts_3d= np.array([])
    ref_pts_3d = []    
    camera_pts_list = []
    for camera2_flag in other_cameras:
        camera2_idx = other_cameras.index(camera2_flag)              
        if camera2_idx ==0:
            f0 = params_db.get_data(bridge_camera+"_int")
            K1 = np.array([[f0, 0, 0], [0, f0, 0], [0, 0, 1]])
            proj_M1 = K1.dot(np.column_stack((np.eye(3, 3), np.zeros((3, 1)))))
            proj_list.append(proj_M1)
        f1 = params_db.get_data(camera2_flag+"_int")
        K2 = np.array([[f1, 0, 0], [0, f1, 0], [0, 0, 1]])
        R_T = get_ext_params_from_db(bridge_camera, camera2_flag, params_db) 
        R_M = R_T[:,0:3]
        t = R_T[:,3]
        c2_origin_c1_csys = np.linalg.solve(R_M, -t)        
        if not np.allclose(np.dot(R_M, c2_origin_c1_csys), -t):
            raise ValueError("Can not get the Camera coordinate in CSYS.")
        camera_pts_list.append(c2_origin_c1_csys)
        proj_M2 = K2.dot(np.column_stack((R_M, t)))
        proj_list.append(proj_M2)

        img_coord_pts, ref_coord_pts = get_level_calib_data([bridge_camera, camera2_flag], \
                                                            img_accuracy)
        camera1_ref_2d, camera2_ref_2d = img_coord_pts
        for flag in flags:
            if camera2_idx ==0:
                ref_pts_3d.append(ref_coord_pts[flag])
                img_pts_data[flag].append(np.array(camera1_ref_2d[flag]))                
            img_pts_data[flag].append(np.array(camera2_ref_2d[flag]))


    for flag in flags:
        res_pt_3d = triangulate_multi_cameras(img_pts_data[flag], proj_list)
        res_pts_3d = np.append(res_pts_3d, res_pt_3d)        
    new_res_pts_3d = res_pts_3d = res_pts_3d.reshape((3, 3)).T
    new_ref_pts_3d = ref_pts_3d = np.array(ref_pts_3d).T
    for camera2_flag in other_cameras:
        c2_origin_c1_csys = camera_pts_list[other_cameras.index(camera2_flag)]
        sol, pts_dist = compute_coord_from_triangule_locate(res_pts_3d, \
                                                            c2_origin_c1_csys, \
                                                            ref_pts_3d)   
#        print("Sol:", sol)        
#        sol = [round(x) for x in sol]
#        print("Round Sol:", sol)
#        error = compute_coord_from_triangule_locate_eqs(sol, ref_pts_3d, pts_dist)
#        print(error)
#        sol = np.array([-4.0, 8.0, -4.0])
        new_res_pts_3d = np.column_stack((new_res_pts_3d, c2_origin_c1_csys))
        new_ref_pts_3d = np.column_stack((new_ref_pts_3d, sol))    
    return new_res_pts_3d, new_ref_pts_3d