cleaning, rename, add loops
This commit is contained in:
Generated
+18
-11
@@ -74,12 +74,30 @@ dependencies = [
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.75"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "bird-detector"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"chrono",
|
||||
"clap",
|
||||
"env_logger",
|
||||
"image",
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.4.1"
|
||||
@@ -318,17 +336,6 @@ dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "krmdet"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"clap",
|
||||
"env_logger",
|
||||
"image",
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.150"
|
||||
|
||||
+2
-1
@@ -1,5 +1,5 @@
|
||||
[package]
|
||||
name = "krmdet"
|
||||
name = "bird-detector"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
@@ -12,3 +12,4 @@ clap = "4.4.7"
|
||||
log = "0.4.20"
|
||||
env_logger = "0.10.0"
|
||||
chrono = "0.4.31"
|
||||
anyhow = "1.0.75"
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
*
|
||||
!.gitignore
|
||||
+71
-27
@@ -1,29 +1,68 @@
|
||||
use std::os::unix::fs::MetadataExt;
|
||||
use std::path::PathBuf;
|
||||
use std::time::Duration;
|
||||
use anyhow::Context;
|
||||
|
||||
use chrono::{NaiveDateTime, Utc};
|
||||
use image::{GenericImageView, Pixel};
|
||||
use log::{debug, error, info};
|
||||
|
||||
/// Folder the camera images are uploaded to
|
||||
const FOLDER_WITH_NEW_IMAGES: &str = "/dev/shm/camera";
|
||||
|
||||
/// File created in the uploads directory when the upload finishes.
|
||||
const COMMIT_FILENAME : &str = "commit";
|
||||
|
||||
/// Folder where the cropped bird pics are saved
|
||||
const FOLDER_WITH_BIRD_IMAGES: &str = "/backup/krmitko";
|
||||
|
||||
/// Image cropping config: left top X
|
||||
const CROP_X : u32 = 1872;
|
||||
|
||||
/// Image cropping config: left top Y
|
||||
const CROP_Y : u32 = 1329;
|
||||
|
||||
/// Image cropping config: crop width
|
||||
const CROP_W : u32 = 1000;
|
||||
|
||||
/// Image cropping config: crop height
|
||||
const CROP_H : u32 = 750;
|
||||
|
||||
/// Thumbnail width, used for bird detection (together with height creates the kernel size)
|
||||
/// This is a compromise between sensitivity and susceptibility to false positives.
|
||||
const THUMB_W: usize = 12;
|
||||
|
||||
/// Thumbnail height
|
||||
const THUMB_H: usize = 8;
|
||||
|
||||
/// Threshold for bird detection.
|
||||
/// Bird is detected if the sum of deviations from a median value in a picture exceeds this threshold.
|
||||
const THRESHOLD_DEVIATION: u32 = 500;
|
||||
|
||||
fn main() {
|
||||
open_and_reduce_img();
|
||||
env_logger::init();
|
||||
|
||||
let commit_file = PathBuf::from(FOLDER_WITH_NEW_IMAGES).join(COMMIT_FILENAME);
|
||||
|
||||
loop {
|
||||
if !commit_file.exists() {
|
||||
debug!("No commit file, wait.");
|
||||
std::thread::sleep(Duration::from_secs(10));
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Err(e) = process_camera_pics() {
|
||||
error!("Error processing pics: {e}");
|
||||
}
|
||||
|
||||
let _ = std::fs::remove_dir_all(FOLDER_WITH_NEW_IMAGES);
|
||||
}
|
||||
}
|
||||
|
||||
fn process_camera_pics() -> anyhow::Result<()> {
|
||||
info!("Processing camera pics");
|
||||
|
||||
const FOLDER_WITH_IMAGES : &str = "../2/";
|
||||
|
||||
const FOLDER_OUTPUT : &str = "birds";
|
||||
|
||||
const THUMB_W : usize = 12;
|
||||
const THUMB_H : usize = 8;
|
||||
|
||||
const THRESHOLD_DEVIATION : u32 = 500;
|
||||
|
||||
fn open_and_reduce_img() {
|
||||
env_logger::init_from_env("LOGGING");
|
||||
|
||||
info!("Bird finder starts");
|
||||
|
||||
let paths = std::fs::read_dir(FOLDER_WITH_IMAGES).unwrap();
|
||||
let paths = std::fs::read_dir(FOLDER_WITH_NEW_IMAGES).context("Read folder with images")?;
|
||||
|
||||
let mut crops = vec![];
|
||||
let mut thumbs = vec![];
|
||||
@@ -33,16 +72,20 @@ fn open_and_reduce_img() {
|
||||
for dir_entry in paths {
|
||||
let Ok(dir_entry) = dir_entry else { continue; };
|
||||
let Ok(meta) = dir_entry.metadata() else { continue; };
|
||||
if !meta.is_file() {
|
||||
if !meta.is_file() || !dir_entry.file_name().to_string_lossy().ends_with(".jpg") {
|
||||
continue;
|
||||
}
|
||||
|
||||
timestamps.push(meta.ctime());
|
||||
|
||||
debug!("{}", dir_entry.path().display());
|
||||
|
||||
let img = image::open(dir_entry.path()).unwrap();
|
||||
let crop = img.crop_imm(1872, 1329, 1000, 750);
|
||||
let Ok(img) = image::open(dir_entry.path()) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
// File loaded fine, assume it's OK
|
||||
timestamps.push(meta.ctime());
|
||||
|
||||
let crop = img.crop_imm(CROP_X, CROP_Y, CROP_W, CROP_H);
|
||||
let thumb = crop.thumbnail(THUMB_W as u32, THUMB_H as u32);
|
||||
|
||||
crops.push(crop);
|
||||
@@ -86,12 +129,15 @@ fn open_and_reduce_img() {
|
||||
if deviation > THRESHOLD_DEVIATION {
|
||||
info!("LIKELY BIRD!!!! in picture #{thumb_num}");
|
||||
|
||||
let datetime = parse_unix_ts(timestamps[thumb_num]).format("%Y-%m-%d_%H-%M-%S");
|
||||
let path = format!("{}/{}.jpg", FOLDER_OUTPUT, datetime);
|
||||
let datetime_str = parse_unix_ts(timestamps[thumb_num]).format("%Y-%m-%d_%H-%M-%S");
|
||||
let path = format!("{}/{}.jpg", FOLDER_WITH_BIRD_IMAGES, datetime_str);
|
||||
let mut pb = PathBuf::from(path);
|
||||
|
||||
// Ensure we do not overwrite a file if there are multiple in the same second!
|
||||
// This adds -2, -3 etc. to the file name
|
||||
let mut cnt = 2;
|
||||
while pb.exists() {
|
||||
pb.set_file_name(format!("{}-{cnt}.jpg", datetime));
|
||||
pb.set_file_name(format!("{}-{cnt}.jpg", datetime_str));
|
||||
cnt += 1;
|
||||
}
|
||||
|
||||
@@ -101,9 +147,7 @@ fn open_and_reduce_img() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// crop.save(format!("{}/{}", FOLDER_OUTPUT, dir_entry.file_name().to_string_lossy())).unwrap();
|
||||
// thumb.save(format!("{}/th-{}", FOLDER_OUTPUT, dir_entry.file_name().to_string_lossy())).unwrap();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn parse_unix_ts(ts: i64) -> chrono::DateTime<Utc> {
|
||||
|
||||
Reference in New Issue
Block a user