检测与标注

Supervision 提供了一个无缝的流程,用于标注由各种物体检测和分割模型生成的预测结果。本指南展示了如何使用 InferenceUltralyticsTransformers 等包进行推理。接着,你将学习如何将这些预测导入 Supervision 并用于标注原始图像。

基本标注示例

运行检测

首先,你需要从你的物体检测或分割模型中获取预测结果。

“Inference”

  1. import cv2
  2. from inference import get_model
  3. model = get_model(model_id="yolov8n-640")
  4. image = cv2.imread(<SOURCE_IMAGE_PATH>)
  5. results = model.infer(image)[0]

“Ultralytics”

  1. import cv2
  2. from ultralytics import YOLO
  3. model = YOLO("yolov8n.pt")
  4. image = cv2.imread(<SOURCE_IMAGE_PATH>)
  5. results = model(image)[0]

“Transformers”

  1. import torch
  2. from PIL import Image
  3. from transformers import DetrImageProcessor, DetrForObjectDetection
  4. processor = DetrImageProcessor.from_pretrained("facebook/detr-resnet-50")
  5. model = DetrForObjectDetection.from_pretrained("facebook/detr-resnet-50")
  6. image = Image.open(<SOURCE_IMAGE_PATH>)
  7. inputs = processor(images=image, return_tensors="pt")
  8. with torch.no_grad():
  9. outputs = model(**inputs)
  10. width, height = image.size
  11. target_size = torch.tensor([[height, width]])
  12. results = processor.post_process_object_detection(
  13. outputs=outputs, target_sizes=target_size)[0]

将预测结果加载到 Supervision

现在我们有了模型的预测结果,可以将它们加载到 Supervision 中。

“Inference”

我们可以使用 sv.Detections.from_inference 方法加载,该方法支持检测和分割模型的结果。

  1. import cv2
  2. import supervision as sv
  3. from inference import get_model
  4. model = get_model(model_id="yolov8n-640")
  5. image = cv2.imread(<SOURCE_IMAGE_PATH>)
  6. results = model.infer(image)[0]
  7. detections = sv.Detections.from_inference(results)

“Ultralytics”

使用 sv.Detections.from_ultralytics 方法加载,同样支持检测和分割模型结果。

  1. import cv2
  2. import supervision as sv
  3. from ultralytics import YOLO
  4. model = YOLO("yolov8n.pt")
  5. image = cv2.imread(<SOURCE_IMAGE_PATH>)
  6. results = model(image)[0]
  7. detections = sv.Detections.from_ultralytics(results)

“Transformers”

使用 sv.Detections.from_transformers 方法加载,支持检测和分割模型结果。

  1. import torch
  2. import supervision as sv
  3. from PIL import Image
  4. from transformers import DetrImageProcessor, DetrForObjectDetection
  5. processor = DetrImageProcessor.from_pretrained("facebook/detr-resnet-50")
  6. model = DetrForObjectDetection.from_pretrained("facebook/detr-resnet-50")
  7. image = Image.open(<SOURCE_IMAGE_PATH>)
  8. inputs = processor(images=image, return_tensors="pt")
  9. with torch.no_grad():
  10. outputs = model(**inputs)
  11. width, height = image.size
  12. target_size = torch.tensor([[height, width]])
  13. results = processor.post_process_object_detection(
  14. outputs=outputs, target_sizes=target_size)[0]
  15. detections = sv.Detections.from_transformers(
  16. transformers_results=results,
  17. id2label=model.config.id2label)

你也可以使用以下方法加载来自其他计算机视觉框架和库的预测:

使用检测结果标注图像

最后,我们用预测结果对图像进行标注。因为我们使用的是物体检测模型,我们将用到 sv.BoxAnnotatorsv.LabelAnnotator 这两个类。

“Inference”

  1. import cv2
  2. import supervision as sv
  3. from inference import get_model
  4. model = get_model(model_id="yolov8n-640")
  5. image = cv2.imread(<SOURCE_IMAGE_PATH>)
  6. results = model.infer(image)[0]
  7. detections = sv.Detections.from_inference(results)
  8. box_annotator = sv.BoxAnnotator()
  9. label_annotator = sv.LabelAnnotator()
  10. annotated_image = box_annotator.annotate(
  11. scene=image, detections=detections)
  12. annotated_image = label_annotator.annotate(
  13. scene=annotated_image, detections=detections)

