Веб-камера, Node.js и OpenCV: делаем систему распознавания лиц

https://codeforgeek.com/2017/07/building-live-webcam-face-detector-node-js-opencv/
  • Перевод
Компьютерное зрение — это, в двух словах, набор технологий, в основу которых положены принципы человеческого зрения, которые позволяют компьютеру видеть и понимать то, что он видит. На первый взгляд вроде бы просто, но на самом деле это далеко не так.



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

Как говорится: «лучше один раз увидеть», в данном случае — увидеть, как Amazon использует эту технологию для создания торговых центров нового поколения. Потрясающе, правда?

Если вы хотите приобщиться к технологиям компьютерного зрения — предлагаю поговорить о том, как создать интерактивную систему распознавания лиц с использованием обычной веб-камеры, Node.js и OpenCV.

Об изучении компьютерного зрения


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

Конечно, вы можете расширить свои знания в этой области и самостоятельно, например, записавшись на соответствующие курсы, скажем, на EDX.

Существует организация, которая называется OpenCV, работающая в области компьютерного зрения. Она занимается разработкой одноимённой библиотеки с открытым исходным кодом. Эта библиотека поддерживает C, C++ и Java. Официального модуля для Node.js нет, однако, существует модуль node-opencv, созданный энтузиастами. Мы будем пользоваться этим модулем в следующих разделах материала. А именно, ниже рассмотрим следующие вопросы:

  • Установка OpenCV.
  • Работа с модулем OpenCV для Node.js.
  • Разработка системы интерактивного распознавания лиц.

Установка OpenCV


Для начала надо установить библиотеку OpenCV. Если вы пользуетесь Ubuntu, вам помогут следующие команды. Я их проверил на Ubuntu 16.04.

Итак, начнём с установки зависимостей, необходимых для OpenCV.

sudo apt-get install build-essential
sudo apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
sudo apt-get install python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libjasper-dev libdc1394-22-dev

Теперь установим саму библиотеку OpenCV.

sudo apt-get install libopencv-dev

Установить её можно и иначе, воспользовавшись официальным руководством по установке и приведёнными в нём командами.

Библиотеку можно установить и для Windows.

Если вы работаете на Mac, вы можете либо собрать OpenCV из исходников, либо воспользоваться brew.

brew tap homebrew/science
brew install opencv

Модуль node-opencv


Как уже было сказано, OpenCV официально не предлагает драйвер для Node.js. Однако, в реестре npm имеется модуль node-opencv, работой над которым занимается Питер Брэйден и другие программисты. Модуль этот всё ещё находится в состоянии разработки, он пока не поддерживает все API OpenCV.

Надо отметить, что в настоящий момент последняя сборка с GitHub не объединена с npm-модулем node-opencv, поэтому, устанавливая модуль из npm, вы можете столкнуться с проблемами. Рекомендуется установить модуль непосредственно с GitHub, воспользовавшись следующей командой:

npm install peterbraden/node-opencv

Теперь займёмся программированием.

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


Прежде чем мы будем распознавать лица в видеопотоке веб-камеры, разберёмся с выполнением той же операции для обычной фотографии.

Как распознавать лица на фотографиях? OpenCV предоставляет различные классификаторы, которые можно использовать для распознавания лиц, глаз, автомобилей, и многих других объектов. Эти классификаторы, однако, достаточно просты, они не обучены с использованием технологий машинного обучения, поэтому, при распознавании лиц мы можем рассчитывать на точность примерно в 80%.

Вот фото моих друзей с одной из обычных офисных вечеринок.



Напишем программу, которая позволит распознать лица на этом снимке. Вот код (файл face-detector.js), который читает исходное изображение с диска и выводит новое изображение с отмеченными на нём лицами.

var cv = require('opencv');

cv.readImage("./friends.jpg", function(err, im){
  if (err) throw err;
  if (im.width() < 1 || im.height() < 1) throw new Error('Image has no size');

  im.detectObject(cv.FACE_CASCADE,{}, function(err, faces){
    if (err) throw err;

    for (var i = 0; i < faces.length; i++){
      var face = faces[i];
      im.ellipse(face.x + face.width / 2, face.y + face.height / 2, face.width / 2, face.height / 2);
    }

    im.save('./friends-faces.jpg');
    console.log('Image saved as friends-faces.png');
  });
});

Вот как программа распознала лица на снимке.



Знаю, получилось не очень точно, но начало положено, и это хорошо. Сделаем теперь то же самое, используя видеопоток с веб-камеры. Сначала нужно подключиться к камере и вывести видео. Вот код (camera.js), который это делает.

var cv = require('opencv');
try {
  var camera = new cv.VideoCapture(0);
  var window = new cv.NamedWindow('Video', 0)
  setInterval(function() {
    camera.read(function(err, im) {
      if (err) throw err;
      console.log(im.size())
      if (im.size()[0] > 0 && im.size()[1] > 0){
                if (err) throw err;
                window.show(im);
      }
      window.blockingWaitKey(0, 50);
    });
  }, 20); 
} catch (e){
  console.log("Couldn't start camera:", e)
}

