Выбрано из Medium Владимира Гончарова, составлено Heart of the Machine.
Автор Владимир Гончаров обычно фокусируется на двух темах: PHP и администрировании серверов. В течение последних шести месяцев автор использовал свое свободное время для изучения комбинации PHP и OpenCV, а также для вызова и обучения отличных моделей машинного обучения. В этой статье рассказывается, как с практической точки зрения использовать PHP и OpenCV для создания таких систем, как обнаружение лиц, распознавание лиц, сверхвысокое разрешение и обнаружение целей.Поэтому поклонники PHP могут использовать OpenCV для изучения компьютерного зрения.
Как и многие разработчики, я часто использую работу других людей (статьи на среднем, код на Github и т. Д.), Так что я рад поделиться своей работой с сообществом. Не только пишет награду за общину, это позволяет вам найти единомышленников, наставлять профессионалы в узком поле, а дальше ваше понимание области обучения.
На самом деле эта статья о одной из тех моментов. В этой статье я рассказываю почти все мое свободное время за последние шесть месяцев, за исключением времени, когда я потратил на просмотр телешоу и играл в игры.
«Машинное обучение» в наши дни стремительно развивается, и статей о нем множество, в том числе и на Medium, и почти каждый разработчик начинает использовать машинное обучение для рабочих задач и локальных проектов, но с чего начать и что использовать Методы всегда путают. Большинство статей для новичков содержат кучу литературы, и, читая, я обнаруживаю, что эти статьи не из жизни, либо предоставляют какие-то «ценовые» курсы и т. д.
Новые подходы к решению конкретных задач часто описываются в недавно опубликованных статьях, а реализации методов можно найти в статьях на GitHub. Так как чаще всего используются языки программирования: C/C++, Python 2/3, Lua и Matlab, а фреймворки: Caffe, TensorFlow, Torch. Так что огромный выбор языков программирования и фреймворков усложняет процесс поиска того, что вам нужно, и интеграции в ваш проект.
Модуль DNN, добавленный в OpenCV, уменьшает эту путаницу таким образом, что позволяет напрямую использовать модель, обученную в базовой структуре. Я покажу вам, как использовать этот модуль в PHP.
Модуль ДНС:GitHub.com/OpenCV/открыть…
Джереми Ховард (Создатель свободных рук на курсе «Машина обучения для кодировщиков») считает, что существует большая линия между учебной машиной и практическим приложением сегодня.
Ховард считает, что года опыта программирования достаточно, чтобы начать изучать машинное обучение. Я полностью с ним согласен, и я надеюсь, что моя статья поможет снизить входной барьер для PHP-разработчиков, которые плохо знакомы с машинным обучением и не уверены, хотят ли они заниматься машинным обучением, и я попытаюсь объяснить, что я потратил Много времени Время получает точку зрения, так что вам даже не нужно много времени, чтобы понять ее.
Я думал о написании модуля php-opencv с помощью SWIG и потратил на это много времени, но не получил никаких результатов. Все сложно, потому что я не знаю C/C++ и не писал файл расширения для PHP 7. К сожалению, большая часть материала в сети представляет собой расширение PHP на основе PHP 5, поэтому мне пришлось собрать немного информации и разобраться самому.
Затем я нашел на GitHub библиотеку php-opencv, которая представляет собой модуль PHP 7 для вызова методов OpenCV. Я провел несколько ночей, компилируя, устанавливая и запуская примеры. Я начал экспериментировать с разными возможностями этого модуля, но в библиотеке все равно не хватало некоторых методов, поэтому я добавил их сам и создал пулл-реквест, а автор библиотеки их принял. После этого я добавил больше функций.
php-opencv:GitHub.com/Hi Oh Week/Сотрудничество…
Вот как изображение нагрузки:
$image = cv\imread(“images/faces.jpg”);
Напротив, изображение, загруженное в python, таково, что:
image = cv2.imread(“images/faces.jpg”)
При чтении изображения в PHP (и в C++) информация сохраняется в объекте Mat (матрице). В PHP, похожем на многомерный массив, но отличном от него, объект может выполнять несколько быстрых операций, таких как одновременное деление всех элементов на число. В Python при загрузке изображения возвращается объект «NumPy».
Будьте осторожны с исходным действием по умолчанию! Бывает, что imread (в php, c++ и python) загружает изображение не в RGB, а в BGR. Так, в примерах OpenCV часто можно увидеть процесс преобразования BGR в RGB и наоборот.
Распознавание лиц
Первое, что я попробовал, это эта функция. Для этого в OpenCV есть класс CascadeClassifier, который умеет загружать предварительно обученные модели в формате xml. Прежде чем найти лицо, класс рекомендует преобразовать изображение в черно-белый формат.
$src = imread(“images/faces.jpg”);
$gray = cvtColor($src, COLOR_BGR2GRAY);
$faceClassifier = new CascadeClassifier();
$faceClassifier->load(‘models/lbpcascades/lbpcascade_frontalface.xml’);
$faceClassifier->detectMultiScale($gray, $faces);
Полный тестовый пример кода:GitHub.com/PHP-OpenCV/…
результат:
Как видно из этого примера, человеческое лицо можно найти даже на фото в гриме зомби. Характерные точки не мешают локализации лица.
распознавание лица
Для распознавания лиц в OpenCV есть класс LBPHFaceRecognizer и методы обучения/прогнозирования.
Если мы хотим узнать, кто на фото, для начала нам нужно обучить модель с помощью метода train, который принимает два параметра: массив изображений лиц для этих изображений и массив числовых меток. Затем вы можете вызвать метод прогнозирования на тестовом изображении (лицо) и получить соответствующие числовые метки.
$faceRecognizer = LBPHFaceRecognizer :: create ();
$faceRecognizer-> train ($myFaces, $myLabels = [1,1,1,1]); // 4 my faces
$faceRecognizer-> update ($angelinaFaces, $angelinaLabels = [2,2,2,2]); // 4 faces of Angelina
$label = $faceRecognizer-> predict ($faceImage, $confidence);
// get label (1 or 2) and confidence
Полный пример кода:GitHub.com/PHP-OpenCV/…
набор данных:
результат:
Когда я начинаю вызывать класс LBPHFaceRecognizer, ему не удается сохранить/загрузить/обновить обученную модель. На самом деле, мой первый запрос на включение добавил эти методы: запись/чтение/обновление.
Маркеры лиц/характерные точки
Когда я начал знакомиться с OpenCV, я часто видел изображения людей с точками, обозначающими глаза, нос, губы и т. д. Я хотел бы повторить этот эксперимент сам, но он не реализован в версии OpenCV для Python. Я провел вечер, добавляя поддержку FacematkLBF в PHP и возвращая объект. Все просто и легко, загружаем предобученную модель, вводим массив лиц и получаем массив характерных точек для каждого человека.
$facemark = FacemarkLBF::create();
$facemark->loadModel(‘models/opencv-facemark-lbf/lbfmodel.yaml’);
$facemark->fit($image, $faces, $landmarks);
Полный пример кода:GitHub.com/PHP-OpenCV/…
результат:
Как видно из этого примера, макияж зомби затрудняет поиск характерных точек на человеческом лице. Характерные точки также могут мешать локализации лиц. Освещение тоже играет роль, в этом случае посторонние предметы во рту (клубника, сигареты и т.д.) могут не мешать.
После моего первого запроса на включение я вдохновился и начал понимать, что может сделать opencv, и наткнулся на статью «Глубокое обучение, теперь в OpenCV». Сразу решил использовать предобученные модели в php-opencv, их много в инете. Хотя позже я потратил много времени на то, чтобы научиться работать с многомерными матрицами и использовать модели Caffe/Torch/TensorFlow без OpenCV, загрузить модель Caffe оказалось несложно.
Глубокое обучение, теперь в OpenCV:GitHub.com/OpenCV/открыть…
Обнаружение лиц с использованием моделей DNN
Поэтому OpenCV позволяет загружать предварительно обученные модели в Caffe с помощью функции readNetFromCaffe. Он принимает два параметра: пути к файлам .prototxt и .caffemodel. В файле prototxt есть описание модели, а в caffemodel — веса, вычисленные во время обучения модели.
Ниже приведен пример файла prototxt:
input:“data”
input_shape {
dim: 1
dim: 3
dim: 300
dim: 300
}
Этот файл описывает ввод 4-мерной матрицы размером 1x3x300x300. В описании модели обычно указано, что значит вводить в этом формате, но в большинстве случаев это означает, что на вход будет входить RGB-изображение (3 канала) размером 300х300.
Загружая RGB-изображение 300х300 с помощью функции imread, мы получаем матрицу 300х300х3.
В OpenCV есть функция blobFromImage, которая преобразует матрицу 300x300x3 в формат 1x3x300x300.
После этого мы можем просто применить блоб к сетевому вводу с помощью метода setInput и вызвать метод пересылки, который может вернуть нам окончательный результат.
$src = imread(“images/faces.jpg”);
$net = \CV\DNN\readNetFromCaffe(‘models/ssd/res10_300x300_ssd_deploy.prototxt’, ‘models/ssd/res10_300x300_ssd_iter_140000.caffemodel’);
$blob = \CV\DNN\blobFromImage($src, $scalefactor = 1.0, $size = new Size(300, 300), $mean = new Scalar(104, 177, 123), $swapRB = true, $crop = false);
$net->setInput($blob,“”);
$result = $net->forward();
В этом примере результатом является матрица 1x1x200x7, т.е. 200 массивов по 7 элементов на изображение. На фото с 4 лицами сеть нашла 200 кандидатов. Каждый из этих объектов имеет вид [$confidence, $startX, $startY, $endX, $endY]. Элемент $confidence представляет «доверие», то есть насколько хороша прогнозируемая вероятность, например, 0,75 — это хорошо. Элементы после этого представляют координаты прямоугольника лица. В этом примере только 3 лица были найдены с достоверностью более 50%, а остальные 197 кандидатов были найдены с достоверностью менее 15%.
Полный пример кода:GitHub.com/PHP-OpenCV/…
результат:
Как видно из этого примера, нейросеть не всегда дает хорошие результаты при использовании «в лоб», четвертое лицо не находится, но если четвертое фото вынуть отдельно и импортировать в нейросеть, то лицо будет найдено.
Использование нейронных сетей для улучшения качества изображения
Давным-давно я слышал о библиотеке waifu2x, которая убирает шумы и увеличивает размер иконок/фото. Библиотека написана на lua и использует несколько моделей, обученных на Torch под капотом (чтобы увеличить размер иконок, убрать фотошумы и т.д.). Автор этой библиотеки экспортировал эти модели в Caffe и помог мне использовать их в OpenCV. Таким примером может быть что-то, написанное на PHP для увеличения разрешения значка.
- библиотека waifu2x:GitHub.com/nagadaohmi/вау…
- Завершенный код кода:GitHub.com/PHP-OpenCV/…
классификация изображений
Нейронная сеть MobileNet, обученная на ImageNet, может классифицировать изображения. Всего он может выделить 1000 категорий, что мне мало.
Полный код примера:GitHub.com/PHP-OpenCV/…
Tensorflow целевой обнаружение API
Сеть MobileNet SSD (Single Shot MultiBox Detector), обученная с помощью Tensorflow на наборе данных COCO, может не только классифицировать изображения, но и возвращать области объектов, хотя можно обнаружить только 182 класса.
Полный код примера:GitHub.com/PHP-OpenCV/…
Выделение синтаксиса и завершение кода
Я также добавил файлы phpdoc.php в репозиторий и в качестве примера. Благодаря этому PHPSTORM подсвечивает синтаксис, классы и методы функции, а также может использоваться для автодополнения кода. Этот файл не нужно включать в свой код (иначе появится ошибка), достаточно поставить его в свой проект. Лично мне это упрощает программирование. Этот файл описывает большую часть функций OpenCV, но не все, так что добро пожаловать, чтобы отправить запрос на извлечение.
phpdoc.php:GitHub.com/PHP-OpenCV/…
Установить
Модуль «dnn» присутствует только в OpenCV 3.4 (в предыдущих версиях он был в contrib).
Последняя версия OpenCV для Ubuntu 18.04 — 3.2. Сборка OpenCV из исходников занимает около получаса, поэтому я скомпилировал этот пакет под Ubuntu 18.04 (также для 17.10, размер 25 МБ) как для PHP 7.2 (Ubuntu 18.04), так и для PHP 7.1 (Ubuntu 17.10) (размер 100 КБ), скомпилировал Пакет php-opencv. Зарегистрировал ppa: php-opencv, но еще не закончил его заливать и не нашел ничего лучше, чем залить пакет на GitHub. Я также создал запрос на создание учетной записи в pecl, но не получил ответа в течение нескольких месяцев.
Загрузите пакеты на Github:GitHub.com/PHP-OpenCV/…
Итак, теперь установка под Ubuntu 18.04 выглядит так:
apt update && apt install -y wget && \
wget https://raw.githubusercontent.com/php-opencv/php-opencv-packages/master/opencv_3.4_amd64.deb && dpkg -i opencv_3.4_amd64.deb && rm opencv_3.4_amd64.deb && \
wget https://raw.githubusercontent.com/php-opencv/php-opencv-packages/master/php-opencv_7.2-3.4_amd64.deb && dpkg -i php-opencv_7.2–3.4_amd64.deb && rm php-opencv_7.2–3.4_amd64.deb && \
echo“extension=opencv.so”> /etc/php/7.2/cli/conf.d/opencv.ini
Установка этой опции занимает около 1 минуты, все варианты установки выполняются в Ubuntu:GitHub.com/PHP-OpenCV/…
Я также скомпилировал образ докера размером 168 МБ.
Пример использования
скачать:
git clone https://github.com/php-opencv/php-opencv-examples.git && cd php-opencv-examples
бегать:
php detect_face_by_dnn_ssd.php
Оригинальная ссылка:medium.com/@default O означает o против K/…