1mod common;
6pub mod types;
7
8pub use crate::types::*;
9
10use crate::common::*;
11
12#[derive(Debug, Clone, PartialEq, Eq, Hash)]
14pub struct Sample {
15 pub image_path: PathBuf,
16 pub annotation: Annotation,
17}
18
19pub fn load<P: AsRef<Path>>(dataset_dir: P) -> Result<Vec<Sample>> {
21 let dataset_dir_r = dataset_dir.as_ref();
22 let image_dir = dataset_dir_r.join("JPEGImages");
23 let annotations_dir = dataset_dir_r.join("Annotations");
24
25 let samples = image_dir
26 .read_dir()?
27 .map(|entry_result| -> Result<Option<_>> {
28 let entry = entry_result?;
29 if entry.file_type()?.is_file() {
30 let path = entry.path();
31 if let Some(ext) = path.extension() {
32 if ext == "jpg" {
33 let name = path.file_stem().unwrap();
34 return Ok(Some((name.to_owned(), path.to_owned())));
35 }
36 }
37 }
38 Ok(None)
39 })
40 .filter_map(|arg| match arg {
41 Ok(None) => None,
42 Ok(Some(pair)) => Some(Ok(pair)),
43 Err(err) => Some(Err(err)),
44 })
45 .map(|arg| {
46 let (image_name, image_path) = arg?;
47 let mut xml_path = annotations_dir.join(&image_name);
48 ensure!(xml_path.set_extension("xml"), "set_extension() failed");
49 info!("Loading {}", xml_path.display());
50
51 let content = fs::read_to_string(&xml_path)
53 .with_context(|| format!("cannot open file {}", xml_path.display()))?;
54 let annotation: Annotation = serde_xml_rs::from_str(&content)
55 .with_context(|| format!("failed to parse file {}", xml_path.display()))?;
56
57 let mut file_name = image_name.clone();
59 file_name.push(".jpg");
60 ensure!(
61 file_name == annotation.filename.as_str(),
62 "Expect \"{}\" in <filename>, but get \"{}\"",
63 file_name.to_str().unwrap(),
64 annotation.filename,
65 );
66
67 let sample = Sample {
68 image_path,
69 annotation,
70 };
71
72 Ok(sample)
73 })
74 .collect::<Result<Vec<Sample>, _>>()?;
75
76 Ok(samples)
77}