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. Упражнения¶
Найдите другое изображение и попробуйте проставить метку для ограничивающей рамки, содержащей объект. Сравните разметку ограничивающих рамок и категорий: что обычно занимает больше времени?
Почему внутренняя размерность аргумента ввода
boxesдляbox_corner_to_centerиbox_center_to_cornerвсегда равна 4?