From 26de63d239f54cc1a537a0a6db30c0a482c4f5aa Mon Sep 17 00:00:00 2001 From: jamjamjon Date: Mon, 19 May 2025 23:25:48 +0800 Subject: [PATCH] update --- examples/classifier/main.rs | 2 +- examples/depth-pro/main.rs | 1 + examples/fastsam/main.rs | 2 +- examples/owlv2/main.rs | 2 +- examples/sam2/README.md | 3 +- examples/sapiens/README.md | 2 +- examples/smolvlm/main.rs | 1 - .../README.md | 0 .../main.rs | 4 +- examples/yolo-sam2/main.rs | 1 - examples/yolo/README.md | 28 +- examples/yolo/main.rs | 113 +- src/inference/model_config.rs | 30 +- src/inference/prob.rs | 2 +- src/models/convnext/config.rs | 1 + src/models/depth_pro/config.rs | 1 + src/models/florence2/impl.rs | 3 - src/models/grounding_dino/impl.rs | 23 +- src/models/moondream2/impl.rs | 1 + src/models/owl/impl.rs | 12 +- src/models/picodet/impl.rs | 20 +- src/models/pipeline/basemodel.rs | 1 - src/models/pipeline/image_classifier.rs | 45 +- src/models/rfdetr/impl.rs | 22 +- src/models/rtdetr/impl.rs | 23 +- src/models/rtmo/impl.rs | 1 - src/models/sam2/impl.rs | 1 - src/models/sapiens/impl.rs | 7 +- src/models/smolvlm/config.rs | 4 +- src/models/smolvlm/impl.rs | 2 - src/models/trocr/impl.rs | 1 - src/models/yolo/config.rs | 76 +- src/models/yolo/impl.rs | 207 +- src/models/yolop/impl.rs | 1 - src/utils/dynconf.rs | 8 +- src/utils/names.rs | 4624 +++++++++++++++++ 36 files changed, 4946 insertions(+), 329 deletions(-) rename examples/{yolov8-rtdetr => ultralytics-rtdetr}/README.md (100%) rename examples/{yolov8-rtdetr => ultralytics-rtdetr}/main.rs (91%) diff --git a/examples/classifier/main.rs b/examples/classifier/main.rs index 73245ff..cb0d987 100644 --- a/examples/classifier/main.rs +++ b/examples/classifier/main.rs @@ -12,7 +12,7 @@ struct Args { device: String, /// model name - #[argh(option, default = "String::from(\"beit\")")] + #[argh(option, default = "String::from(\"mobileone\")")] model: String, /// source image diff --git a/examples/depth-pro/main.rs b/examples/depth-pro/main.rs index 8c0f559..c167d56 100644 --- a/examples/depth-pro/main.rs +++ b/examples/depth-pro/main.rs @@ -27,6 +27,7 @@ fn main() -> Result<()> { .with_model_dtype(args.dtype.as_str().try_into()?) .with_model_device(args.device.as_str().try_into()?) .commit()?; + let mut model = DepthPro::new(config)?; // load diff --git a/examples/fastsam/main.rs b/examples/fastsam/main.rs index 47a54a2..eaacb74 100644 --- a/examples/fastsam/main.rs +++ b/examples/fastsam/main.rs @@ -45,7 +45,7 @@ fn main() -> Result<()> { annotator.annotate(x, y)?.save(format!( "{}.jpg", usls::Dir::Current - .base_dir_with_subs(&["runs", "FastSAM"])? + .base_dir_with_subs(&["runs", model.spec()])? .join(usls::timestamp(None)) .display(), ))?; diff --git a/examples/owlv2/main.rs b/examples/owlv2/main.rs index a0f9a08..3a0c6b4 100644 --- a/examples/owlv2/main.rs +++ b/examples/owlv2/main.rs @@ -51,7 +51,7 @@ fn main() -> Result<()> { // owlv2_base() .with_model_dtype(args.dtype.as_str().try_into()?) .with_model_device(args.device.as_str().try_into()?) - .with_class_names(&args.labels.iter().map(|x| x.as_str()).collect::>()) + .with_text_names(&args.labels.iter().map(|x| x.as_str()).collect::>()) .commit()?; let mut model = OWLv2::new(config)?; diff --git a/examples/sam2/README.md b/examples/sam2/README.md index 5a97486..a5f181e 100644 --- a/examples/sam2/README.md +++ b/examples/sam2/README.md @@ -1,6 +1,5 @@ ## Quick Start ```Shell - -cargo run -r -F cuda --example sam -- --device cuda --scale t +cargo run -r -F cuda --example sam2 -- --device cuda --scale t ``` \ No newline at end of file diff --git a/examples/sapiens/README.md b/examples/sapiens/README.md index 7699915..82903f5 100644 --- a/examples/sapiens/README.md +++ b/examples/sapiens/README.md @@ -1,7 +1,7 @@ ## Quick Start ```shell -cargo run -r -F cuda --example sapiens -- --device cuda +cargo run -r -F cuda --example sapiens -- --device cuda ``` ## Results diff --git a/examples/smolvlm/main.rs b/examples/smolvlm/main.rs index 7069282..8063d4f 100644 --- a/examples/smolvlm/main.rs +++ b/examples/smolvlm/main.rs @@ -36,7 +36,6 @@ fn main() -> Result<()> { } .with_device_all(args.device.as_str().try_into()?) .commit()?; - let mut model = SmolVLM::new(config)?; // load images diff --git a/examples/yolov8-rtdetr/README.md b/examples/ultralytics-rtdetr/README.md similarity index 100% rename from examples/yolov8-rtdetr/README.md rename to examples/ultralytics-rtdetr/README.md diff --git a/examples/yolov8-rtdetr/main.rs b/examples/ultralytics-rtdetr/main.rs similarity index 91% rename from examples/yolov8-rtdetr/main.rs rename to examples/ultralytics-rtdetr/main.rs index b085f28..6de6b8a 100644 --- a/examples/yolov8-rtdetr/main.rs +++ b/examples/ultralytics-rtdetr/main.rs @@ -22,7 +22,7 @@ fn main() -> Result<()> { let args: Args = argh::from_env(); // build model - let config = ModelConfig::yolo_v8_rtdetr_l() + let config = ModelConfig::ultralytics_rtdetr_l() .with_model_dtype(args.dtype.as_str().try_into()?) .with_model_device(args.device.as_str().try_into()?) .commit()?; @@ -41,7 +41,7 @@ fn main() -> Result<()> { annotator.annotate(x, y)?.save(format!( "{}.jpg", usls::Dir::Current - .base_dir_with_subs(&["runs", "YOLOv8-RT-DETR"])? + .base_dir_with_subs(&["runs", "ultralytics-RTDETR"])? .join(usls::timestamp(None)) .display(), ))?; diff --git a/examples/yolo-sam2/main.rs b/examples/yolo-sam2/main.rs index ed3ca1c..3632be5 100644 --- a/examples/yolo-sam2/main.rs +++ b/examples/yolo-sam2/main.rs @@ -28,7 +28,6 @@ fn main() -> Result<()> { .with_scale(Scale::N) .with_version(8.into()) .with_model_device(args.device.as_str().try_into()?) - .auto_yolo_model_file() .commit()?; let mut yolo = YOLO::new(options_yolo)?; diff --git a/examples/yolo/README.md b/examples/yolo/README.md index d3d214f..4d2f71a 100644 --- a/examples/yolo/README.md +++ b/examples/yolo/README.md @@ -27,27 +27,29 @@ cargo run -r --example yolo -- --task detect --ver v8 --num-classes 6 --model xx # Classify cargo run -r --example yolo -- --task classify --ver 5 --scale s --image-width 224 --image-height 224 --num-classes 1000 --use-imagenet-1k-classes # YOLOv5 -cargo run -r --example yolo -- --task classify --ver 8 --scale n --image-width 224 --image-height 224 # YOLOv8 -cargo run -r --example yolo -- --task classify --ver 11 --scale n --image-width 224 --image-height 224 # YOLOv11 +cargo run -r --example yolo -- --task classify --ver 8 --scale n --image-width 224 --image-height 224 --use-imagenet-1k-classes # YOLOv8 +cargo run -r --example yolo -- --task classify --ver 11 --scale n --image-width 224 --image-height 224 # YOLO11 # Detect -cargo run -r --example yolo -- --task detect --ver 5 --scale n --use-coco-80-classes # YOLOv5 -cargo run -r --example yolo -- --task detect --ver 6 --scale n --use-coco-80-classes # YOLOv6 -cargo run -r --example yolo -- --task detect --ver 7 --scale t --use-coco-80-classes # YOLOv7 -cargo run -r --example yolo -- --task detect --ver 8 --scale n --use-coco-80-classes # YOLOv8 -cargo run -r --example yolo -- --task detect --ver 9 --scale t --use-coco-80-classes # YOLOv9 -cargo run -r --example yolo -- --task detect --ver 10 --scale n --use-coco-80-classes # YOLOv10 -cargo run -r --example yolo -- --task detect --ver 11 --scale n --use-coco-80-classes # YOLOv11 -cargo run -r --example yolo -- --task detect --ver 8 --model v8-s-world-v2-shoes.onnx # YOLOv8-world +cargo run -r --example yolo -- --task detect --ver 5 --scale n --use-coco-80-classes --dtype fp16 # YOLOv5 +cargo run -r --example yolo -- --task detect --ver 6 --scale n --use-coco-80-classes --dtype fp16 # YOLOv6 +cargo run -r --example yolo -- --task detect --ver 7 --scale t --use-coco-80-classes --dtype fp16 # YOLOv7 +cargo run -r --example yolo -- --task detect --ver 8 --scale n --use-coco-80-classes --dtype fp16 # YOLOv8 +cargo run -r --example yolo -- --task detect --ver 9 --scale t --use-coco-80-classes --dtype fp16 # YOLOv9 +cargo run -r --example yolo -- --task detect --ver 10 --scale n --use-coco-80-classes --dtype fp16 # YOLOv10 +cargo run -r --example yolo -- --task detect --ver 11 --scale n --use-coco-80-classes --dtype fp16 # YOLO11 +cargo run -r --example yolo -- --task detect --ver 12 --scale n --use-coco-80-classes --dtype fp16 # YOLOv12 +cargo run -r --example yolo -- --task detect --ver 8 --model v8-s-world-v2-shoes.onnx # YOLOv8-world # Pose cargo run -r --example yolo -- --task pose --ver 8 --scale n # YOLOv8-Pose cargo run -r --example yolo -- --task pose --ver 11 --scale n # YOLOv11-Pose # Segment -cargo run -r --example yolo -- --task segment --ver 5 --scale n # YOLOv5-Segment -cargo run -r --example yolo -- --task segment --ver 8 --scale n # YOLOv8-Segment -cargo run -r --example yolo -- --task segment --ver 11 --scale n # YOLOv8-Segment +cargo run -r --example yolo -- --task segment --ver 5 --scale n --use-coco-80-classes --dtype fp16 # YOLOv5-Segment +cargo run -r --example yolo -- --task segment --ver 8 --scale n --use-coco-80-classes --dtype fp16 # YOLOv8-Segment +cargo run -r --example yolo -- --task segment --ver 9 --scale c --use-coco-80-classes --dtype fp16 # YOLOv9-Segment +cargo run -r --example yolo -- --task segment --ver 11 --scale n --use-coco-80-classes --dtype fp16 # YOLO11-Segment # Obb cargo run -r --example yolo -- --ver 8 --task obb --scale n --image-width 1024 --image-height 1024 --source images/dota.png # YOLOv8-Obb diff --git a/examples/yolo/main.rs b/examples/yolo/main.rs index 4f69ad9..4c25ba1 100644 --- a/examples/yolo/main.rs +++ b/examples/yolo/main.rs @@ -5,21 +5,21 @@ use usls::{ }; #[derive(argh::FromArgs, Debug)] -/// Example +/// YOLO Example struct Args { - /// model file + /// model file(.onnx) #[argh(option)] model: Option, - /// source + /// source: image, image folder, video stream #[argh(option, default = "String::from(\"./assets/bus.jpg\")")] source: String, - /// dtype + /// model dtype #[argh(option, default = "String::from(\"auto\")")] dtype: String, - /// task + /// task: det, seg, pose, classify, obb #[argh(option, default = "String::from(\"det\")")] task: String, @@ -27,101 +27,101 @@ struct Args { #[argh(option, default = "8.0")] ver: f32, - /// device + /// device: cuda, cpu, mps #[argh(option, default = "String::from(\"cpu:0\")")] device: String, - /// scale + /// scale: n, s, m, l, x #[argh(option, default = "String::from(\"n\")")] scale: String, - /// trt_fp16 + /// enable TensorRT FP16 #[argh(option, default = "true")] trt_fp16: bool, - /// batch_size + /// batch size #[argh(option, default = "1")] batch_size: usize, - /// min_batch_size + /// bin batch size: For TensorRT #[argh(option, default = "1")] min_batch_size: usize, - /// max_batch_size + /// max Batch size: For TensorRT #[argh(option, default = "4")] max_batch_size: usize, - /// min_image_width + /// min image width: For TensorRT #[argh(option, default = "224")] min_image_width: isize, - /// image_width + /// image width: For TensorRT #[argh(option, default = "640")] image_width: isize, - /// max_image_width + /// max image width: For TensorRT #[argh(option, default = "1280")] max_image_width: isize, - /// min_image_height + /// min image height: For TensorRT #[argh(option, default = "224")] min_image_height: isize, - /// image_height + /// image height: For TensorRT #[argh(option, default = "640")] image_height: isize, - /// max_image_height + /// max image height: For TensorRT #[argh(option, default = "1280")] max_image_height: isize, - /// num_classes + /// num classes #[argh(option)] num_classes: Option, - /// num_keypoints + /// num keypoints #[argh(option)] num_keypoints: Option, - /// use_coco_80_classes - #[argh(switch)] - use_coco_80_classes: bool, - - /// use_coco_17_keypoints_classes - #[argh(switch)] - use_coco_17_keypoints_classes: bool, - - /// use_imagenet_1k_classes - #[argh(switch)] - use_imagenet_1k_classes: bool, - - /// confs - #[argh(option)] - confs: Vec, - - /// keypoint_confs - #[argh(option)] - keypoint_confs: Vec, - - /// exclude_classes - #[argh(option)] - exclude_classes: Vec, - - /// retain_classes - #[argh(option)] - retain_classes: Vec, - - /// class_names + /// class names #[argh(option)] class_names: Vec, - /// keypoint_names + /// keypoint names #[argh(option)] keypoint_names: Vec, - /// topk + /// top-k #[argh(option, default = "5")] topk: usize, + + /// use COCO 80 classes + #[argh(switch)] + use_coco_80_classes: bool, + + /// use COCO 17 keypoints classes + #[argh(switch)] + use_coco_17_keypoints_classes: bool, + + /// use ImageNet 1K classes + #[argh(switch)] + use_imagenet_1k_classes: bool, + + /// confidences + #[argh(option)] + confs: Vec, + + /// keypoint nonfidences + #[argh(option)] + keypoint_confs: Vec, + + /// exclude nlasses + #[argh(option)] + exclude_classes: Vec, + + /// retain classes + #[argh(option)] + retain_classes: Vec, } fn main() -> Result<()> { @@ -129,9 +129,7 @@ fn main() -> Result<()> { .with_env_filter(tracing_subscriber::EnvFilter::from_default_env()) .with_timer(tracing_subscriber::fmt::time::ChronoLocal::rfc_3339()) .init(); - let args: Args = argh::from_env(); - let mut config = ModelConfig::yolo() .with_model_file(&args.model.unwrap_or_default()) .with_task(args.task.as_str().try_into()?) @@ -139,7 +137,6 @@ fn main() -> Result<()> { .with_scale(args.scale.as_str().try_into()?) .with_model_dtype(args.dtype.as_str().try_into()?) .with_model_device(args.device.as_str().try_into()?) - // .with_trt_fp16(args.trt_fp16) .with_model_trt_fp16(args.trt_fp16) .with_model_ixx( 0, @@ -174,27 +171,21 @@ fn main() -> Result<()> { .with_topk(args.topk) .retain_classes(&args.retain_classes) .exclude_classes(&args.exclude_classes); - if args.use_coco_80_classes { config = config.with_class_names(&NAMES_COCO_80); } - if args.use_coco_17_keypoints_classes { config = config.with_keypoint_names(&NAMES_COCO_KEYPOINTS_17); } - if args.use_imagenet_1k_classes { config = config.with_class_names(&NAMES_IMAGENET_1K); } - if let Some(nc) = args.num_classes { config = config.with_nc(nc); } - if let Some(nk) = args.num_keypoints { config = config.with_nk(nk); } - if !args.class_names.is_empty() { config = config.with_class_names( &args @@ -204,7 +195,6 @@ fn main() -> Result<()> { .collect::>(), ); } - if !args.keypoint_names.is_empty() { config = config.with_keypoint_names( &args @@ -216,7 +206,7 @@ fn main() -> Result<()> { } // build model - let mut model = YOLO::try_from(config.auto_yolo_model_file().commit()?)?; + let mut model = YOLO::new(config.commit()?)?; // build dataloader let dl = DataLoader::new(&args.source)? @@ -256,6 +246,7 @@ fn main() -> Result<()> { } } + // summary model.summary(); Ok(()) diff --git a/src/inference/model_config.rs b/src/inference/model_config.rs index 6870cfe..0944b53 100644 --- a/src/inference/model_config.rs +++ b/src/inference/model_config.rs @@ -37,9 +37,9 @@ pub struct ModelConfig { pub processor: ProcessorConfig, // Others - pub class_names: Option>, // TODO: remove Option - pub keypoint_names: Option>, // TODO: remove Option - pub text_names: Option>, // TODO: remove Option + pub class_names: Vec, + pub keypoint_names: Vec, + pub text_names: Vec, pub class_confs: Vec, pub keypoint_confs: Vec, pub text_confs: Vec, @@ -68,9 +68,9 @@ pub struct ModelConfig { impl Default for ModelConfig { fn default() -> Self { Self { - class_names: None, - keypoint_names: None, - text_names: None, + class_names: vec![], + keypoint_names: vec![], + text_names: vec![], class_confs: vec![0.25f32], keypoint_confs: vec![0.3f32], text_confs: vec![0.25f32], @@ -130,11 +130,29 @@ impl ModelConfig { } pub fn commit(mut self) -> anyhow::Result { + // special case for yolo + if self.name == "yolo" && self.model.file.is_empty() { + // version-scale-task + let mut y = String::new(); + if let Some(x) = self.version() { + y.push_str(&x.to_string()); + } + if let Some(x) = self.scale() { + y.push_str(&format!("-{}", x)); + } + if let Some(x) = self.task() { + y.push_str(&format!("-{}", x.yolo_str())); + } + y.push_str(".onnx"); + self.model.file = y; + } + fn try_commit(name: &str, mut m: EngineConfig) -> anyhow::Result { if !m.file.is_empty() { m = m.try_commit(name)?; return Ok(m); } + Ok(m) } diff --git a/src/inference/prob.rs b/src/inference/prob.rs index 107859c..919247f 100644 --- a/src/inference/prob.rs +++ b/src/inference/prob.rs @@ -31,7 +31,7 @@ impl Prob { .with_confidence(confidence); if let Some(names) = names { - if id < names.len() { + if !names.is_empty() { meta = meta.with_name(names[id]); } } diff --git a/src/models/convnext/config.rs b/src/models/convnext/config.rs index 30d0074..5b14c14 100644 --- a/src/models/convnext/config.rs +++ b/src/models/convnext/config.rs @@ -13,6 +13,7 @@ impl crate::ModelConfig { .with_image_std(&[0.229, 0.224, 0.225]) .with_normalize(true) .with_apply_softmax(true) + .with_topk(5) .with_class_names(&NAMES_IMAGENET_1K) } diff --git a/src/models/depth_pro/config.rs b/src/models/depth_pro/config.rs index 5cbddb1..e681f80 100644 --- a/src/models/depth_pro/config.rs +++ b/src/models/depth_pro/config.rs @@ -11,5 +11,6 @@ impl crate::ModelConfig { .with_image_std(&[0.5, 0.5, 0.5]) .with_resize_mode(crate::ResizeMode::FitExact) .with_normalize(true) + .with_model_file("model.onnx") } } diff --git a/src/models/florence2/impl.rs b/src/models/florence2/impl.rs index b1f68b0..3491485 100644 --- a/src/models/florence2/impl.rs +++ b/src/models/florence2/impl.rs @@ -34,17 +34,14 @@ impl Florence2 { let encoder = Engine::try_from_config(&config.textual_encoder)?; let decoder = Engine::try_from_config(&config.textual_decoder)?; let decoder_merged = Engine::try_from_config(&config.textual_decoder_merged)?; - let (batch, height, width) = ( vision_encoder.batch().opt(), vision_encoder.try_height().unwrap_or(&1024.into()).opt(), vision_encoder.try_width().unwrap_or(&1024.into()).opt(), ); - let processor = Processor::try_from_config(&config.processor)? .with_image_width(width as _) .with_image_height(height as _); - let quantizer = Quantizer::default(); let ts = Ts::merge(&[ vision_encoder.ts(), diff --git a/src/models/grounding_dino/impl.rs b/src/models/grounding_dino/impl.rs index d1082d9..8d6d62f 100644 --- a/src/models/grounding_dino/impl.rs +++ b/src/models/grounding_dino/impl.rs @@ -33,24 +33,21 @@ impl GroundingDINO { engine.try_width().unwrap_or(&1200.into()).opt(), engine.ts().clone(), ); - - let class_names = config + let class_names: Vec<_> = config .text_names - .as_ref() - .and_then(|v| { - let v: Vec<_> = v - .iter() - .map(|s| s.trim().to_ascii_lowercase()) - .filter(|s| !s.is_empty()) - .collect(); - (!v.is_empty()).then_some(v) - }) - .ok_or_else(|| anyhow::anyhow!("No valid class names were provided in the config. Ensure the 'text_names' field is non-empty and contains valid class names."))?; + .iter() + .map(|s| s.trim().to_ascii_lowercase()) + .filter(|s| !s.is_empty()) + .collect(); + if class_names.is_empty() { + anyhow::bail!( + "No valid class names were provided in the config. Ensure the 'text_names' field is non-empty and contains valid class names." + ); + } let text_prompt = class_names.iter().fold(String::new(), |mut acc, text| { write!(&mut acc, "{}.", text).unwrap(); acc }); - let confs_visual = DynConf::new(config.class_confs(), class_names.len()); let confs_textual = DynConf::new(config.text_confs(), class_names.len()); let processor = Processor::try_from_config(&config.processor)? diff --git a/src/models/moondream2/impl.rs b/src/models/moondream2/impl.rs index 30bab95..fd1100f 100644 --- a/src/models/moondream2/impl.rs +++ b/src/models/moondream2/impl.rs @@ -299,6 +299,7 @@ impl Moondream2 { cy * image_height as f32, )) .with_id(0) + .with_confidence(1.) .with_name(object)]); // keep? diff --git a/src/models/owl/impl.rs b/src/models/owl/impl.rs index 2295c77..1852da8 100644 --- a/src/models/owl/impl.rs +++ b/src/models/owl/impl.rs @@ -31,12 +31,12 @@ impl OWLv2 { engine.ts.clone(), ); let spec = engine.spec().to_owned(); - let names: Vec = config - .class_names() - .expect("No class names specified.") - .iter() - .map(|x| x.to_string()) - .collect(); + let names: Vec = config.text_names().to_vec(); + if names.is_empty() { + anyhow::bail!( + "No valid class names were provided in the config. Ensure the 'text_names' field is non-empty and contains valid class names." + ); + } let names_with_prompt: Vec = names.iter().map(|x| format!("a photo of {}", x)).collect(); let n = names.len(); diff --git a/src/models/picodet/impl.rs b/src/models/picodet/impl.rs index 0a731e3..1700ae1 100644 --- a/src/models/picodet/impl.rs +++ b/src/models/picodet/impl.rs @@ -28,10 +28,7 @@ impl PicoDet { engine.ts.clone(), ); let spec = engine.spec().to_owned(); - let names = config - .class_names() - .expect("No class names are specified.") - .to_vec(); + let names: Vec = config.class_names().to_vec(); let confs = DynConf::new(config.class_confs(), names.len()); let processor = Processor::try_from_config(&config.processor)? .with_image_width(width as _) @@ -94,14 +91,15 @@ impl PicoDet { return None; } let (x1, y1, x2, y2) = (pred[2], pred[3], pred[4], pred[5]); + let mut hbb = Hbb::default() + .with_xyxy(x1.max(0.0f32), y1.max(0.0f32), x2, y2) + .with_confidence(confidence) + .with_id(class_id); + if !self.names.is_empty() { + hbb = hbb.with_name(&self.names[class_id]); + } - Some( - Hbb::default() - .with_xyxy(x1.max(0.0f32), y1.max(0.0f32), x2, y2) - .with_confidence(confidence) - .with_id(class_id) - .with_name(&self.names[class_id]), - ) + Some(hbb) }) .collect(); diff --git a/src/models/pipeline/basemodel.rs b/src/models/pipeline/basemodel.rs index 3a791f0..49430a0 100644 --- a/src/models/pipeline/basemodel.rs +++ b/src/models/pipeline/basemodel.rs @@ -40,7 +40,6 @@ impl BaseModelVisual { let processor = Processor::try_from_config(&config.processor)? .with_image_width(width as _) .with_image_height(height as _); - let device = config.model.device; let task = config.task; let scale = config.scale; diff --git a/src/models/pipeline/image_classifier.rs b/src/models/pipeline/image_classifier.rs index e7a9b12..dcbfccf 100644 --- a/src/models/pipeline/image_classifier.rs +++ b/src/models/pipeline/image_classifier.rs @@ -3,7 +3,7 @@ use anyhow::Result; use ndarray::Axis; use rayon::prelude::*; -use crate::{elapsed, DynConf, Engine, Image, ModelConfig, Prob, Processor, Ts, Xs, Y}; +use crate::{elapsed, Engine, Image, ModelConfig, Prob, Processor, Ts, Xs, Y}; #[derive(Debug, Builder)] pub struct ImageClassifier { @@ -12,20 +12,24 @@ pub struct ImageClassifier { width: usize, batch: usize, apply_softmax: bool, - ts: Ts, processor: Processor, - confs: DynConf, - nc: usize, names: Vec, spec: String, + topk: usize, + ts: Ts, } impl TryFrom for ImageClassifier { type Error = anyhow::Error; fn try_from(config: ModelConfig) -> Result { - let engine = Engine::try_from_config(&config.model)?; + Self::new(config) + } +} +impl ImageClassifier { + pub fn new(config: ModelConfig) -> Result { + let engine = Engine::try_from_config(&config.model)?; let spec = engine.spec().to_string(); let (batch, height, width, ts) = ( engine.batch().opt(), @@ -33,29 +37,9 @@ impl TryFrom for ImageClassifier { engine.try_width().unwrap_or(&224.into()).opt(), engine.ts().clone(), ); - - let (nc, names) = match (config.nc(), config.class_names()) { - (Some(nc), Some(names)) => { - if nc != names.len() { - anyhow::bail!( - "The length of the input class names: {} is inconsistent with the number of classes: {}.", - names.len(), - nc - ); - } - (nc, names.to_vec()) - } - (Some(nc), None) => ( - nc, - (0..nc).map(|x| format!("# {}", x)).collect::>(), - ), - (None, Some(names)) => (names.len(), names.to_vec()), - (None, None) => { - anyhow::bail!("Neither class names nor class numbers were specified."); - } - }; - let confs = DynConf::new(config.class_confs(), nc); + let names = config.class_names.to_vec(); let apply_softmax = config.apply_softmax.unwrap_or_default(); + let topk = config.topk.unwrap_or(5); let processor = Processor::try_from_config(&config.processor)? .with_image_width(width as _) .with_image_height(height as _); @@ -65,18 +49,15 @@ impl TryFrom for ImageClassifier { height, width, batch, - nc, ts, spec, processor, - confs, names, apply_softmax, + topk, }) } -} -impl ImageClassifier { pub fn summary(&mut self) { self.ts.summary(); } @@ -114,7 +95,7 @@ impl ImageClassifier { let probs = Prob::new_probs( &logits.into_raw_vec_and_offset().0, Some(&self.names.iter().map(|x| x.as_str()).collect::>()), - 3, + self.topk, ); Some(Y::default().with_probs(&probs)) diff --git a/src/models/rfdetr/impl.rs b/src/models/rfdetr/impl.rs index 6d15e52..5293266 100644 --- a/src/models/rfdetr/impl.rs +++ b/src/models/rfdetr/impl.rs @@ -28,12 +28,7 @@ impl RFDETR { engine.ts.clone(), ); let spec = engine.spec().to_owned(); - let names: Vec = config - .class_names() - .expect("No class names specified.") - .iter() - .map(|x| x.to_string()) - .collect(); + let names: Vec = config.class_names().to_vec(); let confs = DynConf::new(config.class_confs(), names.len()); let processor = Processor::try_from_config(&config.processor)? .with_image_width(width as _) @@ -107,14 +102,15 @@ impl RFDETR { let y = cy - h / 2.; let x = x.max(0.0).min(image_width as _); let y = y.max(0.0).min(image_height as _); + let mut hbb = Hbb::default() + .with_xywh(x, y, w, h) + .with_confidence(conf) + .with_id(class_id as _); + if !self.names.is_empty() { + hbb = hbb.with_name(&self.names[class_id]); + } - Some( - Hbb::default() - .with_xywh(x, y, w, h) - .with_confidence(conf) - .with_id(class_id as _) - .with_name(&self.names[class_id]), - ) + Some(hbb) }) .collect(); diff --git a/src/models/rtdetr/impl.rs b/src/models/rtdetr/impl.rs index 53db03c..2b0675c 100644 --- a/src/models/rtdetr/impl.rs +++ b/src/models/rtdetr/impl.rs @@ -28,12 +28,7 @@ impl RTDETR { engine.ts.clone(), ); let spec = engine.spec().to_owned(); - let names: Vec = config - .class_names() - .expect("No class names specified.") - .iter() - .map(|x| x.to_string()) - .collect(); + let names: Vec = config.class_names().to_vec(); let confs = DynConf::new(config.class_confs(), names.len()); let processor = Processor::try_from_config(&config.processor)? .with_image_width(width as _) @@ -94,7 +89,6 @@ impl RTDETR { if score < self.confs[class_id] { continue; } - let xyxy = boxes.slice(s![i, ..]); let (x1, y1, x2, y2) = ( xyxy[0] / ratio, @@ -102,13 +96,14 @@ impl RTDETR { xyxy[2] / ratio, xyxy[3] / ratio, ); - y_bboxes.push( - Hbb::default() - .with_xyxy(x1.max(0.0f32), y1.max(0.0f32), x2, y2) - .with_confidence(score) - .with_id(class_id) - .with_name(&self.names[class_id]), - ); + let mut hbb = Hbb::default() + .with_xyxy(x1.max(0.0f32), y1.max(0.0f32), x2, y2) + .with_confidence(score) + .with_id(class_id); + if !self.names.is_empty() { + hbb = hbb.with_name(&self.names[class_id]); + } + y_bboxes.push(hbb); } let mut y = Y::default(); diff --git a/src/models/rtmo/impl.rs b/src/models/rtmo/impl.rs index 0b42d30..de5227a 100644 --- a/src/models/rtmo/impl.rs +++ b/src/models/rtmo/impl.rs @@ -27,7 +27,6 @@ impl RTMO { engine.try_width().unwrap_or(&512.into()).opt(), engine.ts().clone(), ); - let nk = config.nk().unwrap_or(17); let confs = DynConf::new(config.class_confs(), 1); let kconfs = DynConf::new(config.keypoint_confs(), nk); diff --git a/src/models/sam2/impl.rs b/src/models/sam2/impl.rs index 9f576dc..21c9412 100644 --- a/src/models/sam2/impl.rs +++ b/src/models/sam2/impl.rs @@ -30,7 +30,6 @@ impl SAM2 { ); let ts = Ts::merge(&[encoder.ts(), decoder.ts()]); let spec = encoder.spec().to_owned(); - let conf = DynConf::new(config.class_confs(), 1); let processor = Processor::try_from_config(&config.processor)? .with_image_width(width as _) diff --git a/src/models/sapiens/impl.rs b/src/models/sapiens/impl.rs index a192bd5..a50cd58 100644 --- a/src/models/sapiens/impl.rs +++ b/src/models/sapiens/impl.rs @@ -11,7 +11,7 @@ pub struct Sapiens { width: usize, batch: usize, task: Task, - names_body: Option>, + names_body: Vec, ts: Ts, processor: Processor, spec: String, @@ -27,7 +27,6 @@ impl Sapiens { engine.try_width().unwrap_or(&768.into()).opt(), engine.ts().clone(), ); - let task = config.task.expect("No sapiens task specified."); let names_body = config.class_names; let processor = Processor::try_from_config(&config.processor)? @@ -124,8 +123,8 @@ impl Sapiens { if let Some(polygon) = mask.polygon() { y_polygons.push(polygon); } - if let Some(names_body) = &self.names_body { - mask = mask.with_name(&names_body[*i]); + if !self.names_body.is_empty() { + mask = mask.with_name(&self.names_body[*i]); } y_masks.push(mask); } diff --git a/src/models/smolvlm/config.rs b/src/models/smolvlm/config.rs index 339f115..6a41fe9 100644 --- a/src/models/smolvlm/config.rs +++ b/src/models/smolvlm/config.rs @@ -15,7 +15,7 @@ impl crate::ModelConfig { .with_scale(crate::Scale::Million(256.)) .with_visual_file("256m-vision-encoder.onnx") .with_textual_file("256m-embed-tokens.onnx") - .with_textual_decoder_file("256m-decoder-model-merged.onnx") + .with_textual_decoder_merged_file("256m-decoder-model-merged.onnx") } pub fn smolvlm_500m() -> Self { @@ -23,6 +23,6 @@ impl crate::ModelConfig { .with_scale(crate::Scale::Million(500.)) .with_visual_file("500m-vision-encoder.onnx") .with_textual_file("500m-embed-tokens.onnx") - .with_textual_decoder_file("500m-decoder-model-merged.onnx") + .with_textual_decoder_merged_file("500m-decoder-model-merged.onnx") } } diff --git a/src/models/smolvlm/impl.rs b/src/models/smolvlm/impl.rs index 48cf3cc..3039a0b 100644 --- a/src/models/smolvlm/impl.rs +++ b/src/models/smolvlm/impl.rs @@ -36,7 +36,6 @@ impl SmolVLM { let vision = Engine::try_from_config(&config.visual)?; let text_embed = Engine::try_from_config(&config.textual)?; let decoder = Engine::try_from_config(&config.textual_decoder_merged)?; - let fake_image_token = "".to_string(); let image_token = "".to_string(); let global_img_token = "".to_string(); @@ -52,7 +51,6 @@ impl SmolVLM { _ => unimplemented!(), }; let scale = config.scale.clone().unwrap(); - let (batch, num_patch, height, width, ts) = ( vision.batch().opt(), vision.inputs_minoptmax()[0][1].opt(), diff --git a/src/models/trocr/impl.rs b/src/models/trocr/impl.rs index e7a981e..4a27fef 100644 --- a/src/models/trocr/impl.rs +++ b/src/models/trocr/impl.rs @@ -65,7 +65,6 @@ impl TrOCR { Some(Scale::B) => 12, _ => unimplemented!(), }; - let processor = Processor::try_from_config(&config.processor)? .with_image_width(width as _) .with_image_height(height as _); diff --git a/src/models/yolo/config.rs b/src/models/yolo/config.rs index 7941d03..6fe6078 100644 --- a/src/models/yolo/config.rs +++ b/src/models/yolo/config.rs @@ -1,6 +1,7 @@ use crate::{ models::YOLOPredsFormat, ModelConfig, ResizeMode, Scale, Task, NAMES_COCO_80, - NAMES_COCO_KEYPOINTS_17, NAMES_IMAGENET_1K, NAMES_YOLO_DOCLAYOUT_10, + NAMES_COCO_KEYPOINTS_17, NAMES_DOTA_V1_15, NAMES_IMAGENET_1K, NAMES_YOLOE_4585, + NAMES_YOLO_DOCLAYOUT_10, }; impl ModelConfig { @@ -13,7 +14,6 @@ impl ModelConfig { .with_model_ixx(0, 3, 640.into()) .with_resize_mode(ResizeMode::FitAdaptive) .with_resize_filter("CatmullRom") - .with_class_names(&NAMES_COCO_80) } pub fn yolo_classify() -> Self { @@ -27,7 +27,9 @@ impl ModelConfig { } pub fn yolo_detect() -> Self { - Self::yolo().with_task(Task::ObjectDetection) + Self::yolo() + .with_task(Task::ObjectDetection) + .with_class_names(&NAMES_COCO_80) } pub fn yolo_pose() -> Self { @@ -37,31 +39,17 @@ impl ModelConfig { } pub fn yolo_segment() -> Self { - Self::yolo().with_task(Task::InstanceSegmentation) + Self::yolo() + .with_task(Task::InstanceSegmentation) + .with_class_names(&NAMES_COCO_80) } pub fn yolo_obb() -> Self { - Self::yolo().with_task(Task::OrientedObjectDetection) - } - - pub fn auto_yolo_model_file(mut self) -> Self { - if self.model.file.is_empty() { - // [version]-[scale]-[task] - let mut y = String::new(); - if let Some(x) = self.version() { - y.push_str(&x.to_string()); - } - if let Some(x) = self.scale() { - y.push_str(&format!("-{}", x)); - } - if let Some(x) = self.task() { - y.push_str(&format!("-{}", x.yolo_str())); - } - y.push_str(".onnx"); - self.model.file = y; - } - - self + Self::yolo() + .with_model_ixx(0, 2, 1024.into()) + .with_model_ixx(0, 3, 1024.into()) + .with_task(Task::OrientedObjectDetection) + .with_class_names(&NAMES_DOTA_V1_15) } pub fn doclayout_yolo_docstructbench() -> Self { @@ -75,60 +63,80 @@ impl ModelConfig { } // YOLOE models + pub fn yoloe() -> Self { + Self::yolo() + .with_task(Task::InstanceSegmentation) + .with_class_names(&NAMES_YOLOE_4585) + } pub fn yoloe_v8s_seg_pf() -> Self { - Self::yolo_segment() + Self::yoloe() .with_version(8.into()) .with_scale(Scale::S) .with_model_file("yoloe-v8s-seg-pf.onnx") } pub fn yoloe_v8m_seg_pf() -> Self { - Self::yolo_segment() + Self::yoloe() .with_version(8.into()) .with_scale(Scale::M) .with_model_file("yoloe-v8m-seg-pf.onnx") } pub fn yoloe_v8l_seg_pf() -> Self { - Self::yolo_segment() + Self::yoloe() .with_version(8.into()) .with_scale(Scale::L) .with_model_file("yoloe-v8l-seg-pf.onnx") } pub fn yoloe_11s_seg_pf() -> Self { - Self::yolo_segment() + Self::yoloe() .with_version(11.into()) .with_scale(Scale::S) .with_model_file("yoloe-11s-seg-pf.onnx") } pub fn yoloe_11m_seg_pf() -> Self { - Self::yolo_segment() + Self::yoloe() .with_version(11.into()) .with_scale(Scale::M) .with_model_file("yoloe-v8m-seg-pf.onnx") } pub fn yoloe_11l_seg_pf() -> Self { - Self::yolo_segment() + Self::yoloe() .with_version(11.into()) .with_scale(Scale::L) .with_model_file("yoloe-11l-seg-pf.onnx") } - /// ---- TODO pub fn fastsam_s() -> Self { Self::yolo_segment() + .with_class_names(&["object"]) .with_scale(Scale::S) .with_version(8.into()) .with_model_file("FastSAM-s.onnx") } - pub fn yolo_v8_rtdetr_l() -> Self { + pub fn fastsam_x() -> Self { + Self::yolo_segment() + .with_class_names(&["object"]) + .with_scale(Scale::X) + .with_version(8.into()) + .with_model_file("FastSAM-x.onnx") + } + + pub fn ultralytics_rtdetr_l() -> Self { Self::yolo_detect() .with_yolo_preds_format(YOLOPredsFormat::n_a_cxcywh_clss_n()) .with_scale(Scale::L) - .with_model_file("rtdetr-l-det.onnx") + .with_model_file("rtdetr-l.onnx") + } + + pub fn ultralytics_rtdetr_x() -> Self { + Self::yolo_detect() + .with_yolo_preds_format(YOLOPredsFormat::n_a_cxcywh_clss_n()) + .with_scale(Scale::X) + .with_model_file("rtdetr-x.onnx") } } diff --git a/src/models/yolo/impl.rs b/src/models/yolo/impl.rs index 7bf550d..ac05d38 100644 --- a/src/models/yolo/impl.rs +++ b/src/models/yolo/impl.rs @@ -28,12 +28,12 @@ pub struct YOLO { confs: DynConf, kconfs: DynConf, iou: f32, + topk: usize, processor: Processor, ts: Ts, spec: String, classes_excluded: Vec, classes_retained: Vec, - topk: usize, } impl TryFrom for YOLO { @@ -47,7 +47,6 @@ impl TryFrom for YOLO { impl YOLO { pub fn new(config: ModelConfig) -> Result { let engine = Engine::try_from_config(&config.model)?; - let (batch, height, width, ts, spec) = ( engine.batch().opt(), engine.try_height().unwrap_or(&640.into()).opt(), @@ -55,7 +54,6 @@ impl YOLO { engine.ts.clone(), engine.spec().to_owned(), ); - let task: Option = match &config.task { Some(task) => Some(task.clone()), None => match engine.try_fetch("task") { @@ -128,9 +126,10 @@ impl YOLO { (Task::InstanceSegmentation, Version(5, 0, _)) => { YOLOPredsFormat::n_a_cxcywh_confclss_coefs() } - (Task::InstanceSegmentation, Version(8, 0, _) | Version(11, 0, _)) => { - YOLOPredsFormat::n_cxcywh_clss_coefs_a() - } + ( + Task::InstanceSegmentation, + Version(8, 0, _) | Version(9, 0, _) | Version(11, 0, _), + ) => YOLOPredsFormat::n_cxcywh_clss_coefs_a(), (Task::OrientedObjectDetection, Version(8, 0, _) | Version(11, 0, _)) => { YOLOPredsFormat::n_cxcywh_clss_r_a() } @@ -169,61 +168,69 @@ impl YOLO { }; // Class names - let names: Option> = match Self::fetch_names_from_onnx(&engine) { - Some(names_parsed) => match &config.class_names { - Some(names) => { - if names.len() == names_parsed.len() { - // prioritize user-defined - Some(names.clone()) - } else { - // Fail to override - anyhow::bail!( - "The lengths of parsed class names: {} and user-defined class names: {} do not match.", - names_parsed.len(), - names.len(), - ) - } + let names_parsed = Self::fetch_names_from_onnx(&engine); + let names_customized = config.class_names.to_vec(); + let names: Vec<_> = match (names_parsed, names_customized.is_empty()) { + (None, true) => vec![], + (None, false) => names_customized, + (Some(names_parsed), true) => names_parsed, + (Some(names_parsed), false) => { + if names_parsed.len() == names_customized.len() { + names_customized // prioritize user-defined + } else { + anyhow::bail!( + "The lengths of parsed class names: {} and user-defined class names: {} do not match.", + names_parsed.len(), + names_customized.len(), + ); } - None => Some(names_parsed), - }, - None => config.class_names.clone(), - }; - - // Class names & Number of class - let (nc, names) = match (config.nc(), names) { - (_, Some(names)) => (names.len(), names.to_vec()), - (Some(nc), None) => (nc, Self::n2s(nc)), - (None, None) => { - anyhow::bail!( - "Neither class names nor the number of classes were specified. \ - \nConsider specify them with `ModelConfig::default().with_nc()` or `ModelConfig::default().with_class_names()`" - ); } }; + // Class names & Number of class + let nc = match config.nc() { + None => names.len(), + Some(n) => { + if names.len() != n { + anyhow::bail!( + "The lengths of class names: {} and user-defined num_classes: {} do not match.", + names.len(), + n, + ) + } + n + } + }; + if nc == 0 && names.is_empty() { + anyhow::bail!( + "Neither class names nor the number of classes were specified. \ + \nConsider specify them with `ModelConfig::default().with_nc()` or `ModelConfig::default().with_class_names()`" + ); + } + // Keypoint names & Number of keypoints - let (nk, names_kpt) = if let Task::KeypointsDetection = task { - let nk = Self::fetch_nk_from_onnx(&engine).or(config.nk()); - match (&config.keypoint_names, nk) { - (Some(names), Some(nk)) => { - if names.len() != nk { + let names_kpt = config.keypoint_names.to_vec(); + let nk = if let Task::KeypointsDetection = task { + match (names_kpt.is_empty(), Self::fetch_nk_from_onnx(&engine).or(config.nk())) { + (false, Some(nk)) => { + if names_kpt.len() != nk { anyhow::bail!( - "The lengths of user-defined keypoint names: {} and nk parsed: {} do not match.", - names.len(), + "The lengths of user-defined keypoint class names: {} and num_keypoints: {} do not match.", + names_kpt.len(), nk, ); } - (nk, names.clone()) - } - (Some(names), None) => (names.len(), names.clone()), - (None, Some(nk)) => (nk, Self::n2s(nk)), - (None, None) => anyhow::bail!( + nk + }, + (false, None) => names_kpt.len(), + (true, Some(nk)) => nk, + (true, None) => anyhow::bail!( "Neither keypoint names nor the number of keypoints were specified when doing `KeypointsDetection` task. \ \nConsider specify them with `ModelConfig::default().with_nk()` or `ModelConfig::default().with_keypoint_names()`" ), } } else { - (0, vec![]) + 0 }; // Attributes @@ -295,12 +302,8 @@ impl YOLO { Ok(ys) } - pub fn summary(&mut self) { - self.ts.summary(); - } - fn postprocess(&self, xs: Xs) -> Result> { - let protos = if xs.len() == 2 { Some(&xs[1]) } else { None }; + // let protos = if xs.len() == 2 { Some(&xs[1]) } else { None }; let ys: Vec = xs[0] .axis_iter(Axis(0)) .into_par_iter() @@ -345,11 +348,11 @@ impl YOLO { let ratio = self.processor.images_transform_info[idx].height_scale; // Other tasks - let (y_bboxes, y_mbrs) = slice_bboxes? + let (y_hbbs, y_obbs) = slice_bboxes? .axis_iter(Axis(0)) .into_par_iter() .enumerate() - .filter_map(|(i, bbox)| { + .filter_map(|(i, hbb)| { // confidence & class_id let (class_id, confidence) = match &slice_id { Some(ids) => (ids[[i, 0]] as _, slice_clss[[i, 0]] as _), @@ -389,50 +392,50 @@ impl YOLO { } // Bboxes - let bbox = bbox.mapv(|x| x / ratio); - let bbox = if self.layout.is_bbox_normalized { + let hbb = hbb.mapv(|x| x / ratio); + let hbb = if self.layout.is_bbox_normalized { ( - bbox[0] * self.width() as f32, - bbox[1] * self.height() as f32, - bbox[2] * self.width() as f32, - bbox[3] * self.height() as f32, + hbb[0] * self.width() as f32, + hbb[1] * self.height() as f32, + hbb[2] * self.width() as f32, + hbb[3] * self.height() as f32, ) } else { - (bbox[0], bbox[1], bbox[2], bbox[3]) + (hbb[0], hbb[1], hbb[2], hbb[3]) }; let (cx, cy, x, y, w, h) = match self.layout.box_type()? { BoxType::Cxcywh => { - let (cx, cy, w, h) = bbox; + let (cx, cy, w, h) = hbb; let x = (cx - w / 2.).max(0.); let y = (cy - h / 2.).max(0.); (cx, cy, x, y, w, h) } BoxType::Xyxy => { - let (x, y, x2, y2) = bbox; + let (x, y, x2, y2) = hbb; let (w, h) = (x2 - x, y2 - y); let (cx, cy) = ((x + x2) / 2., (y + y2) / 2.); (cx, cy, x, y, w, h) } BoxType::Xywh => { - let (x, y, w, h) = bbox; + let (x, y, w, h) = hbb; let (cx, cy) = (x + w / 2., y + h / 2.); (cx, cy, x, y, w, h) } BoxType::Cxcyxy => { - let (cx, cy, x2, y2) = bbox; + let (cx, cy, x2, y2) = hbb; let (w, h) = ((x2 - cx) * 2., (y2 - cy) * 2.); let x = (x2 - w).max(0.); let y = (y2 - h).max(0.); (cx, cy, x, y, w, h) } BoxType::XyCxcy => { - let (x, y, cx, cy) = bbox; + let (x, y, cx, cy) = hbb; let (w, h) = ((cx - x) * 2., (cy - y) * 2.); (cx, cy, x, y, w, h) } }; - let (y_bbox, y_mbr) = match &slice_radians { + let (y_hbb, y_obb) = match &slice_radians { Some(slice_radians) => { let radians = slice_radians[[i, 0]]; let (w, h, radians) = if w > h { @@ -441,47 +444,51 @@ impl YOLO { (h, w, radians + std::f32::consts::PI / 2.) }; let radians = radians % std::f32::consts::PI; - let mbr = Obb::from_cxcywhr(cx, cy, w, h, radians) + let mut obb = Obb::from_cxcywhr(cx, cy, w, h, radians) .with_confidence(confidence) - .with_id(class_id) - .with_name(&self.names[class_id]); + .with_id(class_id); + if !self.names.is_empty() { + obb = obb.with_name(&self.names[class_id]); + } - (None, Some(mbr)) + (None, Some(obb)) } None => { - let bbox = Hbb::default() + let mut hbb = Hbb::default() .with_xywh(x, y, w, h) .with_confidence(confidence) .with_id(class_id) - .with_uid(i) - .with_name(&self.names[class_id]); + .with_uid(i); + if !self.names.is_empty() { + hbb = hbb.with_name(&self.names[class_id]); + } - (Some(bbox), None) + (Some(hbb), None) } }; - Some((y_bbox, y_mbr)) + Some((y_hbb, y_obb)) }) .collect::<(Vec<_>, Vec<_>)>(); - let mut y_bboxes: Vec = y_bboxes.into_iter().flatten().collect(); - let mut y_mbrs: Vec = y_mbrs.into_iter().flatten().collect(); + let mut y_hbbs: Vec = y_hbbs.into_iter().flatten().collect(); + let mut y_obbs: Vec = y_obbs.into_iter().flatten().collect(); // Mbrs - if !y_mbrs.is_empty() { + if !y_obbs.is_empty() { if self.layout.apply_nms { - y_mbrs.apply_nms_inplace(self.iou); + y_obbs.apply_nms_inplace(self.iou); } - y = y.with_obbs(&y_mbrs); + y = y.with_obbs(&y_obbs); return Some(y); } // Bboxes - if !y_bboxes.is_empty() { + if !y_hbbs.is_empty() { if self.layout.apply_nms { - y_bboxes.apply_nms_inplace(self.iou); + y_hbbs.apply_nms_inplace(self.iou); } - y = y.with_hbbs(&y_bboxes); + y = y.with_hbbs(&y_hbbs); } // KeypointsDetection @@ -490,8 +497,8 @@ impl YOLO { if let Some(hbbs) = y.hbbs() { let y_kpts = hbbs .into_par_iter() - .filter_map(|bbox| { - let pred = pred_kpts.slice(s![bbox.uid(), ..]); + .filter_map(|hbb| { + let pred = pred_kpts.slice(s![hbb.uid(), ..]); let kpts = (0..self.nk) .into_par_iter() .map(|i| { @@ -501,14 +508,17 @@ impl YOLO { if kconf < self.kconfs[i] { Keypoint::default() } else { - Keypoint::default() + let mut kpt = Keypoint::default() .with_id(i) .with_confidence(kconf) .with_xy( kx.max(0.0f32).min(image_width as f32), ky.max(0.0f32).min(image_height as f32), - ) - .with_name(&self.names_kpt[i]) + ); + if !self.names_kpt.is_empty() { + kpt = kpt.with_name(&self.names_kpt[i]); + } + kpt } }) .collect::>(); @@ -522,11 +532,12 @@ impl YOLO { // InstanceSegmentation if let Some(coefs) = slice_coefs { if let Some(hbbs) = y.hbbs() { + let protos = &xs[1]; let y_masks = hbbs .into_par_iter() - .filter_map(|bbox| { - let coefs = coefs.slice(s![bbox.uid(), ..]).to_vec(); - let proto = protos.as_ref()?.slice(s![idx, .., .., ..]); + .filter_map(|hbb| { + let coefs = coefs.slice(s![hbb.uid(), ..]).to_vec(); + let proto = protos.slice(s![idx, .., .., ..]); let (nm, mh, mw) = proto.dim(); // coefs * proto => mask @@ -553,9 +564,9 @@ impl YOLO { mask, )?; let (xmin, ymin, xmax, ymax) = - (bbox.xmin(), bbox.ymin(), bbox.xmax(), bbox.ymax()); + (hbb.xmin(), hbb.ymin(), hbb.xmax(), hbb.ymax()); - // Using bbox to crop the mask + // Using hbb to crop the mask for (y, row) in mask.enumerate_rows_mut() { for (x, _, pixel) in row { if x < xmin as _ @@ -569,10 +580,10 @@ impl YOLO { } let mut mask = Mask::default().with_mask(mask); - if let Some(id) = bbox.id() { + if let Some(id) = hbb.id() { mask = mask.with_id(id); } - if let Some(name) = bbox.name() { + if let Some(name) = hbb.name() { mask = mask.with_name(name); } @@ -613,7 +624,7 @@ impl YOLO { .and_then(|m| m.as_str().parse::().ok()) } - fn n2s(n: usize) -> Vec { - (0..n).map(|x| format!("# {}", x)).collect::>() + pub fn summary(&mut self) { + self.ts.summary(); } } diff --git a/src/models/yolop/impl.rs b/src/models/yolop/impl.rs index b9a5c3f..717078f 100644 --- a/src/models/yolop/impl.rs +++ b/src/models/yolop/impl.rs @@ -29,7 +29,6 @@ impl YOLOPv2 { engine.try_width().unwrap_or(&512.into()).opt(), engine.ts().clone(), ); - let confs = DynConf::new(config.class_confs(), 80); let iou = config.iou.unwrap_or(0.45f32); let processor = Processor::try_from_config(&config.processor)? diff --git a/src/utils/dynconf.rs b/src/utils/dynconf.rs index fa715d2..1ec0cff 100644 --- a/src/utils/dynconf.rs +++ b/src/utils/dynconf.rs @@ -6,7 +6,13 @@ pub struct DynConf(Vec); impl Default for DynConf { fn default() -> Self { - Self(vec![0.4f32]) + Self(vec![0.3f32]) + } +} + +impl From for DynConf { + fn from(conf: f32) -> Self { + Self(vec![conf]) } } diff --git a/src/utils/names.rs b/src/utils/names.rs index 644973e..e4affef 100644 --- a/src/utils/names.rs +++ b/src/utils/names.rs @@ -1,3 +1,4627 @@ +pub static NAMES_YOLOE_4585: [&str; 4585] = [ + "3D CG rendering", + "3D glasses", + "abacus", + "abalone", + "monastery", + "belly", + "academy", + "accessory", + "accident", + "accordion", + "acorn", + "acrylic paint", + "act", + "action", + "action film", + "activity", + "actor", + "adaptation", + "add", + "adhesive tape", + "adjust", + "adult", + "adventure", + "advertisement", + "antenna", + "aerobics", + "spray can", + "afro", + "agriculture", + "aid", + "air conditioner", + "air conditioning", + "air sock", + "aircraft cabin", + "aircraft model", + "air field", + "air line", + "airliner", + "airman", + "plane", + "airplane window", + "airport", + "airport runway", + "airport terminal", + "airship", + "airshow", + "aisle", + "alarm", + "alarm clock", + "mollymawk", + "album", + "album cover", + "alcohol", + "alcove", + "algae", + "alley", + "almond", + "aloe vera", + "alp", + "alpaca", + "alphabet", + "german shepherd", + "altar", + "amber", + "ambulance", + "bald eagle", + "American shorthair", + "amethyst", + "amphitheater", + "amplifier", + "amusement park", + "amusement ride", + "anchor", + "ancient", + "anemone", + "angel", + "angle", + "animal", + "animal sculpture", + "animal shelter", + "animation", + "animation film", + "animator", + "anime", + "ankle", + "anklet", + "anniversary", + "trench coat", + "ant", + "antelope", + "antique", + "antler", + "anvil", + "apartment", + "ape", + "app", + "app icon", + "appear", + "appearance", + "appetizer", + "applause", + "apple", + "apple juice", + "apple pie", + "apple tree", + "applesauce", + "appliance", + "appointment", + "approach", + "apricot", + "apron", + "aqua", + "aquarium", + "aquarium fish", + "aqueduct", + "arcade", + "arcade machine", + "arch", + "arch bridge", + "archaelogical excavation", + "archery", + "archipelago", + "architect", + "architecture", + "archive", + "archway", + "area", + "arena", + "argument", + "arm", + "armadillo", + "armband", + "armchair", + "armoire", + "armor", + "army", + "army base", + "army tank", + "array", + "arrest", + "arrow", + "art", + "art exhibition", + "art gallery", + "art print", + "art school", + "art studio", + "art vector illustration", + "artichoke", + "article", + "artifact", + "artist", + "artists loft", + "ash", + "ashtray", + "asia temple", + "asparagus", + "asphalt road", + "assemble", + "assembly", + "assembly line", + "association", + "astronaut", + "astronomer", + "athlete", + "athletic", + "atlas", + "atm", + "atmosphere", + "atrium", + "attach", + "fighter jet", + "attend", + "attraction", + "atv", + "eggplant", + "auction", + "audi", + "audio", + "auditorium", + "aurora", + "author", + "auto factory", + "auto mechanic", + "auto part", + "auto show", + "auto showroom", + "car battery", + "automobile make", + "automobile model", + "motor vehicle", + "autumn", + "autumn forest", + "autumn leave", + "autumn park", + "autumn tree", + "avatar", + "avenue", + "aviator sunglasses", + "avocado", + "award", + "award ceremony", + "award winner", + "shed", + "ax", + "azalea", + "baboon", + "baby", + "baby bottle", + "baby carriage", + "baby clothe", + "baby elephant", + "baby food", + "baby seat", + "baby shower", + "back", + "backdrop", + "backlight", + "backpack", + "backyard", + "bacon", + "badge", + "badger", + "badlands", + "badminton", + "badminton racket", + "bag", + "bagel", + "bagpipe", + "baguette", + "bait", + "baked goods", + "baker", + "bakery", + "baking", + "baking sheet", + "balance", + "balance car", + "balcony", + "ball", + "ball pit", + "ballerina", + "ballet", + "ballet dancer", + "ballet skirt", + "balloon", + "balloon arch", + "baseball player", + "ballroom", + "bamboo", + "bamboo forest", + "banana", + "banana bread", + "banana leaf", + "banana tree", + "band", + "band aid", + "bandage", + "headscarf", + "bandeau", + "bangs", + "bracelet", + "balustrade", + "banjo", + "bank", + "bank card", + "bank vault", + "banknote", + "banner", + "banquet", + "banquet hall", + "banyan tree", + "baozi", + "baptism", + "bar", + "bar code", + "bar stool", + "barbecue", + "barbecue grill", + "barbell", + "barber", + "barber shop", + "barbie", + "barge", + "barista", + "bark", + "barley", + "barn", + "barn owl", + "barn door", + "barrel", + "barricade", + "barrier", + "handcart", + "bartender", + "baseball", + "baseball base", + "baseball bat", + "baseball hat", + "baseball stadium", + "baseball game", + "baseball glove", + "baseball pitcher", + "baseball team", + "baseball uniform", + "basement", + "basil", + "basin", + "basket", + "basket container", + "basketball", + "basketball backboard", + "basketball coach", + "basketball court", + "basketball game", + "basketball hoop", + "basketball player", + "basketball stadium", + "basketball team", + "bass", + "bass guitar", + "bass horn", + "bassist", + "bat", + "bath", + "bath heater", + "bath mat", + "bath towel", + "swimwear", + "bathrobe", + "bathroom", + "bathroom accessory", + "bathroom cabinet", + "bathroom door", + "bathroom mirror", + "bathroom sink", + "toilet paper", + "bathroom window", + "batman", + "wand", + "batter", + "battery", + "battle", + "battle rope", + "battleship", + "bay", + "bay bridge", + "bay window", + "bayberry", + "bazaar", + "beach", + "beach ball", + "beach chair", + "beach house", + "beach hut", + "beach towel", + "beach volleyball", + "lighthouse", + "bead", + "beagle", + "beak", + "beaker", + "beam", + "bean", + "bean bag chair", + "beanbag", + "bear", + "bear cub", + "beard", + "beast", + "beat", + "beautiful", + "beauty", + "beauty salon", + "beaver", + "bed", + "bedcover", + "bed frame", + "bedroom", + "bedding", + "bedpan", + "bedroom window", + "bedside lamp", + "bee", + "beech tree", + "beef", + "beekeeper", + "beeper", + "beer", + "beer bottle", + "beer can", + "beer garden", + "beer glass", + "beer hall", + "beet", + "beetle", + "beige", + "clock", + "bell pepper", + "bell tower", + "belt", + "belt buckle", + "bench", + "bend", + "bengal tiger", + "bento", + "beret", + "berry", + "berth", + "beverage", + "bib", + "bibimbap", + "bible", + "bichon", + "bicycle", + "bicycle helmet", + "bicycle wheel", + "biker", + "bidet", + "big ben", + "bike lane", + "bike path", + "bike racing", + "bike ride", + "bikini", + "bikini top", + "bill", + "billard", + "billboard", + "billiard table", + "bin", + "binder", + "binocular", + "biology laboratory", + "biplane", + "birch", + "birch tree", + "bird", + "bird bath", + "bird feeder", + "bird house", + "bird nest", + "birdbath", + "bird cage", + "birth", + "birthday", + "birthday cake", + "birthday candle", + "birthday card", + "birthday party", + "biscuit", + "bishop", + "bison", + "bit", + "bite", + "black", + "black sheep", + "blackberry", + "blackbird", + "blackboard", + "blacksmith", + "blade", + "blanket", + "sports coat", + "bleacher", + "blender", + "blessing", + "blind", + "eye mask", + "flasher", + "snowstorm", + "block", + "blog", + "blood", + "bloom", + "blossom", + "blouse", + "blow", + "hair drier", + "blowfish", + "blue", + "blue artist", + "blue jay", + "blue sky", + "blueberry", + "bluebird", + "pig", + "board", + "board eraser", + "board game", + "boardwalk", + "boat", + "boat deck", + "boat house", + "paddle", + "boat ride", + "bobfloat", + "bobcat", + "body", + "bodyboard", + "bodybuilder", + "boiled egg", + "boiler", + "bolo tie", + "bolt", + "bomb", + "bomber", + "bonasa umbellu", + "bone", + "bonfire", + "bonnet", + "bonsai", + "book", + "book cover", + "bookcase", + "folder", + "bookmark", + "bookshelf", + "bookstore", + "boom microphone", + "boost", + "boot", + "border", + "Border collie", + "botanical garden", + "bottle", + "bottle cap", + "bottle opener", + "bottle screw", + "bougainvillea", + "boulder", + "bouquet", + "boutique", + "boutique hotel", + "bow", + "bow tie", + "bow window", + "bowl", + "bowling", + "bowling alley", + "bowling ball", + "bowling equipment", + "box", + "box girder bridge", + "box turtle", + "boxer", + "underdrawers", + "boxing", + "boxing glove", + "boxing ring", + "boy", + "brace", + "bracket", + "braid", + "brain", + "brake", + "brake light", + "branch", + "brand", + "brandy", + "brass", + "brass plaque", + "bread", + "breadbox", + "break", + "breakfast", + "seawall", + "chest", + "brewery", + "brick", + "brick building", + "wall", + "brickwork", + "wedding dress", + "bride", + "groom", + "bridesmaid", + "bridge", + "bridle", + "briefcase", + "bright", + "brim", + "broach", + "broadcasting", + "broccoli", + "bronze", + "bronze medal", + "bronze sculpture", + "bronze statue", + "brooch", + "creek", + "broom", + "broth", + "brown", + "brown bear", + "brownie", + "brunch", + "brunette", + "brush", + "coyote", + "brussels sprout", + "bubble", + "bubble gum", + "bubble tea", + "bucket cabinet", + "shield", + "bud", + "buddha", + "buffalo", + "buffet", + "bug", + "build", + "builder", + "building", + "building block", + "building facade", + "building material", + "lamp", + "bull", + "bulldog", + "bullet", + "bullet train", + "bulletin board", + "bulletproof vest", + "bullfighting", + "megaphone", + "bullring", + "bumblebee", + "bumper", + "roll", + "bundle", + "bungee", + "bunk bed", + "bunker", + "bunny", + "buoy", + "bureau", + "burial chamber", + "burn", + "burrito", + "bus", + "bus driver", + "bus interior", + "bus station", + "bus stop", + "bus window", + "bush", + "business", + "business card", + "business executive", + "business suit", + "business team", + "business woman", + "businessman", + "bust", + "butcher", + "butchers shop", + "butte", + "butter", + "cream", + "butterfly", + "butterfly house", + "button", + "buttonwood", + "buy", + "taxi", + "cabana", + "cabbage", + "cabin", + "cabin car", + "cabinet", + "cabinetry", + "cable", + "cable car", + "cactus", + "cafe", + "canteen", + "cage", + "cake", + "cake stand", + "calculator", + "caldron", + "calendar", + "calf", + "call", + "phone box", + "calligraphy", + "calm", + "camcorder", + "camel", + "camera", + "camera lens", + "camouflage", + "camp", + "camper", + "campfire", + "camping", + "campsite", + "campus", + "can", + "can opener", + "canal", + "canary", + "cancer", + "candle", + "candle holder", + "candy", + "candy bar", + "candy cane", + "candy store", + "cane", + "jar", + "cannon", + "canopy", + "canopy bed", + "cantaloupe", + "cantilever bridge", + "canvas", + "canyon", + "cap", + "cape", + "cape cod", + "cappuccino", + "capsule", + "captain", + "capture", + "car", + "car dealership", + "car door", + "car interior", + "car logo", + "car mirror", + "parking lot", + "car seat", + "car show", + "car wash", + "car window", + "caramel", + "card", + "card game", + "cardboard", + "cardboard box", + "cardigan", + "cardinal", + "cargo", + "cargo aircraft", + "cargo ship", + "caribbean", + "carnation", + "carnival", + "carnivore", + "carousel", + "carp", + "carpenter", + "carpet", + "slipper", + "house finch", + "coach", + "dalmatian", + "aircraft carrier", + "carrot", + "carrot cake", + "carry", + "cart", + "carton", + "cartoon", + "cartoon character", + "cartoon illustration", + "cartoon style", + "carve", + "case", + "cash", + "cashew", + "casino", + "casserole", + "cassette", + "cassette deck", + "plaster bandage", + "casting", + "castle", + "cat", + "cat bed", + "cat food", + "cat furniture", + "cat tree", + "catacomb", + "catamaran", + "catamount", + "catch", + "catcher", + "caterpillar", + "catfish", + "cathedral", + "cattle", + "catwalk", + "catwalk show", + "cauliflower", + "cave", + "caviar", + "CD", + "CD player", + "cedar", + "ceiling", + "ceiling fan", + "celebrate", + "celebration", + "celebrity", + "celery", + "cello", + "smartphone", + "cement", + "graveyard", + "centerpiece", + "centipede", + "ceramic", + "ceramic tile", + "cereal", + "ceremony", + "certificate", + "chain", + "chain saw", + "chair", + "chairlift", + "daybed", + "chalet", + "chalice", + "chalk", + "chamber", + "chameleon", + "champagne", + "champagne flute", + "champion", + "championship", + "chandelier", + "changing table", + "channel", + "chap", + "chapel", + "character sculpture", + "charcoal", + "charge", + "charger", + "chariot", + "charity", + "charity event", + "charm", + "graph", + "chase", + "chassis", + "check", + "checkbook", + "chessboard", + "checklist", + "cheer", + "cheerlead", + "cheese", + "cheeseburger", + "cheesecake", + "cheetah", + "chef", + "chemical compound", + "chemist", + "chemistry", + "chemistry lab", + "cheongsam", + "cherry", + "cherry blossom", + "cherry tomato", + "cherry tree", + "chess", + "chestnut", + "chicken", + "chicken breast", + "chicken coop", + "chicken salad", + "chicken wing", + "garbanzo", + "chiffonier", + "chihuahua", + "child", + "child actor", + "childs room", + "chile", + "chili dog", + "chimney", + "chimpanzee", + "chinaware", + "chinese cabbage", + "chinese garden", + "chinese knot", + "chinese rose", + "chinese tower", + "chip", + "chipmunk", + "chisel", + "chocolate", + "chocolate bar", + "chocolate cake", + "chocolate chip", + "chocolate chip cookie", + "chocolate milk", + "chocolate mousse", + "truffle", + "choir", + "kitchen knife", + "cutting board", + "chopstick", + "christmas", + "christmas ball", + "christmas card", + "christmas decoration", + "christmas dinner", + "christmas eve", + "christmas hat", + "christmas light", + "christmas market", + "christmas ornament", + "christmas tree", + "chrysanthemum", + "church", + "church tower", + "cider", + "cigar", + "cigar box", + "cigarette", + "cigarette case", + "waistband", + "cinema", + "photographer", + "cinnamon", + "circle", + "circuit", + "circuit board", + "circus", + "water tank", + "citrus fruit", + "city", + "city bus", + "city hall", + "city nightview", + "city park", + "city skyline", + "city square", + "city street", + "city wall", + "city view", + "clam", + "clarinet", + "clasp", + "class", + "classic", + "classroom", + "clavicle", + "claw", + "clay", + "pottery", + "clean", + "clean room", + "cleaner", + "cleaning product", + "clear", + "cleat", + "clementine", + "client", + "cliff", + "climb", + "climb mountain", + "climber", + "clinic", + "clip", + "clip art", + "clipboard", + "clipper", + "clivia", + "cloak", + "clogs", + "close-up", + "closet", + "cloth", + "clothe", + "clothing", + "clothespin", + "clothesline", + "clothing store", + "cloud", + "cloud forest", + "cloudy", + "clover", + "joker", + "clown fish", + "club", + "clutch", + "clutch bag", + "coal", + "coast", + "coat", + "coatrack", + "cob", + "cock", + "cockatoo", + "cocker", + "cockpit", + "roach", + "cocktail", + "cocktail dress", + "cocktail shaker", + "cocktail table", + "cocoa", + "coconut", + "coconut tree", + "coffee", + "coffee bean", + "coffee cup", + "coffee machine", + "coffee shop", + "coffeepot", + "coffin", + "cognac", + "spiral", + "coin", + "coke", + "colander", + "cold", + "slaw", + "collaboration", + "collage", + "collection", + "college student", + "sheepdog", + "crash", + "color", + "coloring book", + "coloring material", + "pony", + "pillar", + "comb", + "combination lock", + "comic", + "comedy", + "comedy film", + "comet", + "comfort", + "comfort food", + "comic book", + "comic book character", + "comic strip", + "commander", + "commentator", + "community", + "commuter", + "company", + "compass", + "compete", + "contest", + "competitor", + "composer", + "composition", + "compost", + "computer", + "computer box", + "computer chair", + "computer desk", + "keyboard", + "computer monitor", + "computer room", + "computer screen", + "computer tower", + "concept car", + "concert", + "concert hall", + "conch", + "concrete", + "condiment", + "condom", + "condominium", + "conductor", + "cone", + "meeting", + "conference center", + "conference hall", + "meeting room", + "confetti", + "conflict", + "confluence", + "connect", + "connector", + "conservatory", + "constellation", + "construction site", + "construction worker", + "contain", + "container", + "container ship", + "continent", + "profile", + "contract", + "control", + "control tower", + "convenience store", + "convention", + "conversation", + "converter", + "convertible", + "transporter", + "cook", + "cooking", + "cooking spray", + "cooker", + "cool", + "cooler", + "copper", + "copy", + "coral", + "coral reef", + "rope", + "corded phone", + "liquor", + "corgi", + "cork", + "corkboard", + "cormorant", + "corn", + "corn field", + "cornbread", + "corner", + "trumpet", + "cornice", + "cornmeal", + "corral", + "corridor", + "corset", + "cosmetic", + "cosmetics brush", + "cosmetics mirror", + "cosplay", + "costume", + "costumer film designer", + "infant bed", + "cottage", + "cotton", + "cotton candy", + "couch", + "countdown", + "counter", + "counter top", + "country artist", + "country house", + "country lane", + "country pop artist", + "countryside", + "coupe", + "couple", + "couple photo", + "courgette", + "course", + "court", + "courthouse", + "courtyard", + "cousin", + "coverall", + "cow", + "cowbell", + "cowboy", + "cowboy boot", + "cowboy hat", + "crab", + "crabmeat", + "crack", + "cradle", + "craft", + "craftsman", + "cranberry", + "crane", + "crape", + "crapper", + "crate", + "crater lake", + "lobster", + "crayon", + "cream cheese", + "cream pitcher", + "create", + "creature", + "credit card", + "crescent", + "croissant", + "crest", + "crew", + "cricket", + "cricket ball", + "cricket team", + "cricketer", + "crochet", + "crock pot", + "crocodile", + "crop", + "crop top", + "cross", + "crossbar", + "crossroad", + "crosstalk", + "crosswalk", + "crouton", + "crow", + "crowbar", + "crowd", + "crowded", + "crown", + "crt screen", + "crucifix", + "cruise", + "cruise ship", + "cruiser", + "crumb", + "crush", + "crutch", + "crystal", + "cub", + "cube", + "cucumber", + "cue", + "cuff", + "cufflink", + "cuisine", + "farmland", + "cup", + "cupcake", + "cupid", + "curb", + "curl", + "hair roller", + "currant", + "currency", + "curry", + "curtain", + "curve", + "pad", + "customer", + "cut", + "cutlery", + "cycle", + "cycling", + "cyclone", + "cylinder", + "cymbal", + "cypress", + "cypress tree", + "dachshund", + "daffodil", + "dagger", + "dahlia", + "daikon", + "dairy", + "daisy", + "dam", + "damage", + "damp", + "dance", + "dance floor", + "dance room", + "dancer", + "dandelion", + "dark", + "darkness", + "dart", + "dartboard", + "dashboard", + "date", + "daughter", + "dawn", + "day bed", + "daylight", + "deadbolt", + "death", + "debate", + "debris", + "decanter", + "deck", + "decker bus", + "decor", + "decorate", + "decorative picture", + "deer", + "defender", + "deity", + "delicatessen", + "deliver", + "demolition", + "monster", + "demonstration", + "den", + "denim jacket", + "dentist", + "department store", + "depression", + "derby", + "dermopathy", + "desert", + "desert road", + "design", + "designer", + "table", + "table lamp", + "desktop", + "desktop computer", + "dessert", + "destruction", + "detective", + "detergent", + "dew", + "dial", + "diamond", + "diaper", + "diaper bag", + "journal", + "die", + "diet", + "excavator", + "number", + "digital clock", + "dill", + "dinner", + "rowboat", + "dining room", + "dinner party", + "dinning table", + "dinosaur", + "dip", + "diploma", + "direct", + "director", + "dirt", + "dirt bike", + "dirt field", + "dirt road", + "dirt track", + "disaster", + "disciple", + "disco", + "disco ball", + "discotheque", + "disease", + "plate", + "dish antenna", + "dish washer", + "dishrag", + "dishes", + "dishsoap", + "Disneyland", + "dispenser", + "display", + "display window", + "trench", + "dive", + "diver", + "diving board", + "paper cup", + "dj", + "doberman", + "dock", + "doctor", + "document", + "documentary", + "dog", + "dog bed", + "dog breed", + "dog collar", + "dog food", + "dog house", + "doll", + "dollar", + "dollhouse", + "dolly", + "dolphin", + "dome", + "domicile", + "domino", + "donkey", + "donut", + "doodle", + "door", + "door handle", + "doormat", + "doorplate", + "doorway", + "dormitory", + "dough", + "downtown", + "dozer", + "drag", + "dragon", + "dragonfly", + "drain", + "drama", + "drama film", + "draw", + "drawer", + "drawing", + "drawing pin", + "pigtail", + "dress", + "dress hat", + "dress shirt", + "dress shoe", + "dress suit", + "dresser", + "dressing room", + "dribble", + "drift", + "driftwood", + "drill", + "drink", + "drinking water", + "drive", + "driver", + "driveway", + "drone", + "drop", + "droplight", + "dropper", + "drought", + "medicine", + "pharmacy", + "drum", + "drummer", + "drumstick", + "dry", + "duchess", + "duck", + "duckbill", + "duckling", + "duct tape", + "dude", + "duet", + "duffel", + "canoe", + "dumbbell", + "dumpling", + "dune", + "dunk", + "durian", + "dusk", + "dust", + "garbage truck", + "dustpan", + "duvet", + "DVD", + "dye", + "eagle", + "ear", + "earmuff", + "earphone", + "earplug", + "earring", + "earthquake", + "easel", + "easter", + "easter bunny", + "easter egg", + "eat", + "restaurant", + "eclair", + "eclipse", + "ecosystem", + "edit", + "education", + "educator", + "eel", + "egg", + "egg roll", + "egg tart", + "eggbeater", + "egret", + "Eiffel tower", + "elastic band", + "senior", + "electric chair", + "electric drill", + "electrician", + "electricity", + "electron", + "electronic", + "elephant", + "elevation map", + "elevator", + "elevator car", + "elevator door", + "elevator lobby", + "elevator shaft", + "embankment", + "embassy", + "embellishment", + "ember", + "emblem", + "embroidery", + "emerald", + "emergency", + "emergency service", + "emergency vehicle", + "emotion", + "Empire State Building", + "enamel", + "enclosure", + "side table", + "energy", + "engagement", + "engagement ring", + "engine", + "engine room", + "engineer", + "engineering", + "english shorthair", + "ensemble", + "enter", + "entertainer", + "entertainment", + "entertainment center", + "entrance", + "entrance hall", + "envelope", + "equestrian", + "equipment", + "eraser", + "erhu", + "erosion", + "escalator", + "escargot", + "espresso", + "estate", + "estuary", + "eucalyptus tree", + "evening", + "evening dress", + "evening light", + "evening sky", + "evening sun", + "event", + "evergreen", + "ewe", + "excavation", + "exercise", + "exhaust hood", + "exhibition", + "exit", + "explorer", + "explosion", + "extension cord", + "extinguisher", + "extractor", + "extrude", + "eye", + "eye shadow", + "eyebrow", + "eyeliner", + "fabric", + "fabric store", + "facade", + "face", + "face close-up", + "face powder", + "face towel", + "facial tissue holder", + "facility", + "factory", + "factory workshop", + "fair", + "fairground", + "fairy", + "falcon", + "fall", + "family", + "family car", + "family photo", + "family room", + "fan", + "fang", + "farm", + "farmer", + "farmer market", + "farmhouse", + "fashion", + "fashion accessory", + "fashion designer", + "fashion girl", + "fashion illustration", + "fashion look", + "fashion model", + "fashion show", + "fast food", + "fastfood restaurant", + "father", + "faucet", + "fault", + "fauna", + "fawn", + "fax", + "feast", + "feather", + "fedora", + "feed", + "feedbag", + "feeding", + "feeding chair", + "feline", + "mountain lion", + "fence", + "fender", + "fern", + "ferret", + "ferris wheel", + "ferry", + "fertilizer", + "festival", + "fiber", + "fiction", + "fiction book", + "field", + "field road", + "fig", + "fight", + "figure skater", + "figurine", + "file", + "file photo", + "file cabinet", + "fill", + "film camera", + "film director", + "film format", + "film premiere", + "film producer", + "filming", + "filter", + "fin", + "hand", + "finish line", + "fir", + "fir tree", + "fire", + "fire alarm", + "fire department", + "fire truck", + "fire escape", + "fire hose", + "fire pit", + "fire station", + "firecracker", + "fireman", + "fireplace", + "firework", + "firework display", + "first-aid kit", + "fish", + "fish boat", + "fish market", + "fish pond", + "fishbowl", + "fisherman", + "fishing", + "fishing boat", + "fishing net", + "fishing pole", + "fishing village", + "fitness", + "fitness course", + "five", + "fixture", + "fjord", + "flag", + "flag pole", + "flake", + "flame", + "flamingo", + "flannel", + "flap", + "flare", + "flash", + "flask", + "flat", + "flatfish", + "flavor", + "flea", + "flea market", + "fleet", + "flight", + "flight attendant", + "flip", + "flip-flop", + "flipchart", + "float", + "flock", + "flood", + "floor", + "floor fan", + "floor mat", + "floor plan", + "floor window", + "floral arrangement", + "florist", + "floss", + "flour", + "flow", + "flower", + "flower basket", + "flower bed", + "flower box", + "flower field", + "flower girl", + "flower market", + "fluid", + "flush", + "flute", + "fly", + "fly fishing", + "flyer", + "horse", + "foam", + "fog", + "foggy", + "foie gra", + "foil", + "folding chair", + "leaf", + "folk artist", + "folk dance", + "folk rock artist", + "fondant", + "hotpot", + "font", + "food", + "food coloring", + "food court", + "food processor", + "food stand", + "food truck", + "foosball", + "foot", + "foot bridge", + "football", + "football coach", + "football college game", + "football match", + "football field", + "football game", + "football helmet", + "football player", + "football stadium", + "football team", + "path", + "footprint", + "footrest", + "footstall", + "footwear", + "forbidden city", + "ford", + "forehead", + "forest", + "forest fire", + "forest floor", + "forest path", + "forest road", + "forge", + "fork", + "forklift", + "form", + "formal garden", + "formation", + "formula 1", + "fort", + "fortification", + "forward", + "fossil", + "foundation", + "fountain", + "fountain pen", + "fox", + "frame", + "freckle", + "highway", + "lorry", + "French", + "French bulldog", + "French fries", + "French toast", + "freshener", + "fridge", + "fried chicken", + "fried egg", + "fried rice", + "friendship", + "frisbee", + "frog", + "frost", + "frosting", + "frosty", + "frozen", + "fruit", + "fruit cake", + "fruit dish", + "fruit market", + "fruit salad", + "fruit stand", + "fruit tree", + "fruits shop", + "fry", + "frying pan", + "fudge", + "fuel", + "fume hood", + "fun", + "funeral", + "fungi", + "funnel", + "fur", + "fur coat", + "furniture", + "futon", + "gadget", + "muzzle", + "galaxy", + "gallery", + "game", + "game board", + "game controller", + "ham", + "gang", + "garage", + "garage door", + "garage kit", + "garbage", + "garden", + "garden asparagus", + "garden hose", + "garden spider", + "gardener", + "gardening", + "garfield", + "gargoyle", + "wreath", + "garlic", + "garment", + "gas", + "gas station", + "gas stove", + "gasmask", + "collect", + "gathering", + "gauge", + "gazebo", + "gear", + "gecko", + "geisha", + "gel", + "general store", + "generator", + "geranium", + "ghost", + "gift", + "gift bag", + "gift basket", + "gift box", + "gift card", + "gift shop", + "gift wrap", + "gig", + "gin", + "ginger", + "gingerbread", + "gingerbread house", + "ginkgo tree", + "giraffe", + "girl", + "give", + "glacier", + "gladiator", + "glass bead", + "glass bottle", + "glass bowl", + "glass box", + "glass building", + "glass door", + "glass floor", + "glass house", + "glass jar", + "glass plate", + "glass table", + "glass vase", + "glass wall", + "glass window", + "glasses", + "glaze", + "glider", + "earth", + "glove", + "glow", + "glue pudding", + "go", + "go for", + "goal", + "goalkeeper", + "goat", + "goat cheese", + "gobi", + "goggles", + "gold", + "gold medal", + "Golden Gate Bridge", + "golden retriever", + "goldfish", + "golf", + "golf cap", + "golf cart", + "golf club", + "golf course", + "golfer", + "goose", + "gorilla", + "gothic", + "gourd", + "government", + "government agency", + "gown", + "graduate", + "graduation", + "grain", + "grampus", + "grand prix", + "grandfather", + "grandmother", + "grandparent", + "granite", + "granola", + "grape", + "grapefruit", + "wine", + "grass", + "grasshopper", + "grassland", + "grassy", + "grater", + "grave", + "gravel", + "gravestone", + "gravy", + "gravy boat", + "gray", + "graze", + "grazing", + "green", + "greenery", + "greet", + "greeting", + "greeting card", + "greyhound", + "grid", + "griddle", + "grill", + "grille", + "grilled eel", + "grind", + "grinder", + "grits", + "grocery bag", + "grotto", + "ground squirrel", + "group", + "group photo", + "grove", + "grow", + "guacamole", + "guard", + "guard dog", + "guest house", + "guest room", + "guide", + "guinea pig", + "guitar", + "guitarist", + "gulf", + "gull", + "gun", + "gundam", + "gurdwara", + "guzheng", + "gym", + "gymnast", + "habitat", + "hacker", + "hail", + "hair", + "hair color", + "hair spray", + "hairbrush", + "haircut", + "hairgrip", + "hairnet", + "hairpin", + "hairstyle", + "half", + "hall", + "halloween", + "halloween costume", + "halloween pumpkin", + "halter top", + "hamburg", + "hamburger", + "hami melon", + "hammer", + "hammock", + "hamper", + "hamster", + "hand dryer", + "hand glass", + "hand towel", + "handbag", + "handball", + "handcuff", + "handgun", + "handkerchief", + "handle", + "handsaw", + "handshake", + "handstand", + "handwriting", + "hanfu", + "hang", + "hangar", + "hanger", + "happiness", + "harbor", + "harbor seal", + "hard rock artist", + "hardback book", + "safety helmet", + "hardware", + "hardware store", + "hardwood", + "hardwood floor", + "mouth organ", + "pipe organ", + "harpsichord", + "harvest", + "harvester", + "hassock", + "hat", + "hatbox", + "hautboy", + "hawthorn", + "hay", + "hayfield", + "hazelnut", + "head", + "head coach", + "headlight", + "headboard", + "headdress", + "headland", + "headquarter", + "hearing", + "heart", + "heart shape", + "heat", + "heater", + "heather", + "hedge", + "hedgehog", + "heel", + "helicopter", + "heliport", + "helmet", + "help", + "hen", + "henna", + "herb", + "herd", + "hermit crab", + "hero", + "heron", + "hibiscus", + "hibiscus flower", + "hide", + "high bar", + "high heel", + "highland", + "highlight", + "hike", + "hiker", + "hiking boot", + "hiking equipment", + "hill", + "hill country", + "hill station", + "hillside", + "hindu temple", + "hinge", + "hip", + "hip hop artist", + "hippo", + "historian", + "historic", + "history", + "hockey", + "hockey arena", + "hockey game", + "hockey player", + "hockey stick", + "hoe", + "hole", + "vacation", + "holly", + "holothurian", + "home", + "home appliance", + "home base", + "home decor", + "home interior", + "home office", + "home theater", + "homework", + "hummus", + "honey", + "beehive", + "honeymoon", + "hood", + "hoodie", + "hook", + "jump", + "horizon", + "hornbill", + "horned cow", + "hornet", + "horror", + "horror film", + "horse blanket", + "horse cart", + "horse farm", + "horse ride", + "horseback", + "horseshoe", + "hose", + "hospital", + "hospital bed", + "hospital room", + "host", + "inn", + "hot", + "hot air balloon", + "hot dog", + "hot sauce", + "hot spring", + "hotel", + "hotel lobby", + "hotel room", + "hotplate", + "hourglass", + "house", + "house exterior", + "houseplant", + "hoverboard", + "howler", + "huddle", + "hug", + "hula hoop", + "person", + "humidifier", + "hummingbird", + "humpback whale", + "hunt", + "hunting lodge", + "hurdle", + "hurricane", + "husky", + "hut", + "hyaena", + "hybrid", + "hydrangea", + "hydrant", + "seaplane", + "ice", + "ice bag", + "polar bear", + "ice cave", + "icecream", + "ice cream cone", + "ice cream parlor", + "ice cube", + "ice floe", + "ice hockey player", + "ice hockey team", + "lollipop", + "ice maker", + "rink", + "ice sculpture", + "ice shelf", + "skate", + "ice skating", + "iceberg", + "icicle", + "icing", + "icon", + "id photo", + "identity card", + "igloo", + "light", + "iguana", + "illuminate", + "illustration", + "image", + "impala", + "incense", + "independence day", + "individual", + "indoor", + "indoor rower", + "induction cooker", + "industrial area", + "industry", + "infantry", + "inflatable boat", + "information desk", + "infrastructure", + "ingredient", + "inhalator", + "injection", + "injury", + "ink", + "inking pad", + "inlet", + "inscription", + "insect", + "install", + "instrument", + "insulated cup", + "interaction", + "interior design", + "website", + "intersection", + "interview", + "invertebrate", + "invitation", + "ipad", + "iphone", + "ipod", + "iris", + "iron", + "ironing board", + "irrigation system", + "island", + "islet", + "isopod", + "ivory", + "ivy", + "izakaya", + "jack", + "jackcrab", + "jacket", + "jacuzzi", + "jade", + "jaguar", + "jail cell", + "jam", + "japanese garden", + "jasmine", + "jaw", + "jay", + "jazz", + "jazz artist", + "jazz fusion artist", + "jeans", + "jeep", + "jelly", + "jelly bean", + "jellyfish", + "jet", + "motorboat", + "jewel", + "jewellery", + "jewelry shop", + "jigsaw puzzle", + "rickshaw", + "jockey", + "jockey cap", + "jog", + "joint", + "journalist", + "joystick", + "judge", + "jug", + "juggle", + "juice", + "juicer", + "jujube", + "jump rope", + "jumpsuit", + "jungle", + "junkyard", + "kale", + "kaleidoscope", + "kangaroo", + "karaoke", + "karate", + "karting", + "kasbah", + "kayak", + "kebab", + "key", + "keycard", + "khaki", + "kick", + "kilt", + "kimono", + "kindergarden classroom", + "kindergarten", + "king", + "king crab", + "kiss", + "kit", + "kitchen", + "kitchen cabinet", + "kitchen counter", + "kitchen floor", + "kitchen hood", + "kitchen island", + "kitchen sink", + "kitchen table", + "kitchen utensil", + "kitchen window", + "kitchenware", + "kite", + "kiwi", + "knee pad", + "kneel", + "knife", + "rider", + "knit", + "knitting needle", + "knob", + "knocker", + "knot", + "koala", + "koi", + "ktv", + "laboratory", + "lab coat", + "label", + "labrador", + "maze", + "lace", + "lace dress", + "ladder", + "ladle", + "ladybird", + "lagoon", + "lake", + "lake district", + "lake house", + "lakeshore", + "lamb", + "lamb chop", + "lamp post", + "lamp shade", + "spear", + "land", + "land vehicle", + "landfill", + "landing", + "landing deck", + "landmark", + "landscape", + "landslide", + "lanyard", + "lantern", + "lap", + "laptop", + "laptop keyboard", + "larva", + "lasagne", + "laser", + "lash", + "lasso", + "latch", + "latex", + "latte", + "laugh", + "launch", + "launch event", + "launch party", + "laundromat", + "laundry", + "laundry basket", + "laundry room", + "lava", + "lavender", + "lawn", + "lawn wedding", + "lawyer", + "lay", + "lead", + "lead singer", + "lead to", + "leader", + "leak", + "lean", + "learn", + "leash", + "leather", + "leather jacket", + "leather shoe", + "speech", + "lecture hall", + "lecture room", + "ledge", + "leftover", + "leg", + "legend", + "legging", + "legislative chamber", + "lego", + "legume", + "lemon", + "lemon juice", + "lemonade", + "lemur", + "lens", + "lens flare", + "lentil", + "leopard", + "leotard", + "tights", + "leprechaun", + "lesson", + "letter", + "mailbox", + "letter logo", + "lettering", + "lettuce", + "level", + "library", + "license", + "license plate", + "lichen", + "lick", + "lid", + "lie", + "life belt", + "life jacket", + "lifeboat", + "lifeguard", + "lift", + "light fixture", + "light show", + "light switch", + "lighting", + "lightning", + "lightning rod", + "lilac", + "lily", + "limb", + "lime", + "limestone", + "limo", + "line", + "line art", + "line up", + "linen", + "liner", + "lion", + "lip balm", + "lipstick", + "liquid", + "liquor store", + "list", + "litchi", + "live", + "livestock", + "living room", + "living space", + "lizard", + "load", + "loading dock", + "loafer", + "hallway", + "locate", + "lock", + "lock chamber", + "locker", + "loft", + "log", + "log cabin", + "logo", + "loki", + "long hair", + "longboard", + "loom", + "loop", + "lose", + "lottery", + "lotus", + "love", + "loveseat", + "luggage", + "lumber", + "lumberjack", + "lunch", + "lunch box", + "lush", + "luxury", + "luxury yacht", + "mac", + "macadamia", + "macaque", + "macaroni", + "macaw", + "machete", + "machine", + "machine gun", + "magazine", + "magic", + "magician", + "magnet", + "magnifying glass", + "magnolia", + "magpie", + "mahjong", + "mahout", + "maid", + "chain mail", + "mail slot", + "make", + "makeover", + "makeup artist", + "makeup tool", + "mallard", + "mallard duck", + "mallet", + "mammal", + "mammoth", + "man", + "management", + "manager", + "manatee", + "mandala", + "mandarin orange", + "mandarine", + "mane", + "manga", + "manger", + "mango", + "mangosteen", + "mangrove", + "manhattan", + "manhole", + "manhole cover", + "manicure", + "mannequin", + "manor house", + "mansion", + "mantid", + "mantle", + "manufactured home", + "manufacturing", + "manuscript", + "map", + "maple", + "maple leaf", + "maple syrup", + "maraca", + "marathon", + "marble", + "march", + "marching band", + "mare", + "marigold", + "marine", + "marine invertebrate", + "marine mammal", + "puppet", + "mark", + "market", + "market square", + "market stall", + "marriage", + "martial", + "martial artist", + "martial arts gym", + "martini", + "martini glass", + "mascara", + "mascot", + "mashed potato", + "masher", + "mask", + "massage", + "mast", + "mat", + "matador", + "match", + "matchbox", + "material", + "mattress", + "mausoleum", + "maxi dress", + "meal", + "measuring cup", + "measuring tape", + "meat", + "meatball", + "mechanic", + "mechanical fan", + "medal", + "media", + "medical equipment", + "medical image", + "medical staff", + "medicine cabinet", + "medieval", + "medina", + "meditation", + "meerkat", + "meet", + "melon", + "monument", + "menu", + "mermaid", + "net", + "mess", + "messenger bag", + "metal", + "metal artist", + "metal detector", + "meter", + "mezzanine", + "microphone", + "microscope", + "microwave", + "midnight", + "milestone", + "military uniform", + "milk", + "milk can", + "milk tea", + "milkshake", + "mill", + "mine", + "miner", + "mineral", + "mineral water", + "miniskirt", + "miniature", + "minibus", + "minister", + "minivan", + "mint", + "mint candy", + "mirror", + "miss", + "missile", + "mission", + "mistletoe", + "mix", + "mixer", + "mixing bowl", + "mixture", + "moat", + "mobility scooter", + "model", + "model car", + "modern", + "modern tower", + "moisture", + "mold", + "molding", + "mole", + "monarch", + "money", + "monitor", + "monk", + "monkey", + "monkey wrench", + "monochrome", + "monocycle", + "monster truck", + "moon", + "moon cake", + "moonlight", + "moor", + "moose", + "swab", + "moped", + "morning", + "morning fog", + "morning light", + "morning sun", + "mortar", + "mosaic", + "mosque", + "mosquito", + "moss", + "motel", + "moth", + "mother", + "motherboard", + "motif", + "sport", + "motor", + "motorbike", + "motorcycle", + "motorcycle helmet", + "motorcycle racer", + "motorcyclist", + "motorsport", + "mound", + "mountain", + "mountain bike", + "mountain biker", + "mountain biking", + "mountain gorilla", + "mountain lake", + "mountain landscape", + "mountain pass", + "mountain path", + "mountain range", + "mountain river", + "mountain snowy", + "mountain stream", + "mountain view", + "mountain village", + "mountaineer", + "mountaineering bag", + "mouse", + "mousepad", + "mousetrap", + "mouth", + "mouthwash", + "move", + "movie poster", + "movie ticket", + "mower", + "mp3 player", + "mr", + "mud", + "muffin", + "mug", + "mulberry", + "mulch", + "mule", + "municipality", + "mural", + "muscle", + "muscle car", + "museum", + "mushroom", + "music", + "music festival", + "music stool", + "music studio", + "music video performer", + "musical keyboard", + "musician", + "mussel", + "mustard", + "mythology", + "nacho", + "nail polish", + "nailfile", + "nanny", + "napkin", + "narrow", + "national flag", + "nativity scene", + "natural history museum", + "nature", + "nature reserve", + "navigation", + "navratri", + "navy", + "nebula", + "neck", + "neckband", + "necklace", + "neckline", + "nectar", + "nectarine", + "needle", + "neighbor", + "neighbourhood", + "neon", + "neon light", + "nerve", + "nest", + "new year", + "newborn", + "newfoundland", + "newlywed", + "news", + "news conference", + "newsstand", + "night", + "night market", + "night sky", + "night view", + "nightclub", + "nightstand", + "noodle", + "nose", + "noseband", + "note", + "notebook", + "notepad", + "notepaper", + "notice", + "number icon", + "nun", + "nurse", + "nursery", + "nursing home", + "nut", + "nutcracker", + "oak", + "oak tree", + "oar", + "oasis", + "oast house", + "oatmeal", + "oats", + "obelisk", + "observation tower", + "observatory", + "obstacle course", + "sea", + "octopus", + "offer", + "office", + "office building", + "office chair", + "office cubicle", + "office desk", + "office supply", + "office window", + "officer", + "official", + "oil", + "oil lamp", + "oil painting", + "oilrig", + "okra", + "old photo", + "olive", + "olive oil", + "olive tree", + "omelet", + "onion", + "onion ring", + "opal", + "open", + "opening", + "opening ceremony", + "opera", + "opera house", + "operate", + "operating room", + "operation", + "optical shop", + "orangutan", + "orange", + "orange juice", + "orange tree", + "orangery", + "orbit", + "orchard", + "orchestra pit", + "orchid", + "order", + "organization", + "origami", + "ornament", + "osprey", + "ostrich", + "otter", + "out", + "outcrop", + "outdoor", + "outhouse", + "electric outlet", + "outline", + "oval", + "oven", + "overall", + "overcoat", + "overpass", + "owl", + "oyster", + "teething ring", + "pack", + "package", + "paddock", + "police van", + "padlock", + "paella", + "pagoda", + "pain", + "paint brush", + "painter", + "paisley bandanna", + "palace", + "palette", + "paling", + "pall", + "palm tree", + "pan", + "pancake", + "panda", + "panel", + "panorama", + "pansy", + "pant", + "pantry", + "pants", + "pantyhose", + "papaya", + "paper", + "paper bag", + "paper cutter", + "paper lantern", + "paper plate", + "paper towel", + "paperback book", + "paperweight", + "parachute", + "parade", + "paradise", + "parrot", + "paramedic", + "paraquet", + "parasail", + "paratrooper", + "parchment", + "parish", + "park", + "park bench", + "parking", + "parking garage", + "parking meter", + "parking sign", + "parliament", + "parsley", + "participant", + "partner", + "partridge", + "party", + "party hat", + "pass", + "passage", + "passbook", + "passenger", + "passenger ship", + "passenger train", + "passion fruit", + "passport", + "pasta", + "paste", + "pastry", + "pasture", + "patch", + "patient", + "pattern", + "pavement", + "pavilion", + "paw", + "pay", + "payphone", + "pea", + "peace", + "peach", + "peacock", + "peak", + "peanut", + "peanut butter", + "pear", + "pearl", + "pebble", + "pecan", + "pedestrian", + "pedestrian bridge", + "pedestrian street", + "peel", + "peeler", + "pegboard", + "pegleg", + "pelican", + "pen", + "penalty kick", + "pencil", + "pencil case", + "pencil sharpener", + "pencil skirt", + "pendant", + "pendulum", + "penguin", + "peninsula", + "pennant", + "penny", + "piggy bank", + "peony", + "pepper", + "pepper grinder", + "peppercorn", + "pepperoni", + "perch", + "perform", + "performance", + "performance arena", + "perfume", + "pergola", + "persian cat", + "persimmon", + "personal care", + "personal flotation device", + "pest", + "pet", + "pet shop", + "pet store", + "petal", + "petunia", + "church bench", + "pheasant", + "phenomenon", + "philosopher", + "phone", + "phonebook", + "record player", + "photo", + "photo booth", + "photo frame", + "photography", + "physicist", + "physics laboratory", + "pianist", + "piano", + "plectrum", + "pick up", + "pickle", + "picnic", + "picnic area", + "picnic basket", + "picnic table", + "picture", + "picture frame", + "pie", + "pigeon", + "pilgrim", + "tablet", + "pillow", + "pilot", + "pilot boat", + "pin", + "pine", + "pine cone", + "pine forest", + "pine nut", + "pineapple", + "table tennis table", + "table tennis", + "pink", + "pint", + "pipa", + "pipe", + "pipe bowl", + "pirate", + "pirate flag", + "pirate ship", + "pistachio", + "ski slope", + "pocket bread", + "pitaya", + "pitbull", + "pitch", + "pitcher", + "pitcher plant", + "pitchfork", + "pizza", + "pizza cutter", + "pizza pan", + "pizzeria", + "placard", + "place", + "place mat", + "plaid", + "plain", + "plan", + "planet", + "planet earth", + "plank", + "plant", + "plantation", + "planting", + "plaque", + "plaster", + "plastic", + "plasticine", + "plateau", + "platform", + "platinum", + "platter", + "play", + "play badminton", + "play baseball", + "play basketball", + "play billiard", + "play football", + "play pong", + "play tennis", + "play volleyball", + "player", + "playground", + "playhouse", + "playing card", + "playing chess", + "playing golf", + "playing mahjong", + "playingfield", + "playpen", + "playroom", + "plaza", + "plier", + "plot", + "plow", + "plug", + "plug hat", + "plum", + "plumber", + "plumbing fixture", + "plume", + "plywood", + "pocket", + "pocket watch", + "pocketknife", + "pod", + "podium", + "poetry", + "poinsettia", + "point", + "pointer", + "poker card", + "poker chip", + "poker table", + "pole", + "polecat", + "police", + "police car", + "police dog", + "police station", + "politician", + "polka dot", + "pollen", + "pollution", + "polo", + "polo neck", + "polo shirt", + "pomegranate", + "pomeranian", + "poncho", + "pond", + "ponytail", + "poodle", + "pool", + "pop", + "pop artist", + "popcorn", + "pope", + "poppy", + "porcelain", + "porch", + "pork", + "porridge", + "portable battery", + "portal", + "portfolio", + "porthole", + "portrait", + "portrait session", + "pose", + "possum", + "post", + "post office", + "stamp", + "postcard", + "poster", + "poster page", + "pot", + "potato", + "potato chip", + "potato salad", + "potholder", + "potty", + "pouch", + "poultry", + "pound", + "pour", + "powder", + "power line", + "power plugs and sockets", + "power see", + "power station", + "practice", + "Prague Castle", + "prayer", + "preacher", + "premiere", + "prescription", + "show", + "presentation", + "president", + "press room", + "pressure cooker", + "pretzel", + "prince", + "princess", + "print", + "printed page", + "printer", + "printing", + "prison", + "produce", + "product", + "profession", + "professional", + "professor", + "project picture", + "projection screen", + "projector", + "prom", + "promenade", + "propeller", + "prophet", + "proposal", + "protective suit", + "protest", + "protester", + "publication", + "publicity portrait", + "ice hockey", + "pudding", + "puddle", + "puff", + "puffin", + "pug", + "pull", + "pulpit", + "pulse", + "pump", + "pumpkin", + "pumpkin pie", + "pumpkin seed", + "punch bag", + "punch", + "student", + "purple", + "push", + "putt", + "puzzle", + "tower", + "pyramid", + "python", + "qr code", + "quail", + "quarry", + "quarter", + "quartz", + "queen", + "quesadilla", + "queue", + "quiche", + "quilt", + "quilting", + "quote", + "rabbit", + "raccoon", + "race", + "race track", + "raceway", + "race car", + "racket", + "radar", + "radiator", + "radio", + "raft", + "rag doll", + "rail", + "railcar", + "railroad", + "railroad bridge", + "railway line", + "railway station", + "rain", + "rain boot", + "rainbow", + "rainbow trout", + "raincoat", + "rainforest", + "rainy", + "raisin", + "rake", + "ram", + "ramp", + "rapeseed", + "rapid", + "rapper", + "raspberry", + "rat", + "ratchet", + "raven", + "ravine", + "ray", + "razor", + "razor blade", + "read", + "reading", + "reamer", + "rear", + "rear light", + "rear view", + "rearview mirror", + "receipt", + "receive", + "reception", + "recipe", + "record", + "record producer", + "recorder", + "recording studio", + "recreation room", + "recreational vehicle", + "rectangle", + "recycling", + "recycling bin", + "red", + "red carpet", + "red flag", + "red panda", + "red wine", + "redwood", + "reed", + "reef", + "reel", + "referee", + "reflect", + "reflection", + "reflector", + "register", + "rein", + "reindeer", + "relax", + "release", + "relief", + "religion", + "religious", + "relish", + "remain", + "remodel", + "remote", + "remove", + "repair", + "repair shop", + "reptile", + "rescue", + "rescuer", + "research", + "researcher", + "reservoir", + "residence", + "residential neighborhood", + "resin", + "resort", + "resort town", + "restaurant kitchen", + "restaurant patio", + "restroom", + "retail", + "retriever", + "retro", + "reveal", + "rhinoceros", + "rhododendron", + "rib", + "ribbon", + "rice", + "rice cooker", + "rice field", + "ride", + "ridge", + "riding", + "rifle", + "rim", + "ring", + "riot", + "ripple", + "rise", + "rise building", + "river", + "river bank", + "river boat", + "river valley", + "riverbed", + "road", + "road sign", + "road trip", + "roadside", + "roast chicken", + "robe", + "robin", + "robot", + "stone", + "rock arch", + "rock artist", + "rock band", + "rock climber", + "rock climbing", + "rock concert", + "rock face", + "rock formation", + "rocker", + "rocket", + "rocking chair", + "rocky", + "rodent", + "rodeo", + "rodeo arena", + "roe", + "roe deer", + "roller", + "coaster", + "roller skate", + "roller skates", + "rolling pin", + "romance", + "romantic", + "roof", + "roof garden", + "room", + "room divider", + "root", + "root beer", + "rope bridge", + "rosary", + "rose", + "rosemary", + "rosy cloud", + "rottweiler", + "round table", + "router", + "row", + "rowan", + "royal", + "rubber stamp", + "rubble", + "rubik's cube", + "ruby", + "ruffle", + "rugby", + "rugby ball", + "rugby player", + "ruins", + "ruler", + "rum", + "run", + "runner", + "running shoe", + "rural", + "rust", + "rustic", + "rye", + "sack", + "saddle", + "saddlebag", + "safari", + "safe", + "safety vest", + "sage", + "sail", + "sailboat", + "sailing", + "sailor", + "squirrel monkey", + "sake", + "salad", + "salad bowl", + "salamander", + "salami", + "sale", + "salmon", + "salon", + "salsa", + "salt", + "salt and pepper shakers", + "salt lake", + "salt marsh", + "salt shaker", + "salute", + "samoyed", + "samurai", + "sand", + "sand bar", + "sand box", + "sand castle", + "sand sculpture", + "sandal", + "sandwich", + "sanitary napkin", + "santa claus", + "sapphire", + "sardine", + "sari", + "sashimi", + "satay", + "satchel", + "satellite", + "satin", + "sauce", + "saucer", + "sauna", + "sausage", + "savanna", + "saw", + "sawbuck", + "sax", + "saxophonist", + "scaffold", + "scale", + "scale model", + "scallop", + "scar", + "strawman", + "scarf", + "scene", + "scenery", + "schnauzer", + "school", + "school bus", + "school uniform", + "schoolhouse", + "schooner", + "science", + "science fiction film", + "science museum", + "scientist", + "scissors", + "wall lamp", + "scone", + "scoop", + "scooter", + "score", + "scoreboard", + "scorpion", + "scout", + "scrambled egg", + "scrap", + "scraper", + "scratch", + "screen", + "screen door", + "screenshot", + "screw", + "screwdriver", + "scroll", + "scrub", + "scrubbing brush", + "sculptor", + "sculpture", + "sea cave", + "sea ice", + "sea lion", + "sea turtle", + "sea urchin", + "seabass", + "seabed", + "seabird", + "seafood", + "seahorse", + "seal", + "sea view", + "seashell", + "seaside resort", + "season", + "seat", + "seat belt", + "seaweed", + "secretary", + "security", + "sedan", + "see", + "seed", + "seesaw", + "segway", + "selfie", + "sell", + "seminar", + "sense", + "sensor", + "server", + "server room", + "service", + "set", + "sewing machine", + "shadow", + "shake", + "shaker", + "shampoo", + "shape", + "share", + "shark", + "sharpener", + "sharpie", + "shaver", + "shaving cream", + "shawl", + "shear", + "shears", + "sheep", + "sheet", + "sheet music", + "shelf", + "shell", + "shellfish", + "shelter", + "shelve", + "shepherd", + "sherbert", + "shiba inu", + "shine", + "shipping", + "shipping container", + "shipwreck", + "shipyard", + "shirt", + "shirtless", + "shoal", + "shoe", + "shoe box", + "shoe shop", + "shoe tree", + "shoot", + "shooting basketball guard", + "shop window", + "shopfront", + "shopper", + "shopping", + "shopping bag", + "shopping basket", + "shopping cart", + "mall", + "shopping street", + "shore", + "shoreline", + "short", + "short hair", + "shorts", + "shot glass", + "shotgun", + "shoulder", + "shoulder bag", + "shovel", + "showcase", + "shower", + "shower cap", + "shower curtain", + "shower door", + "shower head", + "shredder", + "shrew", + "shrimp", + "shrine", + "shrub", + "shutter", + "siamese", + "siberia", + "sibling", + "side", + "side cabinet", + "side dish", + "sidecar", + "sideline", + "siding", + "sign", + "signage", + "signal", + "signature", + "silk", + "silk stocking", + "silo", + "silver", + "silver medal", + "silverware", + "sing", + "singe", + "singer", + "sink", + "sip", + "sit", + "sitting", + "skate park", + "skateboard", + "skateboarder", + "skater", + "skating rink", + "skeleton", + "sketch", + "skewer", + "ski", + "ski boot", + "ski equipment", + "ski jacket", + "ski lift", + "ski pole", + "ski resort", + "snowboard", + "skier", + "skiing shoes", + "skin", + "skull", + "skullcap", + "sky", + "sky tower", + "skylight", + "skyline", + "skyscraper", + "slalom", + "slate", + "sleigh", + "sleep", + "sleeping bag", + "sleepwear", + "sleeve", + "slice", + "slide", + "slider", + "sling", + "slope", + "slot", + "slot machine", + "sloth", + "slow cooker", + "slug", + "slum", + "smell", + "smile", + "smoke", + "snack", + "snail", + "snake", + "snapper", + "snapshot", + "snorkel", + "snout", + "snow", + "snow leopard", + "snow mountain", + "snowball", + "snowboarder", + "snowfield", + "snowflake", + "snowman", + "snowmobile", + "snowplow", + "snowshoe", + "snowy", + "soap", + "soap bubble", + "soap dispenser", + "soccer goalkeeper", + "socialite", + "sock", + "socket", + "soda", + "softball", + "software", + "solar battery", + "soldier", + "solo", + "solution", + "sombrero", + "song", + "sound", + "soup", + "soup bowl", + "soupspoon", + "sour cream", + "souvenir", + "soybean milk", + "spa", + "space", + "space shuttle", + "space station", + "spacecraft", + "spaghetti", + "span", + "wrench", + "spark", + "sparkle", + "sparkler", + "sparkling wine", + "sparrow", + "spatula", + "speaker", + "spectator", + "speech bubble", + "speed limit", + "speed limit sign", + "speedboat", + "speedometer", + "sphere", + "spice", + "spice rack", + "spider", + "spider web", + "spike", + "spin", + "spinach", + "spire", + "splash", + "sponge", + "spoon", + "sport association", + "sport equipment", + "sport team", + "sports ball", + "sports equipment", + "sports meet", + "sportswear", + "dot", + "spray", + "spread", + "spring", + "spring roll", + "sprinkle", + "sprinkler", + "sprout", + "spruce", + "spruce forest", + "squad", + "square", + "squash", + "squat", + "squeeze", + "squid", + "squirrel", + "water gun", + "stab", + "stable", + "stack", + "stadium", + "staff", + "stage", + "stage light", + "stagecoach", + "stain", + "stainless steel", + "stair", + "stairs", + "stairwell", + "stall", + "stallion", + "stand", + "standing", + "staple", + "stapler", + "star", + "stare", + "starfish", + "starfruit", + "starling", + "state park", + "state school", + "station", + "stationary bicycle", + "stationery", + "statue", + "steak", + "steak knife", + "steam", + "steam engine", + "steam locomotive", + "steam train", + "steamed bread", + "steel", + "steering wheel", + "stem", + "stencil", + "step stool", + "stereo", + "stethoscope", + "stew", + "stick", + "stick insect", + "sticker", + "still life", + "stilt", + "stingray", + "stir", + "stirrer", + "stirrup", + "sew", + "stock", + "stocking", + "stomach", + "stone building", + "stone carving", + "stone house", + "stone mill", + "stool", + "stop", + "stop at", + "stop light", + "stop sign", + "stop watch", + "traffic light", + "storage box", + "storage room", + "tank", + "store", + "storefront", + "stork", + "storm", + "storm cloud", + "stormy", + "stove", + "poker", + "straddle", + "strainer", + "strait", + "strap", + "straw", + "straw hat", + "strawberry", + "stream", + "street art", + "street artist", + "street corner", + "street dog", + "street food", + "street light", + "street market", + "street photography", + "street scene", + "street sign", + "street vendor", + "stretch", + "stretcher", + "strike", + "striker", + "string", + "string cheese", + "strip", + "stripe", + "stroll", + "structure", + "studio", + "studio shot", + "stuff", + "stuffed animal", + "stuffed toy", + "stuffing", + "stump", + "stunning", + "stunt", + "stupa", + "style", + "stylus", + "submarine", + "submarine sandwich", + "submarine water", + "suburb", + "subway", + "subway station", + "subwoofer", + "succulent", + "suede", + "sugar", + "sugar bowl", + "sugar cane", + "sugar cube", + "suit", + "suite", + "summer", + "summer evening", + "summit", + "sun", + "sun hat", + "sunbathe", + "sunday", + "sundial", + "sunflower", + "sunflower field", + "sunflower seed", + "sunglasses", + "sunny", + "sunrise", + "sunset", + "sunshade", + "sunshine", + "super bowl", + "sports car", + "superhero", + "supermarket", + "supermarket shelf", + "supermodel", + "supporter", + "surf", + "surface", + "surfboard", + "surfer", + "surgeon", + "surgery", + "surround", + "sushi", + "sushi bar", + "suspenders", + "suspension", + "suspension bridge", + "suv", + "swallow", + "swallowtail butterfly", + "swamp", + "swan", + "swan boat", + "sweat pant", + "sweatband", + "sweater", + "sweatshirt", + "sweet", + "sweet potato", + "swim", + "swim cap", + "swimmer", + "swimming hole", + "swimming pool", + "swing", + "swing bridge", + "swinge", + "swirl", + "switch", + "swivel chair", + "sword", + "swordfish", + "symbol", + "symmetry", + "synagogue", + "syringe", + "syrup", + "system", + "t shirt", + "t-shirt", + "tabasco sauce", + "tabby", + "table tennis racket", + "table top", + "tablecloth", + "tablet computer", + "tableware", + "tachometer", + "tackle", + "taco", + "tae kwon do", + "tai chi", + "tail", + "tailor", + "take", + "takeoff", + "talk", + "tambourine", + "tan", + "tangerine", + "tape", + "tapestry", + "tarmac", + "taro", + "tarp", + "tart", + "tassel", + "taste", + "tatami", + "tattoo", + "tattoo artist", + "tavern", + "tea", + "tea bag", + "tea party", + "tea plantation", + "tea pot", + "tea set", + "teach", + "teacher", + "teacup", + "teal", + "team photo", + "team presentation", + "tear", + "technician", + "technology", + "teddy", + "tee", + "teenager", + "telegraph pole", + "zoom lens", + "telescope", + "television", + "television camera", + "television room", + "television studio", + "temperature", + "temple", + "tempura", + "tennis", + "tennis court", + "tennis match", + "tennis net", + "tennis player", + "tennis racket", + "tent", + "tequila", + "terminal", + "terrace", + "terrain", + "terrarium", + "territory", + "test", + "test match", + "test tube", + "text", + "text message", + "textile", + "texture", + "thanksgiving", + "thanksgiving dinner", + "theater", + "theatre actor", + "therapy", + "thermometer", + "thermos", + "thermos bottle", + "thermostat", + "thicket", + "thimble", + "thing", + "thinking", + "thistle", + "throne", + "throne room", + "throw", + "throw pillow", + "thunder", + "thunderstorm", + "thyme", + "tiara", + "tick", + "ticket", + "ticket booth", + "tide pool", + "tie", + "tiger", + "tight", + "tile", + "tile flooring", + "tile roof", + "tile wall", + "tin", + "tinfoil", + "tinsel", + "tiramisu", + "tire", + "tissue", + "toast", + "toaster", + "tobacco", + "tobacco pipe", + "toddler", + "toe", + "tofu", + "toilet bowl", + "toilet seat", + "toiletry", + "tokyo tower", + "tomato", + "tomato sauce", + "tomato soup", + "tomb", + "tong", + "tongs", + "tool", + "toolbox", + "toothbrush", + "toothpaste", + "toothpick", + "topiary garden", + "topping", + "torch", + "tornado", + "tortilla", + "tortoise", + "tote bag", + "totem pole", + "totoro", + "toucan", + "touch", + "touchdown", + "tour", + "tour bus", + "tour guide", + "tourist", + "tourist attraction", + "tournament", + "tow truck", + "towel", + "towel bar", + "tower block", + "tower bridge", + "town", + "town square", + "toy", + "toy car", + "toy gun", + "toyshop", + "track", + "tractor", + "trade", + "tradition", + "traditional", + "traffic", + "traffic cone", + "traffic congestion", + "traffic jam", + "traffic sign", + "trail", + "trailer", + "trailer truck", + "train", + "train bridge", + "train car", + "train interior", + "train track", + "train window", + "trainer", + "training", + "training bench", + "training ground", + "trolley", + "trampoline", + "transformer", + "transparency", + "travel", + "tray", + "treadmill", + "treat", + "tree", + "tree branch", + "tree farm", + "tree frog", + "tree house", + "tree root", + "tree trunk", + "trial", + "triangle", + "triathlon", + "tribe", + "tributary", + "trick", + "tricycle", + "trim", + "trio", + "tripod", + "trombone", + "troop", + "trophy", + "trophy cup", + "tropic", + "trout", + "truck", + "truck driver", + "tub", + "tube", + "tugboat", + "tulip", + "tuna", + "tundra", + "tunnel", + "turbine", + "turkey", + "turn", + "turnip", + "turquoise", + "turret", + "turtle", + "tusk", + "tv actor", + "tv cabinet", + "tv drama", + "tv genre", + "tv personality", + "tv show", + "tv sitcom", + "tv tower", + "twig", + "twilight", + "twin", + "twine", + "twist", + "type", + "type on", + "typewriter", + "ukulele", + "ultraman", + "umbrella", + "underclothes", + "underwater", + "unicorn", + "uniform", + "universe", + "university", + "up", + "urban", + "urinal", + "urn", + "use", + "utensil", + "utility room", + "vacuum", + "valley", + "valve", + "vampire", + "van", + "vanilla", + "vanity", + "variety", + "vase", + "vault", + "vector cartoon illustration", + "vector icon", + "vegetable", + "vegetable garden", + "vegetable market", + "vegetation", + "vehicle", + "veil", + "vein", + "velvet", + "vending machine", + "vendor", + "vent", + "vespa", + "vessel", + "vest", + "vet", + "veteran", + "veterinarians office", + "viaduct", + "video", + "video camera", + "video game", + "videotape", + "view mirror", + "vigil", + "villa", + "village", + "vine", + "vinegar", + "vineyard", + "violence", + "violet", + "violin", + "violinist", + "violist", + "vision", + "visor", + "vodka", + "volcano", + "volleyball", + "volleyball court", + "volleyball player", + "volunteer", + "voyage", + "vulture", + "waffle", + "waffle iron", + "wagon", + "wagon wheel", + "waist", + "waiter", + "waiting hall", + "waiting room", + "walk", + "walking", + "walking cane", + "wall clock", + "wallpaper", + "walnut", + "walrus", + "war", + "warehouse", + "warm", + "warning sign", + "warrior", + "warship", + "warthog", + "wash", + "washer", + "washing", + "washing machine", + "wasp", + "waste", + "waste container", + "watch", + "water", + "water bird", + "water buffalo", + "water cooler", + "water drop", + "water feature", + "water heater", + "water level", + "water lily", + "water park", + "water pipe", + "water purifier", + "water ski", + "water sport", + "water surface", + "water tower", + "watercolor", + "watercolor illustration", + "watercolor painting", + "waterfall", + "watering can", + "watermark overlay stamp", + "watermelon", + "waterproof jacket", + "waterway", + "wave", + "wax", + "weapon", + "wear", + "weather", + "vane", + "web", + "webcam", + "wedding", + "wedding ring", + "wedding bouquet", + "wedding cake", + "wedding couple", + "wedding invitation", + "wedding party", + "wedding photo", + "wedding photographer", + "wedding photography", + "wedding reception", + "wedge", + "weed", + "weight", + "weight scale", + "welder", + "well", + "western food", + "western restaurant", + "wet", + "wet bar", + "wet suit", + "wetland", + "wetsuit", + "whale", + "whale shark", + "wheat", + "wheat field", + "wheel", + "wheelchair", + "wheelie", + "whipped cream", + "whisk", + "whisker", + "whiskey", + "whistle", + "white", + "white house", + "white wine", + "whiteboard", + "wicket", + "wide", + "wield", + "wig", + "Wii", + "Wii controller", + "wild", + "wildebeest", + "wildfire", + "wildflower", + "wildlife", + "willow", + "wind", + "wind chime", + "wind farm", + "wind turbine", + "windmill", + "window", + "window box", + "window display", + "window frame", + "window screen", + "window seat", + "window sill", + "wiper", + "windshield", + "windy", + "wine bottle", + "wine cooler", + "wine cabinet", + "wine cellar", + "wine glass", + "wine rack", + "wine tasting", + "winery", + "wing", + "winter", + "winter melon", + "winter morning", + "winter scene", + "winter sport", + "winter storm", + "wire", + "wisteria", + "witch", + "witch hat", + "wok", + "wolf", + "woman", + "wood", + "wood duck", + "wood floor", + "wood wall", + "wood-burning stove", + "wooden spoon", + "woodland", + "woodpecker", + "woodworking plane", + "wool", + "job", + "work card", + "workbench", + "worker", + "workplace", + "workshop", + "world", + "worm", + "worship", + "wound", + "wrap", + "wrap dress", + "wrapping paper", + "wrestle", + "wrestler", + "wrinkle", + "wristband", + "write", + "writer", + "writing", + "writing brush", + "writing desk", + "yacht", + "yak", + "yard", + "yellow", + "yoga", + "yoga mat", + "yoghurt", + "yoke", + "yolk", + "youth", + "youth hostel", + "yurt", + "zebra", + "zebra crossing", + "zen garden", + "zip", + "zipper", + "zombie", + "zongzi", + "zoo", +]; + +pub const NAMES_DOTA_V1_5_16: [&str; 16] = [ + "plane", + "ship", + "storage tank", + "baseball diamond", + "tennis court", + "basketball court", + "ground track field", + "harbor", + "bridge", + "large vehicle", + "small vehicle", + "helicopter", + "roundabout", + "soccer ball field", + "swimming pool", + "container crane", +]; +pub const NAMES_DOTA_V1_15: [&str; 15] = [ + "plane", + "ship", + "storage tank", + "baseball diamond", + "tennis court", + "basketball court", + "ground track field", + "harbor", + "bridge", + "large vehicle", + "small vehicle", + "helicopter", + "roundabout", + "soccer ball field", + "swimming pool", +]; + pub const NAMES_YOLO_DOCLAYOUT_10: [&str; 10] = [ "title", "plain text",