Компьютерное зрение — это, в двух словах, набор технологий, в основу которых положены принципы человеческого зрения, которые позволяют компьютеру видеть и понимать то, что он видит. На первый взгляд вроде бы просто, но на самом деле это далеко не так.
Если вы хотите осознать важность компьютерного зрения и узнать об областях его применения, посмотрите это видео.
Как говорится: «лучше один раз увидеть», в данном случае — увидеть, как 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.
Уважаемые читатели! Применяете ли вы технологии машинного зрения в своих проектах?
Автор: ru_vds