Почему распознавание изображений оказалось такой сложной задачей? Десятилетия назад, когда компьютеры стали способны обрабатывать тысячи пикселей, мы начали задаваться вопросом, можем ли мы дать компьютеру способность видеть. Обработка изображений вскоре стала большой областью. Мы изучили такие понятия, как яркость и контрастность, оттенок и насыщенность, тени и блики. Затем мы разработали детекторы границ и вскоре начали понимать, что распознавание объектов — очень сложная задача. Жесткое кодирование для декодирования понятий из данных, содержащих шум и высокую дисперсию, становится чрезвычайно утомительным. Но потом появились нейронные сети! Сверточные нейронные сети стали стандартом де-факто для классификации изображений. Нейронные сети — это аппроксиматоры кривых, или, как их называют математики, аппроксиматоры универсальных функций. Они отлично умеют обобщать. Меня, однако, немного не впечатлила гибкость, которую они предлагают. Во-первых, обучению нейронной сети должен предшествовать набор данных из сотен тысяч помеченных изображений. Когда вы обучаете CNN классифицировать метки на заданном изображении, вы просто даете компьютеру задачу, ответы на которую вы, возможно, никогда не узнаете. Вы получаете в подарок черный ящик, который принимает входные данные и дает вам выходные данные, о которых вы просили. Черный ящик также имеет ограничения с точки зрения того, сколько информации вам будет предоставлено о тестовом изображении, которое вы предоставили для классификации. Мой разум не согласился с этим методом, и поэтому я собираюсь следовать классическому подходу и найти методы распознавания объектов и понятий на изображениях без использования строгой сверточной нейронной сети.

Анализ изображения

Свойства пикселя

С точки зрения данных RGB пиксель может содержать 0-100% красного, 0-100% зеленого и 0-100% синего цветов. Пиксель в градациях серого может содержать только яркость от 0 до 100%. 100% обычно равно 255 для 8 бит на канал. Чтобы получить яркость из трех цветов для пикселя, мы усредняем три значения цвета этого пикселя.

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

Свойства изображения

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

Яркость. Яркость изображения означает, насколько далеки все пиксели изображения, рассматриваемые вместе, от черного цвета или яркости, равной 0. Когда мы увеличиваем или уменьшаем контрастность, мы просто прибавляем или вычитаем из все значения цвета всех пикселей, коэффициент яркости.

Яркостной контраст — яркостный контраст изображения — это ширина промежутка между самыми темными пикселями изображения и самыми яркими пикселями изображения. Для увеличения контраста мы увеличиваем яркость самых светлых пикселей и уменьшаем яркость самых темных пикселей, и наоборот для уменьшения.

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

Шаблоны функций

Подумайте об этом, каким бы ярким или контрастным ни было изображение, предметы внутри него все равно будут узнаваемы. Это означает, что значения пикселей меняются, но что-то остается неизменным — пространственное распределение пикселей. Это просачивается от полного представления изображения к крошечной части изображения. Тот факт, что пиксели, показывающие ботинок, лежат ниже пикселей, показывающих ногу, достаточен для того, чтобы мы могли распознать, что это нога человека. Но как вы узнали, что это человеческая обувь? Это произошло потому, что пиксели в разных областях обуви находились в определенном пространственном расположении. Шнурки были посередине, подошва внизу, а текстура обуви по бокам.

Здесь важно то, что элемент шаблона более высокого уровня состоит из множества элементов шаблона более низкого уровня. Конечно, вы можете анализировать столько раз, что наступит момент, когда функции исчезнут в пиксельные изображения, которые не имеют смысла.

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

Размерность

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

Как мы создаем стог сена из двухмерного расположения функций?

Концепции

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

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

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

Обнаружение объектов с низким разрешением путем обучения на объектах с высоким разрешением — это то, как можно подобрать велосипед, показанный на расстоянии на тестовом изображении.

Теория общих черт

Причина, по которой два объекта обозначаются одним и тем же ярлыком, заключается в том, что у них есть что-то общее. Добыча этих общих черт может стать нашей тренировкой. Часто объект, такой как автобус, имеет множество подтипов, таких как красный автобус, школьный автобус, новый автобус, старый автобус, двухэтажный автобус, одноэтажный автобус и т. д. Все эти категории также имеют свои общие черты. Общие черты между несколькими школьными автобусами по-прежнему имеют общие черты всех автобусов, однако они будут иметь дополнительные общие черты, состоящие из сходных характеристик школьных автобусов. Следовательно, каждая категория должна содержать и ее подкатегории. Каждая категория и подкатегория будут хранить только общие черты на этом уровне. Автобусы будут содержать большинство основных общих черт, но по мере того, как мы будем более конкретными, общие черты между родительской категорией будут дополнять общие черты дочерней категории.

