13.3 Обнаружение объектов и ограничивающие рамки
В предыдущих разделах (например, в разделах 7.1–7.4) мы рассматривали различные модели классификации изображений. В задачах классификации мы предполагаем, что на изображении есть только один главный объект, и нас интересует лишь его класс. Однако часто на изображении есть несколько интересующих нас объектов, и нам нужно знать не только их классы, но и то, где именно они находятся. В компьютерном зрении такие задачи называют обнаружением объектов (object detection) или распознаванием объектов (object recognition).
Обнаружение объектов широко используется в разных областях. Например, в беспилотных автомобилях нужно планировать маршрут по видеоизображениям, распознавая положение автомобилей, пешеходов, дорог и препятствий. Роботы тоже часто решают эту задачу, чтобы находить интересующие их объекты. В сфере безопасности нужно обнаруживать подозрительные объекты, например оружие или взрывчатку.
В следующих разделах мы рассмотрим несколько методов глубокого обучения для обнаружения объектов. Сначала мы введём понятие положения объекта.
MXNet:
%matplotlib inline
from d2l import mxnet as d2l
from mxnet import image, npx, np
npx.set_np()
PyTorch:
%matplotlib inline
from d2l import torch as d2l
import torch
TensorFlow:
%matplotlib inline
from d2l import tensorflow as d2l
import tensorflow as tf
PaddlePaddle:
%matplotlib inline
from d2l import paddle as d2l
import warnings
warnings.filterwarnings("ignore")
import paddle
Загрузим пример изображения, которое будем использовать в этом разделе. Слева на изображении собака, справа — кошка. Это два главных объекта на этом изображении.
MXNet:
d2l.set_figsize()
img = image.imread('../img/catdog.jpg').asnumpy()
d2l.plt.imshow(img);
PyTorch, TensorFlow, PaddlePaddle:
d2l.set_figsize()
img = d2l.plt.imread('../img/catdog.jpg')
d2l.plt.imshow(img);
13.3.1 Ограничивающие рамки
В задачах обнаружения объектов положение объекта в пространстве обычно описывают ограничивающей рамкой (bounding box). Ограничивающая рамка — это прямоугольник, заданный координатами и левого верхнего и правого нижнего углов. Другой распространённый способ задать ограничивающую рамку — координаты её центра, а также ширина и высота.
Здесь мы определяем функции, которые переводят одно представление в другое: box_corner_to_center преобразует представление «два угла» в представление «центр, ширина и высота», а box_center_to_corner делает обратное. Входной параметр boxes может быть тензором длины 4 или двумерным тензором формы (, 4), где — количество ограничивающих рамок.
#@save
def box_corner_to_center(boxes):
"""Преобразование из формата (левый верхний, правый нижний) в формат (центр, ширина, высота)"""
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 = d2l.stack((cx, cy, w, h), axis=-1)
return boxes
#@save
def box_center_to_corner(boxes):
"""Преобразование из формата (центр, ширина, высота) в формат (левый верхний, правый нижний)"""
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 = d2l.stack((x1, y1, x2, y2), axis=-1)
return boxes
Зададим ограничивающие рамки собаки и кошки по координатам. Начало координат изображения находится в левом верхнем углу; ось направлена вправо, ось — вниз.
# bbox — сокращение от английского «bounding box» (ограничивающая рамка)
dog_bbox, cat_bbox = [60.0, 45.0, 378.0, 516.0], [400.0, 112.0, 655.0, 493.0]
Проверить правильность функций преобразования можно, выполнив преобразование дважды.
boxes = d2l.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):
# Преобразуем ограничивающую рамку (x левого верхнего, y левого верхнего,
# x правого нижнего, y правого нижнего) в формат matplotlib:
# ((x левого верхнего, y левого верхнего), ширина, высота)
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'));
Резюме
- Обнаружение объектов не только распознаёт все интересующие объекты на изображении, но и определяет их положение, которое обычно задаётся прямоугольной ограничивающей рамкой.
- Два распространённых представления ограничивающих рамок — (центр, ширина, высота) и (левый верхний угол, правый нижний угол) — можно переводить друг в друга.
Упражнения
- Найдите другое изображение и попробуйте разметить на нём ограничивающие рамки объектов. Что занимает больше времени: разметка ограничивающих рамок или разметка классов?
- Почему внутреннее (последнее) измерение входных параметров
box_corner_to_centerиbox_center_to_cornerвсегда равно 4?
MXNet: Обсуждение
PyTorch: Обсуждение
PaddlePaddle: Обсуждение