Knowhow/Vision

COLMAP write txt files in python

침닦는수건 2022. 7. 13. 18:25
반응형

기존에 갖고 있던 데이터를 COLMAP format에 맞추어 변형하는 코드를 정리하고자 한다.

 

COLMAP을 사용하고자 하는 경우가 보통 SfM, MVS를 통해 3D point를 얻어내기 위함이기 때문에 points3D.txt에 대한 코드는 정리하지 않았다. (이미 points3D.txt가 있는 경우에는 COLMAP을 사용하지 않을테니...)

 

images.txt와 cameras.txt 형태로 데이터를 정리하는 코드만 정리하고자 한다.

 

1. images.txt : pose notation은 https://jseobyun.tistory.com/31 참고

 

하나 유념할 것은, 일반적으로 quaternion을 사용할 때, x,y,z,w 표기를 사용하는데 colmap은 w,x,y,z 표기를 사용한다.

'''
given 
1. poses: list of [T_cw ...]
2. img_names: list of [cam1/001.jpg ...]
3. cam_ids : list of [1 ...]
* len(cam_ids) == len(img_names)
'''
import numpy as np
from scipy.spatial.transform import Rotation as Rot

def write_images_txt(save_path, poses, img_names, cam_ids):	
    f = open(save_path, 'w')
    images_txt = ["# Image list with two lines of data per image:\n",
                  "#   IMAGE_ID, QW, QX, QY, QZ, TX, TY, TZ, CAMERA_ID, NAME\n",
                  "#   POINTS2D[] as (X, Y, POINT3D_ID)\n",
                  "# Number of images: ?, mean observations per image: ?]\n"]
    img_count = 0
    
    for pose, img_name, cam_id in zip(poses, img_names, cam_ids):   
        R_cw = pose[:3, :3]
        t_cw = pose[:3, -1]
        q_cw_xyzw = Rot.from_matrix(R_cw).as_quat()
        q_cw_wxyz = [str(q_cw_xyzw[3]), str(q_cw_xyzw[0]), str(q_cw_xyzw[1]), str(q_cw_xyzw[2])]
        t_cw = [str(t_cw[0]), str(t_cw[1]), str(t_cw[2])]

        img_id = [str(img_count + 1)]
        img_count +=1
        cam_id = [str(cam_id)]
        name = [os.path.join(cam_dir.split('/')[-1], img_name)]

        image_txt = img_id + q_cw_wxyz + t_cw + cam_id + name
        image_txt = " ".join(image_txt) + "\n"
        images_txt.append(image_txt)
        images_txt.append("\n")
        
    f.writelines(images_txt)
    f.close()

 

2. cameras.txt

'''
given 
1. cam_ids: list of [1, 2 ...], unnique item only 
2. cam_type : "OPENCV", only opencv supported
3. img_whs : image width and image height
4. focal length fxs: [fx1, fx2 ...]
5. focal length fys: [fy1, fy2 ...]
6. principal point cxs: [cx1, cx2 ...]
7. principal point cys: [cy1, cy2 ...]
6. distortion coefficients : [ [k1, k2, p1, p2], [k1, k2, p1, p2] ... ] 
'''
import numpy as np

def write_cameras_txt(save_path, cam_ids, img_whs, fxs, fys, cxs, cys, dists):	
    f = open(save_path, 'w')
    cameras_txt = ["# Camera list with one line of data per camera:\n",
                   "#   CAMERA_ID, MODEL, WIDTH, HEIGHT, PARAMS[]\n",
                   "# Number of cameras: ?]\n"]
                   
    img_count = 0    
    for cam_id, img_wh, fx, fy, cx, cy, dist in zip(cam_ids, img_wh, fxs, fys, cxs, cys, dists):   
        cam_id = [str(cam_id)]        
        cam_type = ["OPENCV"]
        img_wh = [str(img_wh[0]), str(img_wh[1])]
        fxfy = [str(fx), str(fy)]
        cxcy = [str(cx), str(cy)]        
        dist = [str(dist[0]), str(dist[1]), str(dist[2]), str(dist[3])]
        camera_txt = cam_id + cam_type + img_wh + fxfy + cxcy + dist
        camera_txt = ' '.join(camera_txt) +"\n"
        cameras_txt.append(camera_txt)
    f.writelines(cameras_txt)
    f.close()

 

반응형