计算机视觉 - 物体检测

什么是物体检测?

物体检测是一种计算机视觉技术,用于定位图像或视频中的物体实例。

目标是识别物体的存在并在它们周围绘制边界框以指示它们的位置。物体检测结合了图像分类和物体定位。

物体检测的重要性

物体检测对于各种实际应用都很重要,例如−

  • 自动驾驶汽车:检测道路上的行人、车辆和障碍物。
  • 监视:监控活动并识别可疑物体。
  • 医疗保健:检测医学图像中的异常。
  • 机器人技术:使机器人能够与其环境中的物体交互。

物体检测技术

物体检测有多种技术,它们是−

  • 传统方法
  • 基于机器学习的方法
  • 基于深度学习的方法

传统方法

传统的物体检测方法依赖于图像处理技术和定制特征。这些方法通常不如现代基于机器学习的方法准确,但更简单、更快捷。

常用的传统方法是Haar Cascades。它使用用正片和负片训练的级联分类器来检测物体。

import cv2

# 加载预训练的 Haar Cascade 分类器进行人脸检测
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
# 读取输入图像
image = cv2.imread('image.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 检测人脸
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
# 在检测到的人脸周围绘制边界框
for (x, y, w, h) in faces:
    cv2.rectangle(image, (x, y), (x+w, y+h), (255, 0, 0), 2)
cv2.imshow('Detected Faces', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

基于机器学习的方法

基于机器学习的方法使用从数据中学习的算法来检测物体。这些方法通常涉及在标记数据集上训练分类器。

最常用的基于机器学习的方法是方向梯度直方图 (HOG) + SVM。这将提取 HOG 特征并使用支持向量机 (SVM) 对对象进行分类。

from skimage.feature import hog
from sklearn.svm import LinearSVC
import joblib

# 加载预先训练的 HOG + SVM 模型
model = joblib.load('hog_svm_model.pkl')
# 从输入图像中提取 HOG 特征
features, _ = hog(image, orientations=9, pixels_per_cell=(8, 8), cells_per_block=(2, 2), block_norm='L2-Hys', visualize=True)
# 使用经过训练的 SVM 模型预测对象的存在
prediction = model.predict([features])

基于深度学习的方法

基于深度学习的方法已经将对象检测以其高精度和处理复杂图像的能力而闻名。这些方法使用卷积神经网络(CNN)来学习特征并执行检测。

常见的基于深度学习的方法如下 −

  • R-CNN(基于区域的卷积神经网络):提出候选区域并使用 CNN 对其进行分类。
  • YOLO(你只看一次):将图像分成网格并直接预测边界框和类概率。
  • SSD(单次多框检测器):与 YOLO 类似,但使用不同的架构实现更快、更准确的检测。

YOLO(你只看一次)

YOLO 是一种流行且高效的物体检测模型。它将图像划分为网格,并预测每个网格单元的边界框和类别概率。

您可以按照以下步骤使用 YOLO −

  • 步骤 1:加载预先训练的 YOLO 模型。
  • import cv2
    import numpy as np
    
    # Load YOLO
    net = cv2.dnn.readNet('yolov3.weights', 'yolov3.cfg')
    layer_names = net.getLayerNames()
    output_layers = [layer_names[i[0] - 1] for i in net.getUnconnectedOutLayers()]
    
  • 第 2 步: 准备输入图像。
  • # 加载输入图像
    image = cv2.imread('image.jpg')
    height, width, channels = image.shape
    # 为 YOLO 准备图像
    blob = cv2.dnn.blobFromImage(image, 0.00392, (416, 416), (0, 0, 0), True, crop=False)
    net.setInput(blob)
    
  • 第 3 步: 运行模型并获取预测结果。
  • # 运行模型
    outs = net.forward(output_layers)
    
  • 第 4 步: 处理输出并绘制边界框。
  • class_ids = []
    confidences = []
    boxes = []
    
    for out in outs:
       for detection in out:
          scores = detection[5:]
          class_id = np.argmax(scores)
          confidence = scores[class_id]
          if confidence > 0.5:
             # Object detected
             center_x = int(detection[0] * width)
             center_y = int(detection[1] * height)
             w = int(detection[2] * width)
             h = int(detection[3] * height)
             # Rectangle coordinates
             x = int(center_x - w / 2)
             y = int(center_y - h / 2)
             boxes.append([x, y, w, h])
             confidences.append(float(confidence))
             class_ids.append(class_id)
    
    # 应用非最大抑制
    indexes = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.4)
    
    # 绘制边界框
    for i in range(len(boxes)):
       if i in indexes:
          x, y, w, h = boxes[i]
          label = str(class_ids[i])
          cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
          cv2.putText(image, label, (x, y + 30), cv2.FONT_HERSHEY_PLAIN, 3, (0, 255, 0), 3)
    
    cv2.imshow('Object Detection', image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()