eventcv_core/representation/
tencode.rs1use super::{
2 age_ms, event_index, frame_len, reference_time, validate_positive, EventFrame, EventFrameData,
3 Representation, RepresentationError, RepresentationKind,
4};
5use crate::EventStream;
6
7const NOTHING: u8 = 0;
10const POSITIVE: u8 = 1;
11const NEGATIVE: u8 = 2;
12
13#[derive(Clone, Copy, Debug)]
14pub struct Tencode {
15 window_ms: f64,
16}
17
18impl Tencode {
19 pub fn new(window_ms: f64) -> Self {
20 Self { window_ms }
21 }
22}
23
24impl Default for Tencode {
25 fn default() -> Self {
26 Self::new(30.0)
27 }
28}
29
30impl Representation for Tencode {
31 type Output = EventFrame;
32
33 fn generate(&self, stream: &EventStream) -> Result<EventFrame, RepresentationError> {
34 validate_positive(self.window_ms, "window_ms")?;
35 let (width, height, length) = frame_len(stream, 3)?;
36 let plane_len = width * height;
37 let mut latest_t = vec![0_u64; plane_len];
41 let mut latest_state = vec![NOTHING; plane_len];
42 let mut values = vec![0_u8; length];
43
44 if let Some(reference) = reference_time(stream) {
45 for event in stream.iter() {
46 if age_ms(stream, reference, event.timestamp) > self.window_ms {
47 continue;
48 }
49 let index = event_index(event, width, height)?;
50 if latest_state[index] == NOTHING || event.timestamp >= latest_t[index] {
53 latest_t[index] = event.timestamp;
54 latest_state[index] = if event.polarity { POSITIVE } else { NEGATIVE };
55 }
56 }
57
58 for index in 0..plane_len {
59 match latest_state[index] {
60 POSITIVE => values[index] = u8::MAX,
61 NEGATIVE => values[2 * plane_len + index] = u8::MAX,
62 _ => continue,
63 }
64 values[plane_len + index] = (255.0
65 * age_ms(stream, reference, latest_t[index])
66 / self.window_ms)
67 .round()
68 .clamp(0.0, 255.0) as u8;
69 }
70 }
71
72 Ok(EventFrame {
73 data: EventFrameData::U8(values),
74 channels: 3,
75 width,
76 height,
77 kind: RepresentationKind::Tencode,
78 channel_names: vec![
79 "positive".to_owned(),
80 "age".to_owned(),
81 "negative".to_owned(),
82 ],
83 })
84 }
85}
86
87#[cfg(test)]
88mod tests {
89 use ndarray::array;
90
91 use super::{Representation, Tencode};
92 use crate::{representation::EventFrameData, EventStream};
93
94 #[test]
95 fn encodes_latest_polarity_and_age() {
96 let stream = EventStream::from_array2(
97 array![[0, 0, 10_000, 1], [1, 0, 30_000, 1], [1, 0, 30_000, 0]],
98 2,
99 1,
100 0.001,
101 );
102
103 let frame = Tencode::new(30.0).generate(&stream).unwrap();
104
105 assert_eq!(
106 frame.data(),
107 &EventFrameData::U8(vec![255, 0, 170, 0, 0, 255])
108 );
109 }
110}