Запустите этот код следующей командой.

node camera.js

Если всё работает как надо, вы увидите окно, в котором будет выводиться то, что снимает видеокамера. В вашем случае картинка будет похожа на ту, что показана ниже, только в кадр попадёт ваше лицо, а не моё.



Веб-камера у меня не очень, но, честное слово, в жизни я выгляжу куда лучше. Разберём нашу программу.

var camera = new cv.VideoCapture(0);
var window = new cv.NamedWindow('Video', 0)

Тут мы пытаемся получить доступ к видеопотоку с камеры и создать новое окно для показа видео.

Теперь для того, чтобы показать видео а не статичную картинку, нужно отобразить в окне свежее изображение, полученное с камеры. Делаем мы это, используя функцию setInterval() и обновляя содержимое окна каждые 20 миллисекунд.

  setInterval(function() {
    camera.read(function(err, im) {
      if (err) throw err;
      console.log(im.size())
      if (im.size()[0] > 0 && im.size()[1] > 0){
                if (err) throw err;
                window.show(im);
      }
      window.blockingWaitKey(0, 50);
    });
  }, 20);

Первое изображение имеет размеры 0x0 пикселей, его нам отображать не нужно. Об этом заботится выражение if.

Итак, мы знаем как распознавать лица на фотоснимках и как получить доступ к видеопотоку с веб-камеры. Теперь объединим это всё и наша интерактивная система распознавания лиц будет готова к работе. Вот код (файл camera.js), который распознаёт лица в видеопотоке.

var cv = require('opencv');

try {
  var camera = new cv.VideoCapture(0);
  var window = new cv.NamedWindow('Video', 0)
  // face detection properties
  var rectColor = [0, 255, 0]; 
   var rectThickness = 2;

  setInterval(function() {
    camera.read(function(err, im) {
      if (err) throw err;
      console.log(im.size())
      if (im.size()[0] > 0 && im.size()[1] > 0){
                im.detectObject(cv.FACE_CASCADE, {}, function(err, faces) {
                if (err) throw err;
                for (var i = 0; i < faces.length; i++) {
                        face = faces[i];
                        im.rectangle([face.x, face.y], [face.width, face.height], rectColor, rectThickness);
                 }
                window.show(im);
                });
      }
      window.blockingWaitKey(0, 50);
    });
  }, 20); 
} catch (e){
  console.log("Couldn't start camera:", e)
}

Запустим его.

node camera.js

Вот, что в итоге получилось

Опять же, точность распознавания здесь невысока, по грубым оценкам — порядка 80%.

Итоги


OpenCV — это потрясающий опенсорсный проект. Его можно использовать бесплатно для разработки приложений, которые могут найти применение, например, в таких областях, как распознавание движений и распознавание лиц. Кроме того, стандартные классификаторы можно обучить для повышения точности распознавания. Надеюсь, OpenCV будет официально поддерживать Node.js, что позволит использовать в этой среде больше возможностей данной замечательной библиотеки. Если вы хотите углубиться в технологии машинного зрения, то, помимо различных учебных курсов, полезно будет почитать эту книгу и взглянуть на материалы с официального сайта OpenCV.

Уважаемые читатели! Применяете ли вы технологии машинного зрения в своих проектах?
Метки:
  • +25
  • 11,6k
  • 6
RUVDS.com 760,37
RUVDS – хостинг VDS/VPS серверов
Поделиться публикацией
Комментарии 6
  • 0
    Если вы хотите осознать важность компьютерного зрения и узнать об областях его применения, посмотрите это видео

    Магазин классный, в такой я бы сходил. А вот в России такое не заработает, надо по 54-ФЗ обязательно чек с qr-кодом выдать.
    • 0
      надо по 54-ФЗ обязательно чек с qr-кодом выдать.


      Ну так все равно через турникет проходить, там можно сразу и чек распечатать И/ИЛИ на электронную почту отправить.
      • 0
        Очень круто.
        Думаю такое заработает как только гипермаркеты поймут что могут уволить тонну продавцов (всякие ашаны, леруа: около 50 касс, забиты в час пик). Но вопрос почём Амазон продаёт свою технологию и плюс расходы на оборудование (камеры, сервера, датчики..).
      • 0
        OpenCV ещё можно собрать через Emscripten и получать распознавание в браузере. Пример с распознаванием лица и глаз из базового примера по работе с OpenCV. А если немного поискать, то можно и распознавание котиков приделать.

        P.S. Мои примеры сделаны грубо и быстро, поэтому работают нормально только на ПК из хрома и ff. На Android тормозит, и часто используется фронтальная камера, а на айфонах Safari таким способом не даёт доступ к камере.
        • 0
          А можно взять библиотеку trackingjs.com и даже opencv не нужно тащить в браузер, работает стабильно и на фотографиях и на видео потоке.

          Но вообще конечно найти лицо на фотографии не очень сложно, интересности начинаются если нужно найти лицо на документах допустим, где поверх него могут быть водяные знаки и т.д.
        • 0

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

          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

          Самое читаемое