Блог от AS3Coder'a о JavaScript, HTML, CSS... и немного о Flash.

пятница, 27 августа 2010 г.

Распознавание лиц на изображении в ActionScript 3.0


На многих фотоаппаратах, даже самых простых "мыльницах" появилась такая функция, как распознавание лиц. Иногда, это действительно удобно и даже необходимо.

А ведь и мы имеем доступ к Web-камере во FlashPlayer, почему бы и нам не реализовать такой механизм?

Первый над этим вопросом видимо задумался Ohtsuka Masakazu, и портировал библиотеку компьютерного зрения OpenCV написанную на C++ на ActionScript 3.0 и опубликовал её на Spark project.

Работает механизм следующим образом: ему подсовывают .xml-файлы, в которых описываются необходимые свойства для распознавания тех или иных объектов, после чего идет поиск на изображении. Размер такого .xml-файла для распознавания лиц составляет что-то около 1 Мб и загружать его по сети не очень корректно. Тогда Ohtsuka Masakazu запаковал его в .zip-архив, который получился в 100 Кб. И уже загрузив архив, использую библиотеку FZip, он его распаковывал внутри FlashPlayer.

Казалось, всё прекрасно работает и можно с радостью использовать

Но не тут-то было. Лишний запрос на запакованный .xml-файл, лишний код для его распаковки - всё это не понравилось Mario Klingemann. Он избавился от загрузки внешнего .xml-файла переписав его содержимое в отдельный класс сократив его размер до 50 Кб. Также он провел некоторые оптимизации внутренних алгоритмов библиотеки.

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

Как всем эти пользоваться?

Больше всего мне понравился вариант от Mario Klingemann. Для примера я буду использовать исходники библиотеки после его оптимизации.

Импортируем пакет классов jp.maaash. Создаем экземпляр класса ObjectDetector и подписываемся на событие ObjectDetectorEvent.DETECTION_COMPLETE.

import jp.maaash.*;
...
var detector:ObjectDetector = new ObjectDetector();
detector.addEventListener(ObjectDetectorEvent.DETECTION_COMPLETE, onDetectorComplete);

Теперь мы можем попросить наш детектор распознать лица на заданном изображении. Вызываем у него метод detect c единственным параметром - ссылкой на данные изображения типа flash.bitmap.BitmapData.

detector.detect(bitmapData) // bitmapData - данные изображения, на котором следует которое следует распознать лица

После того, как распознавание закончится, детектор отправит соответствующее событие ObjectDetectorEvent.DETECTION_COMPLETE, в теле которого будет список распознанных областей.

private function onDetectorComplete (e:ObjectDetectorEvent):void
{
  var arr:Array = e.rects; // Список распознаных областей
  ...
}



Смотрите также:       

среда, 25 августа 2010 г.

Сохранение изображения с Web-камеры

1. Обращение к камере

Для работы с web-камерами во FlashPlayer имеется специальный класс flash.media.Camera. Чтобы получить список доступных камер на компьютере необходимо спросить его у статического свойства names.

var list:Array = Camera.names;
Теперь чтобы обратиться к конкретной камере, нужно вызвать статический метод getCamera, где в качестве параметра передается имя камеры из полученного выше списка. Метод вернет экземпляр класса flash.media.Camera.

var camera:Camera = Camera.getCamera(list[0]);
Но как заметил Илья Панин, обращение к камере в ActionScript 3.0 работает не так, как это описано выше. Казалось бы всё правильно и взято из официальной справки. Но это не так. В качестве параметра методу getCamera необходимо передавать индекс камеры, а не её название, причем в виде строки.

var camera:Camera = Camera.getCamera(index.toString()); // index - порядковый номер камеры
2. Вывод изображения с камеры на сцену

Изображение с камеры - это видео-поток, и для его воспроизведения воспользуется классом   flash.media.Video. Создаем экземпляр класса и добавляем его на сцену. В конструкторе указывается ширина и высота видео.

var video:Video = new Video(320, 240);
addChild(video);
Теперь чтобы отобразить в экземпляре полученного видео изображение с камеры необходимо её просто прикрепить. Вызываем метод attachCamera, где в качестве параметра указываем ссылку на камеру.

video.attachCamera(camera);
После того, как мы попытаемся что-нибудь сделать с изображением с камеры (показать его на сцене, отправить на сервер) FlashPlayer попросит разрешение на это действие у пользователя. Появится диалоговое окно с соответствующим вопросом.



После выбора одного из пунктов камера отправляет событие flash.event.StatusEvent типа STATUS. В обработчике этого события можно даже узнать о выборе пользователя. У экземпляра камеры имеется свойство muted, которое говорит запретил ли пользователь использовать соответствующую камеру.

После того, как изображение с камеры разрешено показать на сцене в экземпляре класса flash.media.Video, необходимо некоторое время для активации камеры. После полной активации камеры она отправляет событие flash.event.ActivityEvent типа ACTIVITY.
Еще одной важной особенностью работы с камерой во FlashPlayer является то, что одновременно показать изображение с неё в разных окнах плеера не получится. Попробуйте открыть эту страницу в двух разных браузерах. Во втором изображение с камеры вы не увидите, пока не закроете первое открытое окно.

