1use byteorder::{LittleEndian, ReadBytesExt};
2use num_traits::AsPrimitive;
3use std::io::BufReader;
4
5pub enum CameraModel {
6 PINHOLE([f64; 4]),
7}
8
9pub struct Camera {
10 pub camera_id: i32,
11 pub width: u64,
12 pub height: u64,
13 pub model: CameraModel,
14}
15
16pub fn read_cameras<PATH: AsRef<std::path::Path>>(path: PATH) -> anyhow::Result<Vec<Camera>> {
17 let file = std::fs::File::open(path).unwrap();
19 let mut reader = std::io::BufReader::new(file);
20 let num_cam = reader.read_u64::<LittleEndian>()?;
21 dbg!(num_cam);
22 let mut cameras: Vec<Camera> = vec![];
23 for _ in 0..num_cam {
24 let camera_id = reader.read_i32::<LittleEndian>()?;
25 let model_id = reader.read_u32::<LittleEndian>()?;
26 let width = reader.read_u64::<LittleEndian>()?;
27 let height = reader.read_u64::<LittleEndian>()?;
28 dbg!(camera_id, model_id, width, height);
29 let model = match model_id {
30 1 => {
31 let mut v = [0f64; 4];
32 for i_param in 0..4 {
33 v[i_param] = reader.read_f64::<LittleEndian>()?;
34 }
35 CameraModel::PINHOLE(v)
36 }
37 _ => {
38 panic!()
39 }
40 };
41 cameras.push(Camera {
42 camera_id,
43 height,
44 width,
45 model,
46 });
47 }
48 Ok(cameras)
49}
50
51pub fn parse_string(reader: &mut BufReader<std::fs::File>) -> anyhow::Result<String> {
52 let mut aa: Vec<u8> = vec![];
53 loop {
54 let a0 = reader.read_u8()?;
55 aa.push(a0);
56 if a0 == 0x00 {
57 break;
58 }
59 }
60 Ok(String::from_utf8(aa).unwrap())
61}
62
63pub struct Image {
64 pub image_id: i32,
65 pub qvec: [f64; 4],
66 pub tvec: [f64; 3],
67 pub camera_id: i32,
68 pub name: String,
69 pub vtx2xy: Vec<f64>,
70 pub vtx2id: Vec<i64>,
71}
72
73pub fn read_images<PATH: AsRef<std::path::Path>>(path: PATH) -> anyhow::Result<Vec<Image>> {
74 let file = std::fs::File::open(path).unwrap();
76 let mut reader = std::io::BufReader::new(file);
77 let num_images = reader.read_u64::<LittleEndian>()?;
78 let mut images = Vec::<Image>::with_capacity(num_images.as_());
79 for _ in 0..num_images {
80 let image_id = reader.read_i32::<LittleEndian>()?;
81 let qvec = [
82 reader.read_f64::<LittleEndian>()?,
83 reader.read_f64::<LittleEndian>()?,
84 reader.read_f64::<LittleEndian>()?,
85 reader.read_f64::<LittleEndian>()?,
86 ];
87 let tvec = [
88 reader.read_f64::<LittleEndian>()?,
89 reader.read_f64::<LittleEndian>()?,
90 reader.read_f64::<LittleEndian>()?,
91 ];
92 let camera_id = reader.read_i32::<LittleEndian>()?;
93 let name = parse_string(&mut reader)?;
94 let num_points = reader.read_u64::<LittleEndian>()?;
95 let mut vtx2xy: Vec<f64> = vec![];
96 let mut vtx2id: Vec<i64> = vec![];
97 for _i_points in 0..num_points {
98 let x = reader.read_f64::<LittleEndian>()?;
99 let y = reader.read_f64::<LittleEndian>()?;
100 let id_s = reader.read_i64::<LittleEndian>()?;
101 vtx2xy.push(x);
102 vtx2xy.push(y);
103 vtx2id.push(id_s);
104 }
105 images.push(Image {
106 image_id,
107 qvec,
108 tvec,
109 camera_id,
110 name,
111 vtx2xy,
112 vtx2id,
113 });
114 }
115 Ok(images)
116}
117
118pub struct Point3D {
119 pub id: u64,
120 pub xyz: [f64; 3],
121 pub rgb: [u8; 3],
122 pub err: f64,
123 pub img: Vec<(i32, i32)>,
124}
125
126pub fn read_points3d<PATH: AsRef<std::path::Path>>(path: PATH) -> anyhow::Result<Vec<Point3D>> {
127 let file = std::fs::File::open(path).unwrap();
129 let mut reader = std::io::BufReader::new(file);
130 let num_points = reader.read_u64::<LittleEndian>()?;
131 let mut points = Vec::<Point3D>::with_capacity(num_points.as_());
132 for _i_point in 0..num_points {
134 let point3d_id = reader.read_u64::<LittleEndian>()?;
135 let x = reader.read_f64::<LittleEndian>()?;
136 let y = reader.read_f64::<LittleEndian>()?;
137 let z = reader.read_f64::<LittleEndian>()?;
138 let r = reader.read_u8()?;
139 let g = reader.read_u8()?;
140 let b = reader.read_u8()?;
141 let error = reader.read_f64::<LittleEndian>()?;
142 let track_length = reader.read_u64::<LittleEndian>()?;
143 let mut img = vec![(0i32, 0i32); 0];
146 for _i_track in 0..track_length {
147 let image_id = reader.read_i32::<LittleEndian>()?;
148 let point2d_idx = reader.read_i32::<LittleEndian>()?;
149 img.push((image_id, point2d_idx));
151 }
152 points.push(Point3D {
153 id: point3d_id,
154 xyz: [x, y, z],
155 rgb: [r, g, b],
156 err: error,
157 img,
158 })
159 }
160 Ok(points)
161}