Распознавание номеров автомобилей

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

В своей работе по изготовлению номеров для автотранспорта я постоянно сталкиваюсь с вопросами как уберечь свой автомобиль от всевидящего ока камер наблюдения ГИБДД.

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

 

Каких только догм и предположений не порождает мысль отечественного автолюбителя. Например некоторые абсолютно уверенны что отсутствие черной рамки по краям номерного знака легко сбивает камеры с толку или перевёрнутые номера вообще не читаются глупым железом. Некоторые способы защиты номера от камер видеофиксации ГИБДД мы уже рассматривали в этой статье.
 

 

Алгоритм распознавания номеров применим не только на дорогах, общий подход это так называемый "механизм распознавания лиц" или необходимых элементов разрабатывается давно и весьма успешно.

Рассмотрим логику таких систем.
Оператор программы задает изображения предмета (-ов) в нескольких ракурсах и т.п. потом при появлении этого или максимально похожего изображения предмета, программа совершает требуемое/заданное действие

В любых задачах обработки изображений 90% успеха — хорошая база данных.
Репрезентативная и большая. База вырезанных номеров + контрпримеров (260 МБ). Примерно 5000 номеров + 1200 контрпримеров.
Выглядят картинки так:


База нарезанных символов для российских номеров (60 МБ).
Примерно 18 тысяч букв, цифр и контрпримеров. *Маленькое дополнение. Папка «17» — пустая. В ней были буквы «O», но классификаторы не делали различия от неё и нуля, поэтому они объединены в папке «0».
Выглядят картинки так:


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


 
//Набор входных изображений, развёрнутых в одномерные массивы
double[][] inputs;
//Набор ответов чем являются входные изображения
int[] outputs;
//"Размазанность" гауссианы при обучении. Чем ниже значение, тем больше "обобщения" делает SVM
double sigma = 12;
//Количество классов при обучении. В номерах 10 цифр, 12 букв, + 1 класс с отрицательной выборкой
int classCount=23;
MulticlassSupportVectorLearning teacher = null;
//Параметры распознающей машины: длина массива на каждую фотографию, параметр ядра обучения, количество классов
//sigma - единственный настраиваемый параметр обучения. Я ставил где-то 10-20, изменялась точность незначительно.
machine = new MulticlassSupportVectorMachine(width*height, new Gaussian(sigma), classCount);
//Инициализация обучения
teacher = new MulticlassSupportVectorLearning(machine, inputs, outputs);
teacher.Algorithm = (svm, classInputs, classOutputs, i, j) => new SequentialMinimalOptimization(svm, classInputs, classOutputs) { CacheSize = 0 };
teacher.Run();
machine.Save("MachineForSymbol");

 

Алгоритм распознавания номеров который заключается в получении текстового представления на заранее подготовленном изображении, содержащем рамку с номером + небольшие отступы для удобства распознавания. Для выделения областей, где содержатся номера, использовался метод Виолы-Джонса. Это позволило создать быстрый алгоритм поиска объектов, который пользуется успехом уже больше десятилетия.
Используется набор слабых классификаторов, на основе которых выносится решение о том, находится объект на изображении или нет.

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

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