@@ -2,7 +2,8 @@ use std::ops::RangeTo;
22use std:: path:: { Path , PathBuf } ;
33use std:: time:: Instant ;
44use anyhow:: Result ;
5- use image:: { ImageBuffer , Rgba , RgbaImage } ;
5+ use image:: { GenericImage , ImageBuffer , Rgba , RgbaImage } ;
6+ use image:: imageops:: FilterType ;
67use imageproc:: drawing:: draw_text_mut;
78use log:: { debug, trace} ;
89use rand:: { Rng , thread_rng} ;
@@ -13,33 +14,59 @@ use crate::objects::ObjectManager;
1314pub struct TargetGenerator {
1415 output : PathBuf ,
1516 backgrounds_path : PathBuf ,
16- pub shape_manager : ObjectManager ,
17+ pub object_manager : ObjectManager ,
1718 background_loader : BackgroundLoader ,
1819}
1920
2021impl TargetGenerator {
2122 pub fn new < Q : AsRef < Path > > ( output : Q , background_path : Q , objects_path : Q ) -> Result < Self > {
2223
24+ let mut object_manager = ObjectManager :: new ( objects_path) ;
25+ object_manager. load_objects ( ) ?;
26+
2327 Ok ( Self {
2428 output : output. as_ref ( ) . to_path_buf ( ) ,
2529 backgrounds_path : background_path. as_ref ( ) . to_path_buf ( ) ,
26- shape_manager : ObjectManager :: new ( objects_path ) ,
30+ object_manager ,
2731 background_loader : BackgroundLoader :: new ( background_path) ?,
2832 } )
2933 }
3034
31- pub fn generate_target ( & self , altitude : f32 ) -> Result < ( ) > {
32-
33- debug ! ( "Beginning to generate a target..." ) ;
35+ pub fn generate_target ( & self , altitude : f32 , fov : f32 , iteration : u32 ) -> Result < ( ) > {
36+ trace ! ( "Beginning to generate a target..." ) ;
3437
3538 let mut background = self . background_loader . random ( ) . unwrap ( ) . clone ( ) ;
3639 let ( w, h) = ( background. width ( ) , background. height ( ) ) ;
37-
38-
39-
40-
41-
42- background. save ( "output.png" ) ?;
40+ let set = self . object_manager . generate_set ( 1 ) ?;
41+
42+ let ground_width = calculate_ground_width ( altitude, fov) ;
43+ let meters_per_pixel = meters_per_pixel ( w, ground_width) ;
44+
45+ for obj in set {
46+ let clone = & obj. dynamic_image . clone ( ) ;
47+ let ( obj_w, obj_h) = ( obj. dynamic_image . width ( ) , obj. dynamic_image . height ( ) ) ;
48+ let ( x, y) = ( thread_rng ( ) . gen_range ( 0 ..w - obj_w) , thread_rng ( ) . gen_range ( 0 ..h - obj_h) ) ;
49+ trace ! ( "Placing object at {}, {}" , x, y) ;
50+ /*let expected_size = expected_object_size_pixels(obj.object_width_meters, meters_per_pixel);
51+
52+ let aspect_ratio = obj_w as f32 / obj_h as f32;
53+
54+ debug!("Resizing object to {}x{}", expected_size as u32, (expected_size / aspect_ratio) as u32); //TODO: too big
55+
56+ background.copy_from(&clone.resize(expected_size as u32, (expected_size / aspect_ratio) as u32, FilterType::Gaussian), x, y)?;*/
57+
58+ let adjusted = resize_ratio ( obj. object_width_meters , METER_CONST ) ;
59+ debug ! ( "Width: {}, Height: {}" , obj_w, obj_h) ;
60+ let aspect_ratio = obj_w as f32 / obj_h as f32 ;
61+ let ( obj_w, obj_h) = ( adjusted as u32 , ( adjusted / aspect_ratio) as u32 ) ;
62+
63+ debug ! ( "Resizing object to {}x{}" , obj_w, obj_h) ; //TODO: too big
64+
65+ background. copy_from ( & clone. resize ( obj_w, obj_h, FilterType :: Gaussian ) , x, y) ?;
66+ }
67+
68+ background. save ( format ! ( "output_{iteration}.png" ) ) ?;
69+ debug ! ( "Saved generated target to output_{iteration}.png" ) ;
4370
4471 Ok ( ( ) )
4572 }
@@ -55,6 +82,26 @@ impl TargetGenerator {
5582 }
5683}
5784
85+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash , PartialOrd , Ord ) ]
86+ pub struct BoundingBox {
87+ pub x : u32 ,
88+ pub y : u32 ,
89+ pub width : u32 ,
90+ pub height : u32 ,
91+ }
92+
93+ const METER_CONST : f32 = 35.0 ;
94+
95+ fn resize_ratio ( object_real_size : f32 , pixels_per_meter : f32 ) -> f32 {
96+ debug ! ( "Real size: {}, Pixels per meter: {}" , object_real_size, pixels_per_meter) ;
97+ object_real_size * pixels_per_meter
98+ }
99+
100+ fn degrees_to_radians ( degrees : f32 ) -> f32 {
101+ degrees * std:: f32:: consts:: PI / 180.0
102+ }
103+
104+ // Calculate the fov in radians based on the image width, height and focal length
58105fn calculate_fov ( image_width : u32 , image_height : u32 , focal_length : f32 ) -> f32 {
59106 2.0 * ( 0.5 * image_width as f32 / focal_length) . atan ( )
60107}
@@ -79,6 +126,6 @@ fn expected_object_size_pixels(real_size: f32, meters_per_pixel: f32) -> f32 {
79126pub fn test_generate_target ( ) {
80127 SimpleLogger :: new ( ) . init ( ) . unwrap ( ) ;
81128
82- let tg = TargetGenerator :: new ( "output" , "backgrounds" , "shapes " ) . unwrap ( ) ;
83- tg. generate_target ( 22.8 ) . unwrap ( ) ;
129+ let tg = TargetGenerator :: new ( "output" , "backgrounds" , "objects " ) . unwrap ( ) ;
130+ tg. generate_target ( 22.8 , degrees_to_radians ( 35.0 ) , 1 ) . unwrap ( ) ;
84131}
0 commit comments