3. Сохранение изображения со сцены

Экземпляр класса flash.media.Video является потомком класса flash.display.DisplayObject и в любой момент времени, например по нажатию соответствующей кнопки, мы можем преобразовать изображение с камеры в данные класса flash.display.BitmapData.

Для этого необходимо создать экземпляр flash.display.BitmapData. В конструкторе указываем ширину и высоту. Вызываем метод draw, с единственным параметром - ссылкой на экземпляр нашего видео.

var bitmapdata:BitmapData = new BitmapData(video.width, video.height);
bitmapdata.draw(video);
Теперь с помощью любого энкодера мы можем преобразовать полученные данные в бинарный файл изображения. Например используя com.adobe.images.PNGEncoder после преобразования, мы получим экземпляр класса flash.utils.ByteArray

var brr:ByteArray = PNGEncoder.encode(bitmapdata);
Осталось только сохранить полученный файл на диск. Используем для этого класс flash.net.FileReference. Создаем экземпляр и вызываем метод save, с двумя параметрами: бинарные данные файла, имя файла.

var file:FileReference = new FileReference();
file.save(brr, "image.png");
Подробнее о сохранении изображения смотрите в предыдущем посте.

4. Пример



5. Как распознавать лица на изображении?

Об этом я напишу в следующем посте. Хочу только сказать огромное спасибо за реализацию этой возможности Ohtsuka Masakazu и Mario Klingemann, а также Eugene Zatepyakin
      
Смотрите также:

среда, 11 августа 2010 г.

SharedObject. Сохранение данных на компьютере пользователя.

Что такое SharedObject?

SharedObject - это название класса, с помощью которого .swf-файл может записывать и читать различные данные на компьютере пользователя. Способ записи данных SharedObject имеет сходство с записью файлов сookie в браузерах.

Кроме того, SharedObject может сохранять данные и на сервере. Используется данная возможность в основном в тесной интеграции с Flash Media Server'ом. Рассматривать в рамках этого поста, возможность работы SharedObject с сервером я не буду. Поговорим только о возможностях работы с локальной системой.

Как же это работает?

Работает это следующим образом: один .swf-файл может записать любую информацию на клиентском компьютере только для себя, и прочитать её позже сможет только тот же .swf-файл, который её записал.

Чтобы записать данные нужно:
  1. Получить или создать экземпляр уникального контейнера
  2. Записать в свойство экземпляра "data" необходимые данные
  3. Сохранить данные экземпляра на локальный диск компьютера

var so:SharedObject = SharedObject.getLocal("as3coder-player");
so.data.volume = 100;
so.flush();

При следующем открытии, .swf-файл может прочитать ранее записанные им данные.
  1. Получить экземпляр уникального контейнера
  2. Получить необходимые данные у свойства экземпляра "data"

var so:SharedObject = SharedObject.getLocal("as3coder-player");
var volume:Number = so.data.volume;



Где и как хранятся данные на локальном диске пользователя?

Данные записываются в файлы с расширением "sol" в формате AMF. Найти их можно в директории:

Windows: C:\Users\<Имя пользователя>\AppData\Roaming\Macromedia\Flash Player\#SharedObjects\<Случайное число>\<Имя домена>\<Путь до .swf-файла>\<Имя контейнера>.sol

Mac OS X: ~/Library/Preferences/Macromedia/Flash Player/#SharedObjects/<Случайное число>/<Имя домена>/<Путь к .swf-файлу>/<Имя контейнера>.sol

Для Windows это выглядит так:



Чем открывать .sol-файлы?

Прочитать содержимое .sol-файлов можно, открыв их использую встроенную во FlashDevelop утилиту написанную на C# под названием "SharedObject Reader"


Также можно найти автономную версию этой программы, написанную на Python, "SOLReader".

Но как оказалось, в последних версиях FlashDevelop эта программа не работает. Если кто знает почему или как можно её отремонтировать пожалуйста сообщите в комментариях.

В качестве альтернативы нашлась другая утилита. Называется ".sol Editor". Умеет не только читать но и писать в .sol-файлах. Интересно конечно :) Но как это применить на практике пока не придумаю.



А как же безопасность?

Естественно Adobe позаботились о безопасности такого взаимодействия .swf-файла с файловой системой пользователя и наложили ограничение на объем записываемых данных. По умолчанию он равен 100 Кб. Но пользователь сам вправе решить, насколько он доверяет определенному домену, и может увеличить, уменьшить, либо вообще убрать это ограничение. Сделать это можно в параметрах Adobe Flash Player:





Где и как использовать?

Это вопрос фантазии. Например, в своих медиа-плеерах я записываю громкость звука, чтобы пользователь её постоянно не убавлял или не прибавлял когда заходил заново.



Смотрите также:

Поиск по блогу

Обо мне



Farid Shamsutdinov (AS3Coder)
Russia, Tatarstan, Kazan
as3coder@gmail.com

Подробнее...

Постоянные читатели

Рассылка

© 2014 Farid Shamsutdinov. При копировании материалов, ссылка на источник обязательна. Технологии Blogger.