Программирование

Кодирование функций

Функции должны быть захвачены математически, кэшированы и сохранены для сравнения. Давайте обозначим каждую уникальную функцию как вектор. Направление вектора покажет направление изменения, а величина вектора покажет, насколько сильно произошло изменение.

Вектор каждого PPP (количество пикселей на [супер] пиксель) можно вычислить с помощью матричной арифметики.

После некоторых экспериментов мы обнаружили, что градиент можно получить, используя метод численного дифференцирования. Градиент обеспечивает направление для каждой точки в PPP. Затем мы отдельно берем среднее значение dXs и dYs и, наконец, вычисляем угловую составляющую вектора, используя ArcTan(Avg dy/avg dx). Величина задается как dX+dY в этот момент, так как более высокие dX и dY означают более высокий непрерывный контраст в PPP.

Таким образом, в расширении мы ограничиваем количество возможных функций до 180 * 100 = 18000 минус ограничения, накладываемые ограниченным размером PPP. Это не слишком много для компьютера, чтобы хранить в оперативной памяти. Мы можем отдельно хранить средний цвет каждого PPP для различения цветов. Цвета также можно округлить до сотых, чтобы сэкономить память.

Для этого вычислите среднее значение изображения, для каждого PPP вычислите среднее значение и посмотрите, какие области PPP попадают в белый цвет, а какие в черный. Это даст нам направление вектора. Величина этого вектора будет средним значением этого ППС.

После извлечения векторов изображение будет выглядеть примерно так:

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

Выбор ключа для вектора:
направление в градусах с округлением + величина с округлением до первого десятичного знака

Кодирование пространственного распределения

Есть способ закодировать 2-мерную связь в 1-мерную строку: упомянув каждую единицу изменения направления уникальным символом.

Поскольку мы хотим закодировать двумерные числа, мы можем использовать n, e, w, s, a, b, c и d для обозначения севера, востока, запада, юга, северо-востока, северо-запада, юго-востока, юго-запад соответственно.

Следовательно, случайная трассировка строки из приведенной ниже матрицы
[
15, 20, 3
2, 15, 18
19, 4, 45]
можно представить как 15s2w15s4.

В ходе экспериментов было замечено, что сохранение кодировки пространственного распределения для каждой пары ключей возрастающей длины требует большого объема памяти. Следовательно, вместо этого мы можем сохранить 15s2w15s4 как 15.s.2.w.15.s.4 в объектном формате, где 15.s.3.xy будет помещено внутри 15.s.

Структура данных может быть следующей:
a{{}=class_names, lastDir:’’, D.b{{}=class_names, lastDir:’’, D.e{{}=class_names, D.f{…}}}}

Возможные лазейки этого типа пространственного кодирования:
Если мы сохраним приведенный выше пример пространственного кодирования 15.s.2.w.15.s.4 как есть, когда тестовое изображение показано, мы хотим, чтобы система соответствовала 15.s.2.w.15.s.4, а также только 2.w.15.s.4. Поэтому мы будем хранить каждый вектор как дочерний по отношению к предыдущему вектору.

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

Хранение сопоставления объектов с классами

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

Неконтролируемое обучение

Очевидно, что по мере того, как система видит все больше и больше изображений, некоторые функции начинают повторяться. Повторяющиеся признаки кэшируются как общие черты. Тот факт, что некоторые черты повторяются, означает, что эти изображения имеют что-то общее. Этой мудрости можно научиться, не навешивая ярлыков. Ярлыки — это когда общим чертам дается имя.

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

Тестирование

Наконец, процедура тестирования должна взять входное изображение, получить все его векторы, пройтись по x и y и посмотреть, имеет ли запись в x и y ключ, установленный в обученной памяти. Если да, посмотрите, добавлен ли какой-либо из его соседей в качестве дочернего элемента текущего сопоставленного объекта кэша. Повторите этот процесс для всех X и Y.

Подсчет очков

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