1- use arrow:: array:: { Float32Array , Float64Array , ListArray } ;
1+ use arrow:: array:: { Float32Array , Float64Array , ListArray , UInt32Array } ;
22
33use re_log_types:: TimeType ;
44use rerun:: {
5- CoordinateFrame , EncodedImage , InstancePoses3D , Transform3D , TransformAxes3D , VideoStream ,
5+ CoordinateFrame , EncodedImage , InstancePoses3D , Pinhole , Transform3D , TransformAxes3D ,
6+ VideoStream ,
67 dataframe:: EntityPathFilter ,
78 external:: re_log,
89 lenses:: { Lens , LensesSink , Op , OpError } ,
@@ -12,10 +13,10 @@ use rerun::{
1213// `re_arrow_combinators` provides the building blocks from which we compose the conversions.
1314use re_arrow_combinators:: {
1415 Transform as _,
15- cast:: PrimitiveCast ,
16+ cast:: { ListToFixedSizeList , PrimitiveCast } ,
1617 map:: MapFixedSizeList ,
1718 map:: MapList ,
18- reshape:: StructToFixedList ,
19+ reshape:: { RowMajorToColumnMajor , StructToFixedList } ,
1920 semantic:: { BinaryToListUInt8 , StringToVideoCodecUInt32 , TimeSpecToNanos } ,
2021} ;
2122
@@ -93,6 +94,27 @@ pub fn list_timespec_to_list_nanos(list_array: &ListArray) -> Result<ListArray,
9394 Ok ( pipeline. transform ( list_array) ?)
9495}
9596
97+ /// Converts 3x3 row-major f64 matrices stored in variable-size lists to column-major f32 fixed-size lists.
98+ pub fn list_3x3_row_major_to_column_major ( list_array : & ListArray ) -> Result < ListArray , OpError > {
99+ let pipeline = MapList :: new (
100+ ListToFixedSizeList :: new ( 9 )
101+ . then ( RowMajorToColumnMajor :: new ( 3 , 3 ) )
102+ . then ( MapFixedSizeList :: new ( PrimitiveCast :: <
103+ Float64Array ,
104+ Float32Array ,
105+ > :: new ( ) ) ) ,
106+ ) ;
107+ Ok ( pipeline. transform ( list_array) ?)
108+ }
109+
110+ /// Converts u32 width and height fields to a `Resolution` component (fixed-size list with two f32 values).
111+ pub fn width_height_to_resolution ( list_array : & ListArray ) -> Result < ListArray , OpError > {
112+ let pipeline = MapList :: new ( StructToFixedList :: new ( [ "width" , "height" ] ) . then (
113+ MapFixedSizeList :: new ( PrimitiveCast :: < UInt32Array , Float32Array > :: new ( ) ) ,
114+ ) ) ;
115+ Ok ( pipeline. transform ( list_array) ?)
116+ }
117+
96118// TODO(grtlr): This example is still missing `tf`-style transforms.
97119
98120fn main ( ) -> anyhow:: Result < ( ) > {
@@ -287,12 +309,46 @@ fn main() -> anyhow::Result<()> {
287309 } ) ?
288310 . build ( ) ;
289311
312+ // Simple pinhole camera calibration lens, setting `image_from_camera` from the `K` matrix.
313+ // TODO(michael): set child_frame of Pinhole?
314+ let pinhole_lens = Lens :: for_input_column (
315+ EntityPathFilter :: all ( ) ,
316+ "foxglove.CameraCalibration:message" ,
317+ )
318+ . output_columns ( |out| {
319+ out. time (
320+ TIME_NAME ,
321+ args. epoch . time_type ( ) ,
322+ [
323+ Op :: access_field ( "timestamp" ) ,
324+ Op :: func ( list_timespec_to_list_nanos) ,
325+ ] ,
326+ )
327+ . component (
328+ Pinhole :: descriptor_resolution ( ) ,
329+ [ Op :: func ( width_height_to_resolution) ] ,
330+ )
331+ . component (
332+ Pinhole :: descriptor_image_from_camera ( ) ,
333+ [
334+ Op :: access_field ( "K" ) ,
335+ Op :: func ( list_3x3_row_major_to_column_major) ,
336+ ] ,
337+ )
338+ . component (
339+ Pinhole :: descriptor_parent_frame ( ) ,
340+ [ Op :: access_field ( "frame_id" ) ] ,
341+ )
342+ } ) ?
343+ . build ( ) ;
344+
290345 let lenses_sink = LensesSink :: new ( GrpcSink :: default ( ) )
291346 . with_lens ( image_lens)
292347 . with_lens ( instance_pose_lens)
293348 . with_lens ( instance_poses_lens)
294349 . with_lens ( video_lens)
295- . with_lens ( transforms_lens) ;
350+ . with_lens ( transforms_lens)
351+ . with_lens ( pinhole_lens) ;
296352
297353 let ( rec, _serve_guard) = args. rerun . init ( "rerun_example_mcap_protobuf" ) ?;
298354 rec. set_sink ( Box :: new ( lenses_sink) ) ;
0 commit comments