14.3. Обнаружение объектов и ограничивающие рамки

В предыдущих разделах (например, Section 8.1–Section 8.4) мы рассмотрели различные модели для классификации изображений. В задачах классификации изображений предполагается, что на изображении присутствует только один значимый объект, и мы фокусируемся исключительно на определении его категории. Однако на изображении часто оказывается несколько объектов. Нам нужно не только узнать их категории, но и определить их точное местоположение на изображении. В компьютерном зрении такие задачи называют обнаружением объектов (или распознаванием объектов).

Обнаружение объектов широко применяется во многих областях. Например, в системах автономного вождения необходимо планировать маршруты, определяя положение транспортных средств, пешеходов, дорог и препятствий на захваченных видеокадрах. Кроме того, роботы могут использовать эту технологию для обнаружения и локализации объектов, представляющих интерес, в процессе навигации в окружающей среде. Более того, системы безопасности могут нуждаться в обнаружении аномальных объектов, таких как нарушители или бомбы.

В следующих разделах мы представим несколько методов глубокого обучения для обнаружения объектов. Мы начнем с введения в понятия положения (или расположения) объектов.

%matplotlib inline
import torch
from d2l import torch as d2l

Мы загрузим пример изображения, которое будет использоваться в этом разделе. На нём слева видна собака, а справа — кошка. Это два основных объекта на изображении.

d2l.set_figsize()
img = d2l.plt.imread('../img/catdog.jpg')
d2l.plt.imshow(img);

14.3.1. Границы объектов

В задачах обнаружения объектов мы обычно используем ограничивающую рамку для описания пространственного положения объекта. Ограничивающая рамка представляет собой прямоугольник, который определяется координатами \(x\) и \(y\) верхнего левого угла, а также аналогичными координатами нижнего правого угла. Другим распространённым способом представления ограничивающей рамки является указание координат центра рамки по осям \((x, y)\), а также её ширины и высоты.

Здесь мы определяем функции для преобразования между этими двумя представлениями: box_corner_to_center преобразует из представления по двум углам в представление с центром, шириной и высотой, а box_center_to_corner — наоборот. Входной аргумент boxes должен быть двумерным тензором формы (\(n\), 4), где \(n\) — количество ограничивающих рамок.

#@save
def box_corner_to_center(boxes):
    """Convert from (upper-left, lower-right) to (center, width, height)."""
    x1, y1, x2, y2 = boxes[:, 0], boxes[:, 1], boxes[:, 2], boxes[:, 3]
    cx = (x1 + x2) / 2
    cy = (y1 + y2) / 2
    w = x2 - x1
    h = y2 - y1
    boxes = torch.stack((cx, cy, w, h), axis=-1)
    return boxes

#@save
def box_center_to_corner(boxes):
    """Convert from (center, width, height) to (upper-left, lower-right)."""
    cx, cy, w, h = boxes[:, 0], boxes[:, 1], boxes[:, 2], boxes[:, 3]
    x1 = cx - 0.5 * w
    y1 = cy - 0.5 * h
    x2 = cx + 0.5 * w
    y2 = cy + 0.5 * h
    boxes = torch.stack((x1, y1, x2, y2), axis=-1)
    return boxes

Мы определим ограничивающие рамки для собаки и кошки на изображении на основе координатной информации. Начало координат на изображении находится в его верхнем левом углу, а положительными направлениями для осей \(x\) и \(y\) являются направления вправо и вниз соответственно.

# Here `bbox` is the abbreviation for bounding box
dog_bbox, cat_bbox = [60.0, 45.0, 378.0, 516.0], [400.0, 112.0, 655.0, 493.0]

Мы можем проверить корректность двух функций преобразования ограничивающих рамок, выполнив преобразование дважды.

boxes = torch.tensor((dog_bbox, cat_bbox))
box_center_to_corner(box_corner_to_center(boxes)) == boxes

Давайте нарисуем ограничивающие рамки на изображении, чтобы проверить их точность. Перед этим мы определим вспомогательную функцию bbox_to_rect. Она представляет ограничивающую рамку в формате пакета matplotlib.

#@save
def bbox_to_rect(bbox, color):
    """Convert bounding box to matplotlib format."""
    # Convert the bounding box (upper-left x, upper-left y, lower-right x,
    # lower-right y) format to the matplotlib format: ((upper-left x,
    # upper-left y), width, height)
    return d2l.plt.Rectangle(
        xy=(bbox[0], bbox[1]), width=bbox[2]-bbox[0], height=bbox[3]-bbox[1],
        fill=False, edgecolor=color, linewidth=2)

После добавления ограничивающих рамок на изображение мы видим, что основные контуры обоих объектов в основном находятся внутри этих рамок.

fig = d2l.plt.imshow(img)
fig.axes.add_patch(bbox_to_rect(dog_bbox, 'blue'))
fig.axes.add_patch(bbox_to_rect(cat_bbox, 'red'));

14.3.2. Резюме

  • Обнаружение объектов не только распознаёт все значимые объекты на изображении, но и определяет их положение. Положение обычно задаётся прямоугольной ограничивающей рамкой.

  • Мы можем преобразовывать между двумя часто используемыми представлениями ограничивающих рамок.

14.3.3. Упражнения

  1. Найдите другое изображение и попробуйте проставить метку для ограничивающей рамки, содержащей объект. Сравните разметку ограничивающих рамок и категорий: что обычно занимает больше времени?

  2. Почему внутренняя размерность аргумента ввода boxes для box_corner_to_center и box_center_to_corner всегда равна 4?

Обсуждения