Compare commits

..

No commits in common. "056bb2f96ce74fdb24ef7e5b59bca21ffc24391c" and "57a2c3197e2acd25b4eace223be6b814ffb5ca0f" have entirely different histories.

10 changed files with 15 additions and 70 deletions

2
.gitignore vendored
View File

@ -1,4 +1,2 @@
/venv /venv
/frames /frames
**/*.png
thermaldecoder/target

View File

@ -1,15 +0,0 @@
### Thermal decoder
https://wiki.telavivmakers.org/tamiwiki/projects/thermalcam
### Rust lib usage
# if you don't already have a virtualenv. Linux specific, adjust to your OS.
```bash
virtualenv venv
. venv/bin/activate
pip install -r requirements.txt
(cd thermaldecoder; maturin develop -r)
python test_rust.py
```

3
readme.md Normal file
View File

@ -0,0 +1,3 @@
### Thermal decoder
https://wiki.telavivmakers.org/tamiwiki/projects/thermalcam

View File

@ -12,7 +12,6 @@ jedi==0.19.1
kiwisolver==1.4.5 kiwisolver==1.4.5
matplotlib==3.8.2 matplotlib==3.8.2
matplotlib-inline==0.1.6 matplotlib-inline==0.1.6
maturin==1.4.0
numpy==1.26.2 numpy==1.26.2
opencv-python==4.8.1.78 opencv-python==4.8.1.78
packaging==23.2 packaging==23.2

View File

@ -1,11 +0,0 @@
from pathlib import Path
from thermaldecoder import decode
import numpy as np
import matplotlib.pyplot as plt
root = Path('frames')
root.mkdir(exist_ok=True)
frames = decode('in.pcap', 'frames')
f = np.array(frames[0])
f.shape = (384, 288)
plt.imshow(f)
plt.show()

Binary file not shown.

View File

@ -400,7 +400,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c39fd04924ca3a864207c66fc2cd7d22d7c016007f9ce846cbb9326331930a" checksum = "14c39fd04924ca3a864207c66fc2cd7d22d7c016007f9ce846cbb9326331930a"
[[package]] [[package]]
name = "thermaldecoder" name = "thermalcamdecoder"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",

View File

@ -1,18 +1,14 @@
[package] [package]
name = "thermaldecoder" name = "thermalcamdecoder"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
name = "thermaldecoder"
crate-type = ["cdylib"]
[dependencies] [dependencies]
anyhow = "1.0.77" anyhow = "1.0.77"
indicatif = "0.17.7" indicatif = "0.17.7"
pcap-parser = { version = "0.14.1", features = ["data"] } pcap-parser = { version = "0.14.1", features = ["data"] }
png = "0.17.10" png = "0.17.10"
pyo3 = { version = "0.20.0", "features" = ["extension-module"] } pyo3 = "0.20.0"
serde = { version = "1.0.193", features = ["derive", "serde_derive", "alloc"] } serde = { version = "1.0.193", features = ["derive", "serde_derive", "alloc"] }

View File

@ -1,7 +1,5 @@
use indicatif::{ProgressBar, ProgressIterator}; use indicatif::{ProgressBar, ProgressIterator};
use png; use png;
use pyo3::exceptions::PyValueError;
use pyo3::prelude::*;
use std::fs::File; use std::fs::File;
use std::io::BufWriter; use std::io::BufWriter;
use std::io::Write; use std::io::Write;
@ -10,8 +8,8 @@ use std::path::Path;
use pcap_parser::traits::PcapReaderIterator; use pcap_parser::traits::PcapReaderIterator;
use pcap_parser::*; use pcap_parser::*;
fn get_packets_without_udp_header(filename: &str) -> anyhow::Result<(Vec<Vec<u8>>, usize, usize)> { fn get_packets_without_udp_header() -> anyhow::Result<(Vec<Vec<u8>>, usize, usize)> {
let file = File::open(filename)?; let file = File::open("in.pcap")?;
let mut cap = PcapNGReader::new(65535, file)?; let mut cap = PcapNGReader::new(65535, file)?;
let mut i = 0; let mut i = 0;
let mut size = 0; let mut size = 0;
@ -104,19 +102,11 @@ impl Header {
const HDR_SIZE: usize = std::mem::size_of::<Header>(); const HDR_SIZE: usize = std::mem::size_of::<Header>();
#[pyfunction] fn main() -> anyhow::Result<()> {
fn decode(filename: &str, frames_root: &str) -> PyResult<Vec<Vec<u16>>> { let (data, i, size) = get_packets_without_udp_header()?;
let res =
decode_raw(filename, frames_root).map_err(|_| PyValueError::new_err("failed to read"))?;
Ok(res.into())
}
fn decode_raw(filename: &str, frames_root: &str) -> anyhow::Result<Vec<Vec<u16>>> {
let (data, i, size) = get_packets_without_udp_header(filename)?;
println!("found {} packets, saved {}, {} size", i, data.len(), size); println!("found {} packets, saved {}, {} size", i, data.len(), size);
let dump_filename = format!("{}/dump.bin", filename); let mut dump = File::create_new("dump.bin");
let mut dump = File::create_new(dump_filename);
let mut frames = vec![]; let mut frames = vec![];
let mut parts = vec![]; let mut parts = vec![];
for packet in data.iter() { for packet in data.iter() {
@ -135,7 +125,7 @@ fn decode_raw(filename: &str, frames_root: &str) -> anyhow::Result<Vec<Vec<u16>>
println!("writing raw pngs"); println!("writing raw pngs");
let pb = ProgressBar::new(frames.len() as u64); let pb = ProgressBar::new(frames.len() as u64);
for (i, frame) in frames.iter().enumerate().progress_with(pb) { for (i, frame) in frames.iter().enumerate().progress_with(pb) {
let name = format!("{}/{:04}.png", frames_root, i); let name = format!("{:03}.png", i);
let path = Path::new(&name); let path = Path::new(&name);
let file = File::create(path).unwrap(); let file = File::create(path).unwrap();
let ref mut w = BufWriter::new(file); let ref mut w = BufWriter::new(file);
@ -148,9 +138,8 @@ fn decode_raw(filename: &str, frames_root: &str) -> anyhow::Result<Vec<Vec<u16>>
println!("writing calibrated (value is temperature)"); println!("writing calibrated (value is temperature)");
let pb = ProgressBar::new(frames.len() as u64); let pb = ProgressBar::new(frames.len() as u64);
let mut framesu16 = vec![];
for (i, frame) in frames.iter().enumerate().progress_with(pb) { for (i, frame) in frames.iter().enumerate().progress_with(pb) {
let name = format!("{}/temp_{:04}.png", frames_root, i); let name = format!("temp_{:03}.png", i);
let path = Path::new(&name); let path = Path::new(&name);
let file = File::create(path).unwrap(); let file = File::create(path).unwrap();
let ref mut w = BufWriter::new(file); let ref mut w = BufWriter::new(file);
@ -158,12 +147,8 @@ fn decode_raw(filename: &str, frames_root: &str) -> anyhow::Result<Vec<Vec<u16>>
encoder.set_color(png::ColorType::Grayscale); encoder.set_color(png::ColorType::Grayscale);
encoder.set_depth(png::BitDepth::Eight); encoder.set_depth(png::BitDepth::Eight);
let mut writer = encoder.write_header()?; let mut writer = encoder.write_header()?;
//let samples: &[u16] = unsafe { std::slice::from_raw_parts(p.cast(), frame.len() / 2) }; let p = frame.as_ptr();
let samples: Vec<u16> = (0..frame.len()) let samples: &[u16] = unsafe { std::slice::from_raw_parts(p.cast(), frame.len() / 2) };
.step_by(2)
.map(|i| u16::from_be_bytes([frame[i], frame[i + 1]]))
.collect();
framesu16.push(samples.clone());
let frame = samples let frame = samples
.iter() .iter()
.copied() .copied()
@ -179,11 +164,5 @@ fn decode_raw(filename: &str, frames_root: &str) -> anyhow::Result<Vec<Vec<u16>>
writer.write_image_data(&frame)?; writer.write_image_data(&frame)?;
} }
Ok(framesu16)
}
#[pymodule]
fn thermaldecoder(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
m.add_function(wrap_pyfunction!(decode, m)?)?;
Ok(()) Ok(())
} }

View File

@ -1,4 +0,0 @@
//fn main() -> anyhow::Result<()> {
// decode_raw("dump.bin")?;
// Ok(())
//}