“Ultralytics”

  1. import cv2
  2. import supervision as sv
  3. from ultralytics import YOLO
  4. model = YOLO("yolov8n.pt")
  5. image = cv2.imread(<SOURCE_IMAGE_PATH>)
  6. results = model(image)[0]
  7. detections = sv.Detections.from_ultralytics(results)
  8. box_annotator = sv.BoxAnnotator()
  9. label_annotator = sv.LabelAnnotator()
  10. annotated_image = box_annotator.annotate(
  11. scene=image, detections=detections)
  12. annotated_image = label_annotator.annotate(
  13. scene=annotated_image, detections=detections)

“Transformers”

  1. import torch
  2. import supervision as sv
  3. from PIL import Image
  4. from transformers import DetrImageProcessor, DetrForObjectDetection
  5. processor = DetrImageProcessor.from_pretrained("facebook/detr-resnet-50")
  6. model = DetrForObjectDetection.from_pretrained("facebook/detr-resnet-50")
  7. image = Image.open(<SOURCE_IMAGE_PATH>)
  8. inputs = processor(images=image, return_tensors="pt")
  9. with torch.no_grad():
  10. outputs = model(**inputs)
  11. width, height = image.size
  12. target_size = torch.tensor([[height, width]])
  13. results = processor.post_process_object_detection(
  14. outputs=outputs, target_sizes=target_size)[0]
  15. detections = sv.Detections.from_transformers(
  16. transformers_results=results,
  17. id2label=model.config.id2label)
  18. box_annotator = sv.BoxAnnotator()
  19. label_annotator = sv.LabelAnnotator()
  20. annotated_image = box_annotator.annotate(
  21. scene=image, detections=detections)
  22. annotated_image = label_annotator.annotate(
  23. scene=annotated_image, detections=detections)

基本标注示例

显示自定义标签

默认情况下,sv.LabelAnnotator 会使用检测结果的 class_name(如果有)或 class_id 作为标签。你可以通过向 annotate 方法传入自定义的 labels 列表来覆盖这一行为。

“Inference”

  1. import cv2
  2. import supervision as sv
  3. from inference import get_model
  4. model = get_model(model_id="yolov8n-640")
  5. image = cv2.imread(<SOURCE_IMAGE_PATH>)
  6. results = model.infer(image)[0]
  7. detections = sv.Detections.from_inference(results)
  8. box_annotator = sv.BoxAnnotator()
  9. label_annotator = sv.LabelAnnotator()
  10. labels = [
  11. f"{class_name} {confidence:.2f}"
  12. for class_name, confidence
  13. in zip(detections['class_name'], detections.confidence)
  14. ]
  15. annotated_image = box_annotator.annotate(
  16. scene=image, detections=detections)
  17. annotated_image = label_annotator.annotate(
  18. scene=annotated_image, detections=detections, labels=labels)

“Ultralytics”

  1. import cv2
  2. import supervision as sv
  3. from ultralytics import YOLO
  4. model = YOLO("yolov8n.pt")
  5. image = cv2.imread(<SOURCE_IMAGE_PATH>)
  6. results = model(image)[0]
  7. detections = sv.Detections.from_ultralytics(results)
  8. box_annotator = sv.BoxAnnotator()
  9. label_annotator = sv.LabelAnnotator()
  10. labels = [
  11. f"{class_name} {confidence:.2f}"
  12. for class_name, confidence
  13. in zip(detections['class_name'], detections.confidence)
  14. ]
  15. annotated_image = box_annotator.annotate(
  16. scene=image, detections=detections)
  17. annotated_image = label_annotator.annotate(
  18. scene=annotated_image, detections=detections, labels=labels)

