Оглавление: Уроки компьютерного зрения. Оглавление / Хабр (habr.com) На предыдущем уроке я рассказал о своем пэт-проекте, связанном с компьютерным зрением. В этом уроке вы познакомились идей и наброском архитектуры этого пэт-проекта. Сегодня продолжу описывать, как я добавлял в проект новые классы и что из этого вышло.  Напомню, что идея состояла в том, чтобы написать полноценный конвейер обработки изображений, начав с простой задачи, например, распознавание номеров. В результате эксперимента выяснилось, что известная библиотека для распознавания символов tesseract плохо распознает цифры. Было принято решение написать какую-то свою распознавалку для цифр. Но сначала надо как-то найти, где эти цифры расположены на изображении.  Напомню, какие шаги были сделаны на прошлом уроке: Применить медианную фильтрацию к изображению. Провести бинаризацию. Сегодня мы пойдем чуть дальше: выделим контур и найдем на нем прямоугольник номерного знака. Для начала напишем класс, который производит выделение контура: Этот контур надо аппроксимировать, разработаем следующий класс: В качестве фильтра ссылка на функцию, которая по какому-либо критерию отберет контуры (нам нужен только прямоугольный контур). Итак, испытываем, сначала без фильтра: Смотрим, что у нас получилось: Здесь для наглядности я показал уменьшенное фото машины. Попробуем обработать полноразмерную фотографию: Итак, мы видим примерно прямоугольник (да, он кривой, но другие фигуры вообще не похожи на прямоугольник).  Теперь встает вопрос: а как нам среди всех этих линий найти наш «прямоугольник»? Для начала, давайте применим фильтр (вот он нам и понадобился), отбросив все фигуры, которые не являются четырехугольниками. Для этого, как вы заметили, в тексте программы есть такая функция: Осталось поменять вот эту строчку кода На эту: И вуаля, у нас остались только четырехугольники: Как видим, объектов осталось значительно меньше, но все еще много мусора. Отфильтруем его, убрав слишком маленькие объекты: И вот что у нас получилось: Осталось всего 5 объектов. По идее, конечно, можно применить дополнительную фильтрацию, например, исключив объекты, имеющие неправильные соотношения длины и ширины (номерной знак имеет конкретные размеры по ГОСТ, а значит, соотношение длины и ширины у него тоже конкретные). Можно так же исключить явно «кривые прямоугольники» у которых разница в длинах противоположных сторон значительно выше уровня погрешности. Правда, при этом следует помнить, что в попытке отфильтровать ненужные объекты можно заодно и нужные до кучи выкинуть. Так что тут надо соблюдать осторожность.  Тем не менее, попробуем. Для начала напишем функцию вычисления длины сторон: И внесем изменения в фильтр: Вот что получилось: Как видим, осталось только три объекта. Один из них, кстати, можно отфильтровать на расхождение с прямыми углами (если угол сильно отклоняется от 90 градусов). Но мы пока этого делать не будем, положим, что один лишний объект – не критично.  Визуализируем найденные номера. Для этого надо извлечь из контура точки. Вот как будет выглядеть извлечение из контура двух противоположных точек первого элемента: И вот что в итоге будет нарисовано: Разумеется, так делать не надо. А надо, ну, хотя бы написать функцию, которая бы извлекала эти точки: И тогда мы можем нарисовать первую фигуру вот так: А все фигуры вот так: И вот что получится: То есть, теперь нам надо проанализировать только эти три области, поискать там буковки и циферки. Но сначала хотелось бы навести порядок в коде. Вот как выглядит у нас запускаемый файл run2.py: Не очень красиво, проведем некоторый рефакторинг. Добавим в папку Libraries файл Utils.py и перенесем туда функции get_rect и dist. Импортируем эти функции: Теперь запускаемый файл выглядит так: А файл утилит вот так: Теперь можно подумать о том, как «расшифровать» номер. На этом уроке я расскажу, как при помощи нейросети распознавать цифры, а распознавалку будем писать на следующем уроке.  И так, знакомитесь, его Величество Keras. Чтобы установить его под Windows, cсначала ставим TensorFlow: pip3 install tensorflow а затем и сам Keras: pip3 install Keras Ну,  и собственно, пример кода обучения нейросети на встроенном в керас стандартном датасете minst: Здесь используется сверточная нейросеть, на входе которой черно-белая картинка 28 на 28 пикселей, на выходе десятизначный вектор вероятностей, что на картинке та или иная цифра. Модель показывает точность порядка 99% на тестовой выборке.  Если вы не верите, что в mnist действительно цифры, это можно проверить, визуализировав какой-нибудь элемент датасета: Для элемента номер нуль мы увидим цифру 5: И этому элементу действительно соответствует лэйбл 5: Попробуем скормить какое-нибудь изображение обученной нейросети. Кстати, после того, как мы нейросеть обучили, ее хорошо бы сохранить: Ну а теперь попробуем загрузить картинку с цифрой и дать нейросетке распознать ее: Вот картинка: На выходе: [[9.9990845e-01 1.4144711e-08 8.4316625e-08 3.7920216e-11 2.4454723e-06   4.7663391e-08 8.7873021e-05 4.1903621e-07 3.8488349e-08 6.0560058e-07]] Видно, в первой (то есть нулевой, счет с нуля) ячейке (соответствует цифре 0) вероятность почти 1, в остальных почти 0. Посмотрим как распознает единицу: [[5.2682775e-08 9.9998152e-01 9.0230742e-07 1.2926430e-09 9.7749239e-07   6.3665328e-07 5.2730784e-06 1.0716837e-05 2.0985880e-08 1.3917042e-11]] Как видим, и тут распознал циферку правильно. На этом все, засовывать нейросеть в проект с «красивым» кодом будем в следующий раз. Напомню, что примеры можно скачать здесь: megabax/CVContainer: It is my pet computer vision project. (github.com)  Программист