使用faster rcnn进行目标检测(pytorch)

参考Faster R-CNN Object Detection with PyTorch | LearnOpenCV

在R-CNN中,每个边界框由图像分类器独立分类,有2000个区域提案,图像分类器计算了每个区域提案的特征图。这个过程很耗时。 在Ross Girshick的后续工作中,他提出了一种称为快速R-CNN的方法,它显著地加快了目标检测的速度。 其想法是为整个图像计算一个单一的特征图,而不是为2000个区域提案计算2000个特征图。对于每个区域提案,感兴趣区域(ROI)池化层从特征图中提取固定长度的特征向量。然后,每个特征向量被用于两个目的

1、将区域分类为其中一个类(例如。狗,猫,背景)。

2、使用边界框回归器提高原始边界框的精度。

 faster R-CNN目标检测器

在 fast R-CNN中,即使对2000个区域提案进行分类的计算是共享的,但生成区域提案的算法部分与执行图像分类的部分不共享任何计算。 在被称为FasterR-CNN的后续工作中,主要的见解是这两个部分-计算区域提案和图像分类-可以使用相同的特征图,从而分担计算负荷。 利用卷积神经网络生成图像特征图,同时用于训练区域提案网络和图像分类器。由于这种共享计算,对象检测的速度有了显著的提高。
 

下载文件: wget https://cdn.pixabay.com/photo/2013/07/05/01/08/traffic-143391_960_720.jpg -O traffic_scene.jpg

wget https://images.unsplash.com/photo-1458169495136-854e4c39548a -O girl_cars.jpg

完整代码

# coding: UTF-8
# language: python
# import pagage
from PIL import Image
import matplotlib.pyplot as plt
import torch
import torchvision
import torchvision.transforms as transforms
import numpy as np
import cv2


# get the pretrained model from torchvision.models
# note pretrained=True will get the pretraied weights for the model
# model.eval() to use the model for interence
model=torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=True)
model.eval()
# model.cuda() to use the model on the GPU
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
COCO_INSTANCE_CATEGORY_NAMES = [
    '__background__', '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'
]

# 定义一个函数来获得图像路径,并通过模型达到图像的预测

def get_prediction(img_path, threshold):
  img = Image.open(img_path) # Load the image
  transform = transforms.Compose([transforms.ToTensor()]) # Defing PyTorch Transform
  img = transform(img) # Apply the transform to the image
  pred = model([img]) # Pass the image to the model
  print('pred')
  print(pred)
  pred_class = [COCO_INSTANCE_CATEGORY_NAMES[i] for i in list(pred[0]['labels'].numpy())] # Get the Prediction Score
  print("original pred_class")
  print(pred_class)
  pred_boxes = [[(i[0], i[1]), (i[2], i[3])] for i in list(pred[0]['boxes'].detach().numpy())] # Bounding boxes
  print("original pred_boxes")
  print(pred_boxes)
  pred_score = list(pred[0]['scores'].detach().numpy())
  print("orignal score")
  print(pred_score)
  pred_t = [pred_score.index(x) for x in pred_score if x > threshold][-1] # Get list of index with score greater than threshold.
  pred_boxes = pred_boxes[:pred_t+1]
  pred_class = pred_class[:pred_t+1]
  print(pred_t)
  print(pred_boxes)
  print(pred_class)
  return pred_boxes, pred_class


# define a fun to get img_path and output img
def object_detection_api(img_path, threshold=0.5, rect_th=3, text_size=3, text_th=3):
 
  boxes, pred_cls = get_prediction(img_path, threshold) # Get predictions
  img = cv2.imread(img_path) # Read image with cv2
  img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # Convert to RGB
  for i in range(len(boxes)):
    cv2.rectangle(img, (int(boxes[i][0][0]),int(boxes[i][0][1])), (int(boxes[i][1][0]),int(boxes[i][1][1])),color=(0, 255, 0), thickness=rect_th)
    cv2.putText(img,pred_cls[i], (int(boxes[i][0][0]),int(boxes[i][0][1])), cv2.FONT_HERSHEY_SIMPLEX, text_size, (0,255,0),thickness=text_th)
    # cv2.rectangle(img, boxes[i][0], boxes[i][1],color=(0, 255, 0), thickness=rect_th) # Draw Rectangle with the coordinates
    # cv2.putText(img,pred_cls[i], boxes[i][0],  cv2.FONT_HERSHEY_SIMPLEX, text_size, (0,255,0),thickness=text_th) # Write the prediction class
  plt.figure(figsize=(20,30)) # display the output image
  plt.imshow(img)
  plt.xticks([])
  plt.yticks([])
  plt.show()


# object_detection_api('./people.jpg',threshold=0.8)
# object_detection_api('./car.jpg', rect_th=6, text_th=5, text_size=5)
object_detection_api("./traffic_scene.jpg", rect_th=2, text_th=1, text_size=1, threshold=0.5)

# compare cpu and GPU time
import time
 
def check_inference_time(image_path, gpu=False):
  model = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=True)
  model.eval()
  img = Image.open(image_path)
  transform = transforms.Compose([transforms.ToTensor()])
  img = transform(img)
  if gpu:
    model.cuda()
    img = img.cuda()
  else:
    model.cpu()
    img = img.cpu()
  start_time = time.time()
  pred = model([img])
  end_time = time.time()
  return end_time-start_time
 
cpu_time = sum([check_inference_time('./girl_cars.jpg', gpu=False) for _ in range(10)])/10.0
gpu_time = sum([check_inference_time('./girl_cars.jpg', gpu=True) for _ in range(10)])/10.0
 
 
print('\n\nAverage Time take by the model with GPU = {}s\nAverage Time take by the model with CPU = {}s'.format(gpu_time, cpu_time))

你可能感兴趣的:(python,机器学习,目标检测,pytorch,深度学习)