“Transformers”

  1. import torch
  2. import supervision as sv
  3. from PIL import Image
  4. from transformers import DetrImageProcessor, DetrForObjectDetection
  5. processor = DetrImageProcessor.from_pretrained("facebook/detr-resnet-50")
  6. model = DetrForObjectDetection.from_pretrained("facebook/detr-resnet-50")
  7. image = Image.open(<SOURCE_IMAGE_PATH>)
  8. inputs = processor(images=image, return_tensors="pt")
  9. with torch.no_grad():
  10. outputs = model(**inputs)
  11. width, height = image.size
  12. target_size = torch.tensor([[height, width]])
  13. results = processor.post_process_object_detection(
  14. outputs=outputs, target_sizes=target_size)[0]
  15. detections = sv.Detections.from_transformers(
  16. transformers_results=results,
  17. id2label=model.config.id2label)
  18. box_annotator = sv.BoxAnnotator()
  19. label_annotator = sv.LabelAnnotator()
  20. labels = [
  21. f"{class_name} {confidence:.2f}"
  22. for class_name, confidence
  23. in zip(detections['class_name'], detections.confidence)
  24. ]
  25. annotated_image = box_annotator.annotate(
  26. scene=image, detections=detections)
  27. annotated_image = label_annotator.annotate(
  28. scene=annotated_image, detections=detections, labels=labels)

自定义标签标注示例

使用分割结果标注图像

如果你使用的是分割模型,sv.MaskAnnotator 可以替代 sv.BoxAnnotator,用来绘制掩码而不是边框。

“Inference”

  1. import cv2
  2. import supervision as sv
  3. from inference import get_model
  4. model = get_model(model_id="yolov8n-seg-640")
  5. image = cv2.imread(<SOURCE_IMAGE_PATH>)
  6. results = model.infer(image)[0]
  7. detections = sv.Detections.from_inference(results)
  8. mask_annotator = sv.MaskAnnotator()
  9. label_annotator = sv.LabelAnnotator(text_position=sv.Position.CENTER_OF_MASS)
  10. annotated_image = mask_annotator.annotate(
  11. scene=image, detections=detections)
  12. annotated_image = label_annotator.annotate(
  13. scene=annotated_image, detections=detections)

“Ultralytics”

  1. import cv2
  2. import supervision as sv
  3. from ultralytics import YOLO
  4. model = YOLO("yolov8n-seg.pt")
  5. image = cv2.imread(<SOURCE_IMAGE_PATH>)
  6. results = model(image)[0]
  7. detections = sv.Detections.from_ultralytics(results)
  8. mask_annotator = sv.MaskAnnotator()
  9. label_annotator = sv.LabelAnnotator(text_position=sv.Position.CENTER_OF_MASS)
  10. annotated_image = mask_annotator.annotate(
  11. scene=image, detections=detections)
  12. annotated_image = label_annotator.annotate(
  13. scene=annotated_image, detections=detections)

“Transformers”

  1. import torch
  2. import supervision as sv
  3. from PIL import Image
  4. from transformers import DetrImageProcessor, DetrForSegmentation
  5. processor = DetrImageProcessor.from_pretrained("facebook/detr-resnet-50-panoptic")
  6. model = DetrForSegmentation.from_pretrained("facebook/detr-resnet-50-panoptic")
  7. image = Image.open(<SOURCE_IMAGE_PATH>)
  8. inputs = processor(images=image, return_tensors="pt")
  9. with torch.no_grad():
  10. outputs = model(**inputs)
  11. width, height = image.size
  12. target_size = torch.tensor([[height, width]])
  13. results = processor.post_process_segmentation(
  14. outputs=outputs, target_sizes=target_size)[0]
  15. detections = sv.Detections.from_transformers(
  16. transformers_results=results,
  17. id2label=model.config.id2label)
  18. mask_annotator = sv.MaskAnnotator()
  19. label_annotator = sv.LabelAnnotator(text_position=sv.Position.CENTER_OF_MASS)
  20. labels = [
  21. f"{class_name} {confidence:.2f}"
  22. for class_name, confidence
  23. in zip(detections['class_name'], detections.confidence)
  24. ]
  25. annotated_image = mask_annotator.annotate(
  26. scene=image, detections=detections)
  27. annotated_image = label_annotator.annotate(
  28. scene=annotated_image, detections=detections, labels=labels)

分割标注示例