![](https://habrastorage.org/files/e83/8fa/75d/e838fa75d03d4c52ba3f3ad37945d42f.jpg)
Есть одна тема в современном Computer Vision, которая часто остаётся за кадром. В ней нет сложной математики и глубокой логики. Но то что её никак не освещают — вгоняет в ступор многих новичков. А тема не проста: имеет множество граблей, про которые не узнаешь, пока не наступишь.
Тема — называется так: подготовка базы изображений для дальнейшего обучения.
В статье:
- Как можно отличить хорошую базу
- Примеры хороших баз
- Примеры программ, которыми удобно размечать базы
NB!
Если что, статья 2016 года. Сейчас как минимум 2021. И тема DataArchitect с тех пор стала куда популярнее, на ней стало куда больше подвязано. Вот несколько моих более новых видео на эту тему: 1,2. Вот примеры статей моих более новых: 1, 2.
А в целом, — советую читать мой канал (vk, telegram) про более новые методы/подходы. Статьи с Хабра свои я там тоже аноншу.
Для начала покажу простой и наиболее любимый свой пример: распознавание автомобильных номеров. Предположим мы делаем систему с нуля. Что мы должны обозначить на этом изображении:
![](https://habrastorage.org/files/648/5b3/0ce/6485b30ce3404a21989169bbbeee02ce.jpg)
Идеальный вариант, на мой взгляд, такой:
![](https://habrastorage.org/files/70e/bb1/540/70ebb15406e54146bee631eb35c9cef5.jpg)
Тут отмечено:
- Рамка для каждого номера, которую видно. Ключевой момент: нужно подчеркнуть угол наклона номера + его положение.
- Значение каждого номера, который виден. Система не будет распознавать лучше, чем человек, который смотрит на фотографию, так что номера, которые практически нельзя разглядеть можно не обозначать.
- Положение каждого символа номера.
Ещё раз: это идеальная разметка. Возможно, она несколько избыточна, но зато на её базе можно настраивать/обучать практически любой алгоритм. Сам я никогда не делал настолько подробную разметку ни в одной задаче, которую решал. Обычно находиться идеальный баланс между тем, что хочется и тем на что есть силы.
Теперь рассмотрим откуда это берётся. И почему этого достаточно. Классический алгоритм выделения номера выглядит следующим образом:
![](https://habrastorage.org/files/90a/2ee/08a/90a2ee08a67e4b42a5ed46695eb47881.jpg)
При этом за каждую часть обычно отвечает свой алгоритм или их группа.
Первая часть — нам нужно найти номера. Предположим, что выделение номера мы реализуем через каскад Хаара, или через HOG дескрипторы. Тогда на вход алгоритма обучения нам нужно будет подать набор положительных и отрицательных примеров:
Положительные:
![](https://habrastorage.org/files/b69/dc6/6cd/b69dc66cd7634fe8ab392907ac1b6c00.jpg)
Отрицательные:
![](https://habrastorage.org/files/afa/979/657/afa979657d574e6190128fa2e1f167a4.jpg)
Если же мы реализуем поиск номера через какую-нибудь нейронную сеть, то целью обучения сети будет такой набор прямоугольников:
![](https://habrastorage.org/files/fe2/6b3/554/fe26b35547674c0e90ae134996edbb76.jpg)
Как видно, из данных, которые мы разметили просто получить оба варианта.
После того как номер найден его нужно обработать. Опять же, тут есть много подходов. Но в целом, вторая часть — это «нормировка номера». Можно сделать алгоритм, ищущий границы в ручную, как описано тут:
![](https://habrastorage.org/getpro/habr/post_images/ffc/e90/5cf/ffce905cffc52ed27086d42c74e38d9f.png)
Этот алгоритм не требует обучения, но по тем данным которые у нас есть мы сможем оценить его качество работы.
А можно обучить несколько нейронных сетей. Например первая ищет угол, вторая ищет кроп.
И опять. Данных, которые мы разметили — полностью хватает.
Можно объединить часть один и часть два и сделать поисковую сеть для номеров, которая сразу выводит и угол и поворот номера. Для неё данных тоже достаточно.
Принципы
Попробуем сформулировать основные принципы разметки:
1. Заранее обдумайте все возможные алгоритмы, которыми может решаться ваша задача. Определите входные данные для каждого из вариантов. Если это не требует большого количества сил при разметке, придумайте такой формат разметки, который бы обеспечил вам любой из существующих вариантов решения задачи входными данными. Если есть возможность, то лучше, чтобы разметка была избыточна. Иначе, если ваш алгоритм не заработает, придётся делать всё заново.
2. Старайтесь, чтобы разметка была в простом, верифицируемом формате. Помните, что любые задачи компьютерного зрения — достаточно сложны в отладке и в поиске багов. Любая часть должна быть просто визуализируема и проста для проверки глазами. Отдавайте предпочтения текстовым форматам данных или графическим. Старайтесь избегать бинарных форматов, или форматов с большим объёмом метаданных. Старайтесь писать всю возможную информацию. Например не забывайте текстовое название изображения. Если вы используете какую-то функцию «получить список названий файлов» помните, что в Windows, Linux, C#, Python порядок этих файлов может различаться.
3. Помните, что разметка — это длительный процесс. Зачастую разметка большой базы может занимать дни или недели. Монотонного труда. Старайтесь предусмотреть в вашей программе всё что понадобиться.
Примеры баз данных
MSRA dataset. MSRA — это целая серия датасетов. Возьмём для примера датасет с детектированием объектов. Для каждой картинки задан ограничивающий прямоугольник объекта на этой картинке:
![](https://habrastorage.org/files/a4b/193/8e5/a4b1938e54b94096b9df934bfef7018b.jpg)
При этом все параметры лежат в текстовом файле такого вида:
235 - число описанных изображений в файле
0\0_101.jpg - адрес картинки
400 300 - её размер
89 10 371 252; 87 9 379 279; 89 11 376 275; - ограничивающий прямоугольник объекта
0\0_108.jpg
400 300
112 4 241 214; 119 0 241 208; 118 0 238 141;
.....
При этом каждый текстовый файл описывает все объекты одного из классов.
VOC2012 Один из наиболее полных датасетов. Делался в исследовательских целях => старались описать всё хорошо и качественно. До 2012 года датасет обновлялся каждый год (2005-2012). Формат описания: xml.
На каждом изображении отмечаются прямоугольники всех объектов:
![](https://habrastorage.org/files/f19/155/20e/f1915520e9cc484b9f8eb044a129a35d.jpg)
![](https://habrastorage.org/files/59e/00a/67d/59e00a67d2e645189ad6ef3aa00c48fd.jpg)
При этом пишутся все данные:
<annotation>
<folder>VOC2007</folder>
<filename>000019.jpg</filename>
<source>
<database>The VOC2007 Database</database>
<annotation>PASCAL VOC2007</annotation>
<image>flickr</image>
<flickrid><owner>
<flickrid>Rosenberg1 Simmo</flickrid>
<name>?</name>
</owner>330638158</flickrid>
<source>
<size>
<width>500</width>
<height>375</height>
<depth>3</depth>
</size>
<segmented>0</segmented>
<object>
<name>cat</name>
<pose>Right</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>231</xmin>
<ymin>88</ymin>
<xmax>483</xmax>
<ymax>256</ymax>
</bndbox>
</object>
<object>
<name>cat</name>
<pose>Right</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>11</xmin>
<ymin>113</ymin>
<xmax>266</xmax>
<ymax>259</ymax>
</bndbox>
</object>
</annotation>
Так же, часть изображений в VOC раскрашены принадлежностью к классу. Задача сегментации (например) требует входных изображений, на которых были бы размечены интересные области. Обычно тип объекта задают цветом:
![](https://habrastorage.org/files/58a/d24/a0c/58ad24a0ccd84088b119335ad537a76e.png)
![](https://habrastorage.org/files/294/90b/c5a/29490bc5a22b4f8ab919fdb3cec547d8.png)
В данном случае разметка — это по сути раскраска.
CIFAR Исследовательский датасет с небольшими изображениями. Пример неудобного датасета. Все картинки лежат в одном большом файле. Там же и их описания. Для доступа к файлу есть обёртки под Питон и под Матлаб. Описание картинки — номер класса. Больше ничего в датасете нет. Когда-то датасет был популярным. Но был неудачным по формату проектирования. Сейчас его редко кто использует.
The Street View House Numbers (SVHN) Dataset Известный датасет с номерами домов от гугла.
![](https://habrastorage.org/files/6aa/d78/6ac/6aad786acbf043f2861f3264a344475d.jpg)
Формат описания — бинарный матлабовский файл для каждого изображения. В файле — прямоугольник ограничивающий цифру и значение цифры.
MS COCO Датасет от Майкрософта. Наверное один из лучших на сегодняшний день. По составу — примерно как VOC, но больше данных, сильно больше информации о разметке.
![](https://habrastorage.org/files/31f/1a1/55e/31f1a155ec5544e29f6b315ff4c071ca.png)
![](https://habrastorage.org/files/aaa/a60/9c7/aaaa609c7df74aae98619fadc9c70a8d.png)
Информация храниться в сопроводительных json-файлах. Вот пример как аннотируется:
annotation{
"id" : int,
"image_id" : int,
"category_id" : int,
"segmentation" : RLE or [polygon],
"area" : float,
"bbox" : [x,y,width,height],
"iscrowd" : 0 or 1,
}
categories[{
"id" : int,
"name" : str,
"supercategory" : str,
}]
Один из интересных моментов датасета. Области сегментации задаются не картинкой, их заливающей, а замкнутым полилайном, который храниться в том же json-файле. Это значительно уменьшает объем данных. Хотя и ухудшает качество разметки.
Второй момент — для каждой из картинок есть текстовое описание происходящего.
The Citycapes Dataset Набор датасетов для чисто сегментационной задачи: разметить всё происходящее на улицах. Для каждой картинки вторая картинка с разметкой. В отдельном файле описание что значит каждый цвет.
![](https://habrastorage.org/files/c1d/49b/19e/c1d49b19e3c745bc9239ae2fa65fd092.jpg)
kaggle На каггле много датасетов и они всегда разные под разные задачки. Это пример того, как надо делать датасеты. Все датасеты максимально просты. Есть 10 классов? Вот они лежат по папочкам без лишних текстовиков. Нужно что-то обнаружить? Вот сегментационная разметка.
IMAGENET Огромный, но безблагодатный датасет. Если честно, так и не смог окончательно разобраться в всех доступных для него описаниях. Большинство описаний в mat-файлах. Задача распознавания требует классификации изображённых данных. Так что создатели решили давать полную классификацию каждому изображению:
![](https://habrastorage.org/files/225/d79/969/225d799699ce4043b93ac2c3e895e84e.jpg)
animals → chordate → vertrbrate,craniate → bird → parrot → African grey. — формат описания изображений.
Набор датасетов по точкам лица. Форматы описания разнятся, но в большинстве случаев даны просто текстовые значения координат для всех точек на лице:
![](https://habrastorage.org/files/2ec/48e/3ba/2ec48e3bac8946eabe61070fcf45bcbf.png)
http://www.absolutely.net/wenn/handy_manny_05_wenn5360250.jpg worker_2 205.056122449 274.885204082 0 409.147959184 276.691326531 0 287.535714286 291.441326531 0 336.903061224 295.956632653 0 249.306122449 268.864795918 0 249.005102041 281.507653061 0 371.821428571 274.283163265 0 373.928571429 282.410714286 0 227.734693878 307.787755102 0 388.840816327 304.416326531 0 273.489795918 309.473469388 0 340.195918367 309.714285714 0 250.371428571 298.636734694 0 252.779591837 314.771428571 0 362.168 296.06 0 365.72244898 312.844897959 0 252.297959184 305.13877551 0 363.073469388 301.526530612 0 275.655102041 378.605612245 0 352.23877551 377.945408163 0 327.151020408 376.625 0 315.92755102 393.790306122 0 244.620408163 413.645918367 0 359.391836735 417.219387755 0 311.255102041 419.11122449 0 310.204081633 424.996938776 0 308.102040816 438.239795918 0 311.044897959 453.794897959 0 118.526530612 259.768877551 0 446.133 275.046 0 145.594897959 364.081122449 0 438.369 380.507 0 142.954081633 321.828061224 0 435.781 330.688 0 317.351020408 518.537755102 0
Набор биометрических датасетов от CASIA. Тут всё замечательно просто. Датасеты для алгоритмов биометрии. Для каждого человека отдельная папочка, внутри которой всё разложено как по нотам: разные спектры, множество подходов.
KITTI Набор самых разных датасетов снятых с автомобиля. Для каждой картинки свой собственный текстовичёк с описанием:
Pedestrian 0.00 1 1.43 694.62 175.43 703.96 201.82 1.74 0.75 0.64 5.98 1.92 48.22 1.55
Van 0.00 1 2.15 68.34 174.12 189.52 222.12 1.94 1.88 5.30 -21.22 2.03 32.10 1.57
Misc 0.00 1 2.06 184.58 181.15 230.79 211.99 1.54 0.85 2.84 -20.97 1.97 37.62 1.56
Car 0.00 0 2.01 221.83 183.54 302.47 223.76 1.48 1.61 3.39 -13.87 1.93 28.89 1.56
Car 0.00 1 2.07 168.24 186.13 265.38 223.54 1.44 1.79 4.32 -16.76 2.04 30.95 1.58
Описание — пример хорошего датасета. Тут задано всё: насколько объект перекрыт, границы объекта. Насколько объект повёрнут к камере, какие реальные координаты объекта по глубине. Но, как я понимаю, большинство исследователей пользуются только координатами рамки объекта.
Кроме изображений с разметкой прямоугольников в датасете есть много интересной информации. Тут есть стереопары для дорожной обстановки.
Есть оптический поток для каждого кадра, который в каждой точке задаёт цвет, кодирующий направление и скорость движения (1), (2):
![](https://habrastorage.org/files/ef5/9f9/a58/ef59f9a58101489d9516ab10855ee9fa.jpg)
В этом датасете много интересно и правильно заданной информации.
Существует огромное множество датасетов которые я здесь не упомянул. Главное, что их объединяет: если датасет серьёзный — он хорошо сделан. С ним удобно работать. Когда будете делать датасеты под свои задачи — не забывайте об этом.
Удобство оператора
Даже если базу размечаете не вы — не забывайте об удобстве оператора, который будет размечать. Удобство оператора = скорость работы + качество разметки. Вот несколько советов:
• Старайтесь дублировать все возможные операции на клавиатуре. Оставляйте на мышь только операции выделения объектов на изображении. Это повышает скорость работы в разы.
• Постоянно сохраняйте работу. Не держите её в памяти программы. Так как программы разметки часто пишутся на коленке — вылеты возможны. Обидно потерять 5000 размеченных изображений.
• Сделайте возможность редактирования размеченных данных. Ошибок не избежать.
• Не давайте оператору лишних инструментов. Всё должно быть просто, все углы должны быть срезаны. У вас 3 типа объектов? Не надо давать оператору программу где можно разметить 10 типов. Ваш девиз — «только необходимость и достаточность».
Пара примеров
Я привожу тут несколько примеров, которые я использовал в разных задачах. Написаны на C# + с подключением EmguCV для работы с изображениями (знаю, что избыточно, но так было проще).
В репозитории 2 программы — одна для раскраски изображений под задачи сегментации, вторая для рисования прямоугольников. Ничего сверхъестественного, но может кому-то понадобятся.
Прочее
Мне понравился сервис Яндекса — Толока. Частично он может решить вопросы разметки базы. Но, нужно сказать, что сильно не всё из описанного в нём есть.
Чуть ниже в комментариях vfdev-5 говорит, что для разметки неплохо ещё вот это приложение подходит.