Последние статьи
- Твердотельный датчик направления и скорости ветра. Эксперимент
- iPhone на стене в качестве панели управления домом
- MegaD-16M-XT - подсветка выключателей и не только
- Переделка выключателей в кнопки и мини-обзор текущего рынка
- RadSens - модульный счетчик Гейгера с интерфейсом I2C
- "U" - значит универсальный. Обзор модуля MegaD-16U-XT
- SCD4x - современная альтернатива для измерения концентрации CO2
- HTU31D - новый датчик температуры и влажности с нагревательным элементом
- Измерение коэффициента пульсации ламп с помощью MegaD-2561
- Использование солнечных панелей в качестве датчика освещенности
- Согласование датчиков с выходом типа TTL со стандартными входами контроллера
- DPS368 - датчик атмосферного давления индустриального класса повышенной точности
- DS18B20 Waterpoof - импортзамещение
- TMP117 - высокоточный датчик температуры с интерфейсом I2C
- MegaD-16R-XT - расширитель на 16 релейных выходов
- MegaD-2561-RTC V3 - больше портов, зуммер и ИОН
Фейс контроль, распознавание лиц в системе видеонаблюдения
11/10/2011 18:04:10
Возможно, данная статья устарела.
Все новые статьи
"Неча на зеркало пенять, коли рожа крива" (Народная поговорка)
Когда я на калитку забора установил домофонную вызывную панель AVC-305 с цветной видеокамерой, то у меня сразу же возникла крамольная мысль - сделать так, чтобы сервер анализировал изображение и открывал замок своим. Я провел несколько испытаний и установил, что такую систему из подручных средств сделать можно и что она работает, о чем хочу поделиться.
Для тех, кто любит порассуждать на тему фотографии лица, приставленной к видеокамере или чего-то в этом роде, сразу хочу сказать, что у меня не тюрьма, колючей проволоки под напряжением, собак и охраны с автоматами нет и что перелезть через забор значительно проще всяческих ухищрений, поэтому о целесообразности и надежности лучше поговорить как-нибудь отдельно. Меня же прежде всего интересует технология.
Итак, оценив изображение с дешевой широкоугольной камеры типа "пинхол", я понял, что задачу распознавания лиц необходимо решать в два этапа.
1. Из целого кадра выделить только лицо
2. Распознать это лицо.
Определение на фото лиц с помощью PHP и библиотеки OpenCV
Только половина дела...
Некоторое время назад я экспериментировал с библиотекой FANN, которая обеспечивает работу с нейронными сетями. Я уже имел некоторый успешный опыт, поэтому для распознавания лиц решил воспользоваться этой библиотекой. Прежде чем использовать нейронную сеть, ее нужно научить отличать своих от чужих. То есть в буквальном смысле показать фотографии лиц, которых мы знаем и уважаем и других лиц, которых автоматически пускать не хотим. Но если мы подсунем фотографии людей с вызывной панели без обработки, то такой обучающий материал будет не совсем качественным. Ведь человек может стоять дальше от камеры или ближе к ней, правее или левее, летом в дождь или зимой, когда на заднем плане будут навалены сугробы, в шубе или в шортах на босу ногу. Помимо лица на фотографии могут присутствовать другие детали, которые в нашей задаче будут являться мусором и сбивать с толку нейронную сеть. Ведь neural network - это просто алгоритм. Он выявляет скрытые взаимосвязи, но не знает что именно он должен определить на фотографии, то ли свой-чужой, то ли зима-лето, то ли людей в шапках и без. Поэтому мы должны предоставить нейронной сети не целый снимок, а только лицо человека.
Для решения этой задачи мы воспользуемся библиотекой OpenCV (компьютерное зрение). Эта библиотека позволяет в том числе выявить на фотографии лица.
Установка OpenCV на Linux (Debian Squeeze)
Прежде всего, необходимо установить пакеты, которые нужны для компиляции библиотеки.
apt-get install build-essential cmake pkg-config libjpeg62-dev apt-get install libtiff4-dev libv4l-dev libpng++-dev libavcodec-dev apt-get install libavformat-dev libswscale-dev libdc1394-22-dev apt-get install libgstreamer0.10-dev libgtk2.0-dev
Теперь скачаем с официального сайта релиз OpenCV 2.3.1 и распакуем его
tar -xvjf OpenCV-2.3.1a.tar.bz2
Заходим в распакованную папку и создаем новый каталог release, а затем компилируем и устанавливаем библиотеку.
make release cd release cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D BUILD_EXAMPLES=ON .. make make install
Программы с использованием OpenCV могут быть написаны на любом языке, но мне удобнее набросать скрипт на языке PHP, поэтому я установил PHP-модуль facedetect, работающий с OpenCV. Для использования в системе PHP и Apache нужно, чтобы были установлены следующие пакеты apache2, php5, php5-dev php5-gd
Качаем с Github PHP-Facedetect, распаковываем и устанавливаем с помощью нехитрой процедуры:
tar -xvzf infusion-PHP-Facedetect.tar.gz phpize ./configure make make install
Теперь осталось только в файле php.ini подключить установленный модуль.
extension=facedetect.so
Прежде чем написать простенькую программу, нужно еще раз немного подумать. Для нейронной сети нам нужно подготовить как можно более нормализованные примеры, чтобы сеть не отвлекалась на мелочи, которые не имеют к решению нашей задачи никакого отношения. Поэтому необходимо предусмотреть две вещи:
Первое. Лицо на фотографии может занимать разную площадь, в том числе в пикселях. Значит необходимо произвести ресайз всех изображений до определенного формата, например 200 на 200 точек.
Второе. Цвет. В данном случае цвет будет мешать. Эта та информация, которая в целом не несет с точки зрения классификации и распознавания лиц полезной функции, но может теоретически мешать нейронной сети правильно принять решение. Мы должны преобразовать цветную фотографию в черно-белую (а точнее, в grayscale).
Сделать это нетрудно и в результате получается вот такой скрипт.
<? $face = face_detect("snap.jpg",'haarcascade_frontalface_alt.xml'); $im = @imagecreatefromjpeg("snap.jpg"); $crop = @imagecreatetruecolor(200, 200); imagecopyresampled($crop, $im, 0, 0, $face[0]['x'], $face[0]['y'], 200, 200, $face[0]['w'], $face[0]['h']); imagefilter($crop, IMG_FILTER_GRAYSCALE); imagejpeg($crop, "face.jpg", 100); imagedestroy($crop); imagedestroy($im); ?>
Программа анализирует snap.jpg, полученный с камеры наблюдения, выявляет на фото лицо и записывает в файл face.jpg
В результате из целого кадра получаем grayscale кроп 200х200 готовый к распознаванию
Спустя некоторое время у нас может набраться достаточное количество лиц, как своих, так и чужих. Чтобы не усложнять программный код в статье, предположим, что нам необходимо отличить от всего массива лиц какое-то конкретное. Для этого мы воспользуемся нейронной сетью и подходом, который описан в статье "Анализ изображений с помощью нейронной сети". Подготовим обучающий материал. Отсортируем вручную несколько десятков фотографии и в папку "1" запишем файлы с лицом, у которого есть доступ, а в папку "0" всех остальных.
Далее напишем простую программу, которая обучит нашу нейронную сеть.
$j = 0; $my_example = array(); for ( $i = 0; $i < 2; $i++ ) { $d = dir("teach/$i"); while($entry = $d->read()) { if ( preg_match("/jpg/", $entry) ) { $im = imagecreatefromjpeg("teach/$i/$entry"); $cur_array = array(); $cnt = 0; for($y=0; $y<200; $y++) { for($x=0; $x < 200; $x++) { $rgb = imagecolorat($im, $x, $y) / 16777215; $cur_array[$cnt] = $rgb; $cnt++; //echo $rgb."<br>";; } } imagedestroy($im); $my_example[$j] = array($cur_array, array($i)); $j++; } } } $ann = fann_create(array(40000, 200, 1), 1.0, 0.7); if ( fann_train($ann, $my_example, 1000, 0.001, 1000) == FALSE) exit('Could not train $ann.'); fann_save($ann, "my.ann");
Теперь проверим работоспособность сети в боевых условиях и с помощью программы.
$ann = fann_create("my.ann"); $file_cnt = 0; $im = imagecreatefromjpeg("../snap/Camera1.jpg"); $cur_array = array(); $cnt = 0; for($y=0; $y<200; $y++) { for($x=0; $x < 200; $x++) { $rgb = imagecolorat($im, $x, $y) / 16777215; $cur_array[$cnt] = $rgb; $cnt++; } } imagedestroy($im); if ( ($output = fann_run($ann, $cur_array)) == FALSE ) exit("Could not run ANN."); else print_r($output);
В результете мы получим число, которое будет ответом нейронной сети. Значения больше 0.7 будут говорить, что этому человеку разрешен доступ. Значения меньше 0.3 - нет. Иные значения лучше трактовать как неопределенные. Фотографии таких лиц лучше складывать в отдельную папку для дальнейшего дообучения сети.
Испытания в реальных условиях показали, что предложенный подход неплохо справляется с задачей.
Человек, который имеет доступ. Ответ нейронной сети: [0] => 0.960845589638
Человек, у которого нет доступа. Ответ нейронной сети: [0] => 0.0223079491407
У предложенного в статье решения есть только один минус. Время распознавания. Оно зависит от объема обучающего материала. В моем примере для обучения использовалось 40 фотографий. Объем сети в памяти занимает порядка 260Мб. Время распознавания на компьютере с процессором Pentium 4 3ГГц - около 15 секунд. Но, полагаю, если система покажет свою работоспособность в будущем, можно будет подумать и об апгрейде сервера. Дообучать сеть можно будет в полуавтоматическом режиме.
Вот такой вот получился фейс-контроль.
Автор: Andrey_B
Любое использование материалов сайта возможно только с разрешения автора и с обязательным указанием источника.
Добавить комментарий:
Сортировка комментариев: Последние сверху | Первые сверху
2020-03-15 00:07:18 | Олег Елин
Series of the Chip: Lightspeeur®
Module of the Chip: SPR2801S
High Energy Efficiency: 9.3 TOPs/Watt
Ultra Low Power: 2.8 TOPs @300mW
Best Peak Performance: 5.6 TOPs @100MHz
Hardware Interface: SDIO3.0 eMMC 4.5
Sealed Package of the Chip: BGA (7mm7mm)
Fabrication Process: 28nm
вот такая погремуха
/www.orangepi.org/Orange%20Pi%20AI%20Stick%202801/
2020-03-15 00:03:26 | Олег Елин
а использовать свитое от компании orange pi для вычислений нейросети ?
2015-08-12 00:17:45 | Алексей
Что если усложнить задачу: 3. Выдать информацию о лице (имя файла, с которым совпадает лицо). Реально?
2014-12-26 11:43:49 | Валерий
Спасибо, установил.
Все равно черный квадрат.
2014-12-25 12:37:49 | Andrey_B
Валерий, правильное имя пакета "libv4l-dev".
2014-12-25 10:17:46 | Валерий
1. Не удалось найти пакет lib4vl-dev.
2. По первому примеру, все проходит без ошибок, но файл face.jpg просто черный квадрат
Может быть черный квадрат из за того, что lib4vl-dev не установлен?
2014-02-02 15:53:00 | Alexander
Мне также первым в голову пришла идея с фотографией вместо головы владельца. Система у вас отличает фото от живого человека? Догадаюсь: ответ будет, скорее всего, ниже 0,3 :)
2013-09-24 18:22:44 | Arbuzmaster
Подскажите пожалуйста почему в fann_train($ann, $my_example, 1000, 0.001, 1000) 5 параметров хотя ожидалось всего 3 ? libFann 2.1.0
2013-01-20 15:21:15 | Stas
Запускаю скрипт определения скрипта и получаю
$ php face-detect.php
PHP Fatal error: Call to undefined function face_detect() in /home/stas/Workplace/smarthouse/face-detect.php on line 2
хотя
find /usr/ -name facedetect.so
/usr/src/PHP-Facedetect-master/.libs/facedetect.so
/usr/src/PHP-Facedetect-master/modules/facedetect.so
/usr/lib/php5/20090626+lfs/facedetect.so
и
tail -2 /etc/php5/apache2/php.ini
extension=fann.so
extension=facedetect.so
Почему так?
2012-04-02 13:15:46 | Andrey_B
Валерий, вы неправильно обучаете сеть, потому что неправильно заполняете массив $my_example. У вас там какое-то шаманство.
Заполняться он должен примерно так:
Для $i = 0
$my_example[$j] = array($cur_array, array(0,0,0)
Для $i = 1
$my_example[$j] = array($cur_array, array(0,0,1)
Для $i = 2
$my_example[$j] = array($cur_array, array(0,1,0)
Для $i = 3
$my_example[$j] = array($cur_array, array(1,0,0)
Собственно, порядок тут неважен. Главное чтобы при трактовке результатов вы пользовались той же логикой. В PHP этот кусом можно реализовать покороче.
А вообще для того рода обсуждений лучше воспользуйтесь нашим форумом. Там удобнее.
2012-04-02 10:58:17 | Valeriy
Попробовал реализовать задачу аналогичную той, что описал stpavel, только с людьми. Вот так немного изменил обучающий скрипт:
====
$j = 0;
$my_example = array();
for ( $i = 0; $i < 4; $i++ )
{
if ($i == 0)
{
$l = 0;
$index = array(0, 0, 0);
}
else
{
$l = $i;
$l--;
$index = array(0, 0, 0);
$index[$l] = 1;
}
$d = dir("teach/$i");
while($entry = $d->read())
{
if ( preg_match("/jpg/", $entry) )
{
$im = imagecreatejpeg("teach/$i/$entry");
$cur_array = array();
$cnt = 0;
for($y=0; $y<200; $y++)
{
for($x=0; $x < 200; $x++)
{
$rgb = imagecolorat($im, $x, $y) / 16777215;
$cur_array[$cnt] = $rgb;
$cnt++;
/ echo $rgb."
";;
}
}
imagedestroy($im);
/ $index[$l] = array($cur_array, array($l));
if ( $l = 0 )
{
$my_example[$j] = array($cur_array, array($l));
}
else
{
/ $my_example[$j] = array($cur_array, array($index));
$j++;
}
}
}
$ann = fann_create(array(40000, 200, 3), 1.0, 0.7);
if ( fann_train($ann, $my_example, 1000, 0.001, 100) == FALSE)
exit('Could not train $ann.');
fann_save($ann, "my1.ann");
?>
====
Т.е. изменил маркировку массива my_example. Каждый элемент этого массива маркировался 0 или 1, а теперь 000, 100, 010, 001 (у меня 4 папки: в первой (которая "0") чужие фото, и 3 со "своими" (1, 2 и 3). На выходе хочется получить что-то типа:
0,9
0,2
0,3
Т.е. человек опознан, и он из папки 1. Но на практике работает не так. Даже при обучении все время выдает разные коэффициенты, а результат выполнения скрипта распознавания разный на одной и той же фотографии при переобучении программы без добавления новых фото(((. Может я недочитал/недопонял принцип работы и логику FANN? Вобщем, если есть идея где я ошибся, буду рад помощи.
P.S.: сори за предыдущий комментарий, некорректно добавился.
2012-03-27 10:46:16 | Andrey_B
Debian 5 - это Lenny?
У меня libfann1 прекрасно установился.
Подробнее здесь
2012-03-27 01:46:41 | artmel
Огромное спасибо за такие статьи!
Подскажите, стоит дебиан 5 , не смог поставить fannlib1, только fannlib2
и теперь у меня выбивает
/var/neuro php index.php
/etc/php5/modules/fann.so: undefined symbol: fann_create_array
как можно это победить? или как поставить fannlib1 ?
2012-01-21 23:49:48 | Andrey_B
Никита, может быть и проще. Нужно будет попробовать.
2012-01-19 15:28:26 | Никита
А не проще ли было воспользоваться распознованием лиц с помощью opencv (opencv.willowgarage.com/wiki/FaceRecognition)? в моей базе 5 лиц, на старой машинке (coreduo, интегрир. видео) отрабатывает разпознование немногим больше секунды.
2011-12-23 14:24:25 | DMG
Александр, тепла или открытого пламени? Если тепла то смотрите PIR-датчики, из готового Фотоны всякие...
2011-12-21 10:57:24 | Andrey_B
red, скажите, а вы вообще-то читали статью?
2011-12-21 01:53:07 | red
А если, к примеру, такой случай: я не имею доступ, то есть ваша нейронная сеть меня не знает, а ВАС ваша нейронная сеть знает и естественно любезно откроет ВАМ дверь. Но я в свою очередь имею возможность сфотографировать ВАС, а затем поднести ВАШУ фотографию к камере видео наблюдения. Тогда получается она впустит меня! Как с этим быть!??
2011-10-31 17:56:21 | Александр
Уважаемый Andrey_B, не встречались ли вам бюджетные решения тепловых сенсоров?
Основная идея такая: при попадании человека или другого источника тепла туда, где ему быть нельзя, включается видеозапись с камеры расположенной рядом и умный дом реагирует на это. А дальнейшее уже зависит от вашего желания, как он вам сообщит об этом.Хоть Фотографию пошлет..
Есть ли подобные решения с адекватным ценником? А то уж больно нехорошая цена на промышленно исполненные системы существует.
2011-10-18 14:25:19 | Дмитрий
Это бесподобно! ) Автор молодец!
Сам пытался подружить OpenCV с Java, в среде NetBeans,
пока ничего путёвого не вышло, похоже всё-таки руки кривые )))
Как появится свободное время обязательно займусь!!