Распознавание лиц

Вопросы и информация о скриптах для ioBroker
Antworten
andrey99986
professional
Beiträge: 198
Registriert: 24.08.2016, 11:12

Распознавание лиц

Beitrag von andrey99986 » 28.04.2018, 11:32

Web-интерфейс для iobroker к распознованию лиц на основе модуля: https://github.com/justadudewhohacks/fa ... gnition.js


1. Системные требования.

Протестировано только на unix Debian, MYSQL.
Категорически рекомендую ставить на систему в которой возможен запуск дополнительного драйвера js (+150mb).
Иначе фризы по несколько секунд и падения всех скриптов js вам обеспечены, я предупредил.
На i5mobile время детекции лиц 1 кадра с видеопотока 1280x720 занимает около 3.3 сек, распознавание 0.01 сек.
Поэтому ни о каком распознавании в реальном времени речи быть не может. Поэтому либо по датчику движения разбираем видеозапись на кадры с последующим распознаванием
или в целях тестирования запускаем выгрузку кадров с потока с частотой меньше скорости детекции+распознавания:
Например в моём случае 1 кадр в 5 сек:
ffmpeg -i rtsp://admin:password@192.168.1.100:554/Streaming/Channels/1 -qscale:v 1 -vf fps=1/5 /home/iobroker/iobroker-data/files/camera/input/out%03d.jpg

2. Алгоритм распознавания.

Процесс обучения состоит в создании 128 векторов (числа от 0 до 1) из предварительно детектированной и кадрированной до 150*150 картинки с лицом.
Каждому лицу можно добавлять неограниченное количество наборов из 128 векторов.
При стандартном распознавании вычисляется "средний" набор векторов для каждого владельца лиц из базы данных json (сами картинки при этом не нужны)
и замеряется лучшее минимальное "расстояние" от среднего набора векторов (соответствующему своему имени) до входной картинки с лицом.
"Расстояние" это число 0 до 1 и есть по сути величина обратная вероятности.
Предложенный автором алгоритм меня не устроил по качеству распознавания, поэтому я добавил возможность измерять расстояние до каждого набора векторов в базе.
Свой метод на странице я назвал "Альтернативный".
Предположу что классический метод нужен когда в базе миллионы лиц и нет времени сверяться с каждым набором, так как время распознавания будет большим.
Для домашних целей альтернативный способ мне показался предпочтительней, можете протестировать.

3. Установка.

3.1.Согласно https://github.com/justadudewhohacks/fa ... gnition.js :

sudo apt-get install cmake
sudo apt-get install libopenblas-dev
sudo apt-get install libx11-dev (если есть GUI)
sudo apt-get install libpng-dev
Имеющие мощную графическую карту могут попробовать скомпилировать dlib с поддержкой CUDA

3.2. Добавляем 2-ой драйвер js.

В свойствах основного и дополнительного js драйвера добавляем модуль: face-recognition
Установка может занимать часы!!!

3.3 В БД MYSQL,настроенной на работу с iobroker создаём таблицу из запроса в файле "table.sql".

3.4 Создаём каталог и подкаталоги :

"/home/iobroker/iobroker-data/files/camera" - основной каталог
"/home/iobroker/iobroker-data/files/camera/conf" - будет размещаться json-файл с обученными лицами
"/home/iobroker/iobroker-data/files/camera/input" - входные файлы в формате jpg для распознования. После распознования файл удаляется.
"/home/iobroker/iobroker-data/files/camera/faces" - откадрированные файлы с лицами в формате jpg после распознования. Нужны для повторного распознования и для составления отчётов на веб-странице. После обучения не нужны, но рекомендую оставлять для понимания.

3.5 В основной драйвер js, который НЕ будет заниматься распознаванием импортируем скрипт из файла "fr_variables.txt".
Запускаем, исправляем ошибки если есть.

3.6 В дополнительный драйвер js, который будет заниматься ТОЛЬКО распознаванием импортируем скрипт из файла "fr_detect_recognize.txt".
Исправляем пути к каталогам, запускаем, исправляем ошибки если есть.

3.7 В основной драйвер js, который НЕ будет заниматься распознаванием импортируем скрипт из файла "fr_web.txt".
Запускаем, исправляем ошибки если есть.

4. Запускаем ffmpeg или вручную копируем jpg с лицами во входящий каталог:
ffmpeg -i rtsp://admin:password@192.168.1.100:554/Streaming/Channels/1 -qscale:v 1 -vf fps=1/5 /home/iobroker/iobroker-data/files/camera/input/out%03d.jpg
Если всё работает нормально файлы будут удалятся после обработки.
Если скорость обработки недостаточная - уменьшаем частоту.

5. В vis- редакторе создаём страницу и импортируем элементы из "fr_vis_elements.txt"

6. Открываем страницу в режиме просмотра.

7. После попадании лица в кадр (можно увидеть в логах) - меняем фильтр на веб странице для подгрузки новых данных.

P.S. "inituser" Не удалять! требование модуля.
P.S.2. Оптимальное разрешение входных кадров - 1280x720. Время детекции растёт прямо пропорционально количеству пикселов, а не длине сторон!
Dateianhänge
example.png
Face_R.rar
(13.51 KiB) 8-mal heruntergeladen

andrey99986
professional
Beiträge: 198
Registriert: 24.08.2016, 11:12

Re: Распознавание лиц

Beitrag von andrey99986 » 11.05.2018, 09:51

Есть ошибка небольшая - имена файлов после
const trainedModelFile =
должны быть одинаковые.
В каталог input правильнее загружать файлы не напрямую с камеры или копированием, а переносом с промежуточной папки. Иначе иногда возникает ошибка и скрипт останавливается.
Вот способ решения проблемы, файлы с камеры кладём в /ffmpeg, а оттуда переносим в input:

Code: Alles auswählen

var fs = require( 'fs' );
var path = require( 'path' );
// In newer Node.js versions where process is already global this isn't necessary.
//var process = require( "process" );

var moveFrom = "/home/iobroker/iobroker-data/files/camera/ffmpeg";
var moveTodir = "/home/iobroker/iobroker-data/files/camera/input";

// Loop through all the files in the temp directory

schedule("* * * * * *", function () {

fs.readdir( moveFrom, function( err, files ) {
        if( err ) {
            console.error( "Could not list the directory." +  err );
           // process.exit( 1 );
        } 

        files.forEach( function( file, index ) {
                // Make one pass and make the file complete
                var fromPath = path.join( moveFrom, file );
                var toPath = path.join( moveTodir, file );

                fs.stat( fromPath, function( error, stat ) {
                    if( error ) {
                        console.error( "Error stating file." +  error );
                        return;
                    }

                    if( stat.isFile() )
                        { //console.log( "is a file." + fromPath );
                        }
                    else if( stat.isDirectory() )
                        console.log( " is a directory." +  fromPath );

                    fs.rename( fromPath, toPath, function( error ) {
                        if( error ) {
                            console.error( "File moving error." +  error );
                        }
                        else {
                            // console.log( "Moved file " + fromPath +  toPath );
                        }
                    } );
                } );
        } );
} );

});

Antworten