目标检测是计算机视觉领域的重要任务,涉及识别并定位图像中一个或多个对象。以下是一些常见的目标检测模型和架构:
R-CNN系列
- R-CNN (Regions with CNN features):通过选择性搜索产生候选区域,然后使用卷积神经网络(CNN)对每个区域进行特征提取和分类。
- Fast R-CNN:对R-CNN进行改进,通过在整个图像上执行一次卷积操作来提高效率,然后使用ROI Pooling对候选区域进行处理。
- Faster R-CNN:引入了区域建议网络(RPN),用于快速生成候选区域,使得整个检测过程几乎是端到端的。
YOLO (You Only Look Once)系列
YOLOv1, YOLOv2, YOLOv3, 和 YOLOv4:将目标检测作为一个单一的回归问题来处理,直接从整张图像预测边界框和类别。YOLO以实时速度著称。 YOLOv5:虽然命名为v5,其源自不同的开发者团队,以开源的形式发布,进一步提高了检测速度和性能。
YOLOv1(2016)
2016年,Joseph Redmon、Santosh Divvala、Ross Girshick等人提出了一种单阶段(one-stage)的目标检测网络
YOLOv2(2016)
YOLOv2 是 Joseph Redmon和Ali Farhadi发表在CVPR 2017。它包括了对原始YOLO的一些改进,保持相同的速度,也更强大,能够检测9000个类别
YOLOv3 (2018)
2018年,作者Redmon又在YOLOv2的基础上做了一些改进。特征提取部分采用Darknet-53网络结构代替原来的Darknet-19,利用特征金字塔网络结构实现了多尺度检测,分类方法使用逻辑回归代替了softmax,在兼顾实用性的同时保证了目标检测的准确性。
YOLOv4(2020)
从YOLOv3后,YOLO没有新版本。直到2020年4月,Alexey Bochkovskiy、Chien-Yao Wang和Hong-Yuan Mark Liao在ArXiv发布了YOLOv4[50]的论文。起初,不同的作者提出一个新的YOLO "官方 "版本让人感觉很奇怪;然而,YOLOv4保持了相同的YOLO理念——实时、开源、端到端和DarkNet框架——而且改进非常令人满意,社区迅速接受了这个版本作为官方的YOLOv4。
YOLOv5(2020)
YOLOX(2021)
YOLOX在YOLO系列的基础上做了一系列的工作,其主要贡献在于:在YOLOv3的基础上,引入了Decoupled Head,Data Aug,Anchor Free和SimOTA样本匹配的方法,构建了一种anchor-free的端到端目标检测框架
YOLOv6(2022)
YOLOv6于2022年9月由美团视觉人工智能部发布在ArXiv。跟随基于锚点的方法的趋势,YOLOv6采用了无锚点的检测器。YOLOv6对Backbone 和 Neck 都进行了重新设计,Head层沿用了YOLOX中的Decoupled Head并稍作修改。
YOLOv7(2022)
YOLOv7由YOLOv4和YOLOR的同一作者于2022年7月发表在ArXiv
YOLOv8(2023)
YOLOv8 与YOLOv5出自同一个团队,是一款前沿、最先进(SOTA)的模型,基于先前 YOLOv5版本的成功,引入了新功能和改进,进一步提升性能和灵活性。
YOLOv9(2024)
YOLOv9是原YOLOv7团队打造,提出了可编程梯度信息(PGI)的概念来应对深度网络实现多个目标所需的各种变化。 PGI可以为目标任务计算目标函数提供完整的输入信息,从而获得可靠的梯度信息来更新网络权值。此外,还设计了一种新的轻量级网络架构——基于梯度路径规划的通用高效层聚合网络(GELAN)。
YOLOv10
标题:YOLOv10: Real-Time End-to-End Object Detection
论文:arxiv.org/pdf/2405.14…
源码:github.com/THU-MIG/yol…
ultralytics yolov10: docs.ultralytics.com/zh/models/y…
由清华大学研究团队最新提出的,同样遵循 YOLO 系列设计原则,致力于打造实时端到端的高性能目标检测器。
YOLO11
文档:docs.ultralytics.com/zh
源码:github.com/ultralytics…
与 YOLOv8 和 YOLOv5出自同一个团队,为目前稳定版的最新版本
YOLO12
实验版本
SSD (Single Shot MultiBox Detector)
采用一个单一的CNN网络在多个特征尺度上直接预测类别分数和位置偏移,实现快速目标检测。
RetinaNet
引入了焦点损失函数(Focal Loss),以解决正负样本不平衡的问题,在检测小目标和稀疏对象方面表现较好。
EfficientDet
基于EfficientNet主干网络,结合了一种新的复合缩放方法,在效率和精度之间取得良好的平衡。
https://github.com/rwightman/efficientdet-pytorch
CenterNet
使用中心关键点(center keypoint)来检测物体,由键点估计来定位目标。通过简化处理,提供了快速且准确的检测性能。
DETR (Detection Transformer)
基于Transformer架构,使用注意力机制进行目标检测,避免了使用锚框的必要。
import torch
from PIL import Image, ImageDraw, ImageFont
from transformers import AutoImageProcessor, DetrForObjectDetection
model_name = "facebook/detr-resnet-101"
image_path = "data/images/catdog.jpg"
color = (255, 0, 0)
font = ImageFont.load_default()
if __name__ == '__main__':
model = DetrForObjectDetection.from_pretrained(model_name)
print(type(model))
image = Image.open(image_path)
image_processor = AutoImageProcessor.from_pretrained(model_name)
inputs = image_processor(images=image, return_tensors="pt")
print(type(inputs))
outputs = model(**inputs)
print(type(outputs))
# convert outputs (bounding boxes and class logits) to Pascal VOC format (xmin, ymin, xmax, ymax)
target_sizes = torch.tensor([image.size[::-1]])
results = image_processor.post_process_object_detection(outputs, target_sizes=target_sizes)[0]
draw = ImageDraw.Draw(image)
for score, label, box in zip(results["scores"], results["labels"], results["boxes"]):
box = [int(i) for i in box.tolist()]
item_label = model.config.id2label[label.item()]
score = round(score.item(), 3)
print(
f"Detected {item_label} with confidence "
f"{score} at location {box}"
)
draw.rectangle(tuple(box), outline=color, width=2)
draw.text((int((box[2] + box[0]) / 2), box[1]), f"{item_label} {score}", fill=color, font=font)
image.show()
Detected cat with confidence 0.996 at location [398, 116, 659, 484]
Detected dog with confidence 0.999 at location [49, 41, 473, 513]
下述代码参考自:www.bilibili.com/video/BV1Gt…
import time
import torch
import torchvision.transforms as T
from PIL import Image, ImageDraw, ImageFont
CLASSES = [
'N/A', 'person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus',
'train', 'truck', 'boat', 'traffic light', 'fire hydrant', 'N/A',
'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse',
'sheep', 'cow', 'elephant', 'bear', 'zebra', 'giraffe', 'N/A', 'backpack',
'umbrella', 'N/A', 'N/A', 'handbag', 'tie', 'suitcase', 'frisbee', 'skis',
'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove',
'skateboard', 'surfboard', 'tennis racket', 'bottle', 'N/A', 'wine glass',
'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple', 'sandwich',
'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake',
'chair', 'couch', 'potted plant', 'bed', 'N/A', 'dining table', 'N/A',
'N/A', 'toilet', 'N/A', 'tv', 'laptop', 'mouse', 'remote', 'keyboard',
'cell phone', 'microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'N/A',
'book', 'clock', 'vase', 'scissors', 'teddy bear', 'hair drier',
'toothbrush'
]
color = (255, 0, 0)
font = ImageFont.load_default()
if __name__ == '__main__':
model = torch.hub.load('facebookresearch/detr', 'detr_resnet50', pretrained=True)
model.eval()
"""
source ~/.bash_profile
echo $GITHUB_TOKEN
Downloading: "https://download.pytorch.org/models/resnet50-0676ba61.pth" to /Users/morningcat/.cache/torch/hub/checkpoints/resnet50-0676ba61.pth
100%|██████████| 97.8M/97.8M [00:08<00:00, 12.7MB/s]
Downloading: "https://dl.fbaipublicfiles.com/detr/detr-r50-e632da11.pth" to /Users/morningcat/.cache/torch/hub/checkpoints/detr-r50-e632da11.pth
100%|██████████| 159M/159M [00:11<00:00, 14.5MB/s]
"""
transform = T.Compose([
T.Resize(800),
T.ToTensor(),
T.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])
img = Image.open("./data/catdog.jpg")
print(img)
# img = img.resize((800, 600))
# print(img)
print(img.width, img.height)
inputs = transform(img).unsqueeze(0)
print(inputs.shape)
with torch.no_grad():
time_s = time.time()
outputs = model(inputs)
print("耗时", time.time() - time_s, "s")
print(outputs.keys())
print("pred_logits", outputs['pred_logits'][0].shape)
print("pred_boxes", outputs['pred_boxes'][0].shape)
print(outputs['pred_logits'][0].argmax(-1))
draw = ImageDraw.Draw(img)
for logit, boxe in zip(outputs['pred_logits'][0], outputs['pred_boxes'][0]):
class_index = logit.argmax(-1)
if class_index >= len(CLASSES):
continue
i_max = logit.softmax(-1).max(-1)
print(i_max)
rate = i_max.values.item()
score = logit[class_index].item()
label = CLASSES[class_index]
print(label, score, rate)
boxe = boxe * torch.Tensor([img.width, img.height, img.width, img.height])
print(boxe)
x, y, w, h = boxe
x0, y0 = x - w // 2, y - h // 2
x1, y1 = x + w // 2, y + h // 2
draw.rectangle((x0, y0, x1, y1), outline=color, width=2)
draw.text((x0, y0), f" {label} {rate}", fill=color, font=font)
img.show()
<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=728x561 at 0x125CBBAF0>
728 561
torch.Size([1, 3, 800, 1038])
耗时 2.857374906539917 s
dict_keys(['pred_logits', 'pred_boxes'])
pred_logits torch.Size([100, 92])
pred_boxes torch.Size([100, 4])
tensor([91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 18,
91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
91, 91, 91, 91, 91, 91, 91, 91, 17, 91])
torch.return_types.max(
values=tensor(0.9993),
indices=tensor(18))
dog 13.864964485168457 0.9992586970329285
tensor([259.0493, 277.2576, 423.1950, 472.9401])
torch.return_types.max(
values=tensor(0.9972),
indices=tensor(17))
cat 12.74626350402832 0.99724280834198
tensor([527.9902, 301.9145, 260.6261, 366.9550])
Swin-Transformer
https://github.com/microsoft/Swin-Transformerhttps://github.com/SwinTransformer/Swin-Transformer-Object-Detectionhttps://github.com/WZMIAOMIAO/deep-learning-for-image-processing/tree/master/pytorch_classification/swin_transformer
ViT
https://github.com/google-research/vision_transformerhttps://github.com/openai/CLIP