Meefik's Blog

Freedom and Open Source

Детекция лиц с инвариантностью к повороту

Не так давно наткнулся на публикацию Object Detection with Pixel Intensity Comparisons Organized in Decision Trees, авторы которой предлагают модификацию метода детекции лиц Виолы-Джонса. Основное отличие метода состоит в том, что вместо признаков Хаара используются простые пиксельные тесты без необходимости рассчитывать интегральное изображение. Это позволяет повысить скорость вычислений и сэкономить память.

Авторы статьи приводят пример реализации данного алгоритма на C с предобученным классификатором для детекции лиц. Недавно появилась реализация алгоритма PICO на JS, однако в ней нет реализации инвариантности к повороту изображения (или наклона головы влево/вправо). Эту недоработку я и решил исправить.

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

В доработку вошло:

  • реализация инвариантности к повороту;
  • функция загрузки классификатора;
  • более производительный метод для преобразования RGBA изображения в оттенки сергого (grayscale);
  • код на ES6.

Код JS-библиотеки: https://github.com/meefik/pico.js

Использование JS-библиотеки

Все параметры библиотеки задаются в конструкторе, вот их описание:

Параметр По умолчанию Описание
shiftfactor 0.1 Шаг перемешения скользящего окна в процентах (10%) от размера изображения
scalefactor 1.1 Шаг изменения размера скользящего окна в процентах (10%) от размера изображения
initialsize 0.1 Начальный размер скользящего окна в процентах (10%) от размера изображения
rotation 0 Массив углов вращения для которых будет выполнен поиск (от 0 до 360 с шагом 1 градус)
threshold 0.2 Процент (20%) пересечения найденных кандидатов для группировки их в одну область
memory 1 Число изображений (кадров) в памяти для повышения качества поиска

На выходе получается массив областей, где, как алгоритм предполагает, находятся лица. Вот описание такой области:

Свойство Описание
c X-коортината центра найденной области лица
r Y-коортината центра найденной области лица
s Размер найденной области (ширина и высота или диаметр)
q Качество обнаружения (чем больше, тем лучше качество)
a Угол поворота изображения (наиболее вероятный из перечисленных в параметре rotation)

Пример кода:

// create PICO instance with options
var pico = new PICO({
  shiftfactor: 0.1, // move the detection window by 10% of its size
  scalefactor: 1.1, // for multiscale processing: resize the detection window by 10% when moving to the higher scale
  initialsize: 0.1, // minimum size of a face (10% of image area)
  rotation: [0, 30, 60, 90, 270, 300, 330], // rotation angles in degrees
  threshold: 0.2, // overlap threshold
  memory: 3 // number of images in the memory
});
// load cascade
pico.loadCascade('./cascade/facefinder').then(function() {
  // image = ImageData
  var dets = pico.detect(image);
  // dets = [{ r: rows, c: cols, s: size, q: quality, a: angle }]
});

Запуск демонстрации:

npm install
npm start

После запуска сервера демонстрационная страница будет доступна по адресу http://localhost:8080

И небольшое видео: