.. _sec_bbox: Обнаружение объектов и ограничивающие рамки =========================================== В предыдущих разделах (например, :numref:`sec_alexnet`–:numref:`sec_googlenet`) мы рассмотрели различные модели для классификации изображений. В задачах классификации изображений предполагается, что на изображении присутствует только *один* значимый объект, и мы фокусируемся исключительно на определении его категории. Однако на изображении часто оказывается *несколько* объектов. Нам нужно не только узнать их категории, но и определить их точное местоположение на изображении. В компьютерном зрении такие задачи называют *обнаружением объектов* (или *распознаванием объектов*). Обнаружение объектов широко применяется во многих областях. Например, в системах автономного вождения необходимо планировать маршруты, определяя положение транспортных средств, пешеходов, дорог и препятствий на захваченных видеокадрах. Кроме того, роботы могут использовать эту технологию для обнаружения и локализации объектов, представляющих интерес, в процессе навигации в окружающей среде. Более того, системы безопасности могут нуждаться в обнаружении аномальных объектов, таких как нарушители или бомбы. В следующих разделах мы представим несколько методов глубокого обучения для обнаружения объектов. Мы начнем с введения в понятия *положения* (или *расположения*) объектов. .. raw:: latex \diilbookstyleinputcell .. code:: python %matplotlib inline import torch from d2l import torch as d2l Мы загрузим пример изображения, которое будет использоваться в этом разделе. На нём слева видна собака, а справа — кошка. Это два основных объекта на изображении. .. raw:: latex \diilbookstyleinputcell .. code:: python d2l.set_figsize() img = d2l.plt.imread('../img/catdog.jpg') d2l.plt.imshow(img); Границы объектов ---------------- В задачах обнаружения объектов мы обычно используем *ограничивающую рамку* для описания пространственного положения объекта. Ограничивающая рамка представляет собой прямоугольник, который определяется координатами :math:`x` и :math:`y` верхнего левого угла, а также аналогичными координатами нижнего правого угла. Другим распространённым способом представления ограничивающей рамки является указание координат центра рамки по осям :math:`(x, y)`, а также её ширины и высоты. Здесь мы определяем функции для преобразования между этими двумя представлениями: ``box_corner_to_center`` преобразует из представления по двум углам в представление с центром, шириной и высотой, а ``box_center_to_corner`` — наоборот. Входной аргумент ``boxes`` должен быть двумерным тензором формы (:math:`n`, 4), где :math:`n` — количество ограничивающих рамок. .. raw:: latex \diilbookstyleinputcell .. code:: python #@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 Мы определим ограничивающие рамки для собаки и кошки на изображении на основе координатной информации. Начало координат на изображении находится в его верхнем левом углу, а положительными направлениями для осей :math:`x` и :math:`y` являются направления вправо и вниз соответственно. .. raw:: latex \diilbookstyleinputcell .. code:: python # 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] Мы можем проверить корректность двух функций преобразования ограничивающих рамок, выполнив преобразование дважды. .. raw:: latex \diilbookstyleinputcell .. code:: python boxes = torch.tensor((dog_bbox, cat_bbox)) box_center_to_corner(box_corner_to_center(boxes)) == boxes Давайте **нарисуем ограничивающие рамки на изображении**, чтобы проверить их точность. Перед этим мы определим вспомогательную функцию ``bbox_to_rect``. Она представляет ограничивающую рамку в формате пакета ``matplotlib``. .. raw:: latex \diilbookstyleinputcell .. code:: python #@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) После добавления ограничивающих рамок на изображение мы видим, что основные контуры обоих объектов в основном находятся внутри этих рамок. .. raw:: latex \diilbookstyleinputcell .. code:: python 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')); Резюме ------ - Обнаружение объектов не только распознаёт все значимые объекты на изображении, но и определяет их положение. Положение обычно задаётся прямоугольной ограничивающей рамкой. - Мы можем преобразовывать между двумя часто используемыми представлениями ограничивающих рамок. Упражнения ---------- 1. Найдите другое изображение и попробуйте проставить метку для ограничивающей рамки, содержащей объект. Сравните разметку ограничивающих рамок и категорий: что обычно занимает больше времени? 2. Почему внутренняя размерность аргумента ввода ``boxes`` для ``box_corner_to_center`` и ``box_center_to_corner`` всегда равна 4? `Обсуждения `__