Создание приложений, регистрирующих звуки и движения

Грэг Дункан

Вы когда-нибудь использовали приложения для веб-камеры с возможностью регистрации движения? Где находится та «материя», которая используется для определения движения? Когда-нибудь вы задумывались, как это было сделано, и что более важно, как это можно использовать в собственных приложениях?

Даже рассматривая приложения, которые определяют превышение порога уровня звука, зададимся вопросом – когда изменение звука запускает исполнительный процесс? Когда-нибудь задумывались, как это было сделано, и что более важно, как это можно добавить в собственные приложения?

Тогда взгляните на сегодняшний проект, появившийся благодаря CodeProject...

Как использовать видео- и аудиоинформацию для регистрации вторжения

clip_image002

Введение

В этой статье рассказывается, как использовать видео- и аудиоинформацию для регистрации вторжения. Изображения и звуки среды наблюдения непрерывно записываются с помощью веб-камеры и микрофона. Когда окружающие условия меняются, немедленно генерируется соответствующее предупреждение.

Пакет содержит:

  • DirectShowLib: Управляет веб-камерой, считывает картинку. Я перенес функции, относящиеся к классу IntruderDetection в класс CManipulateWebcam. Больше информации о DirectShowLib содержится в directshow.net.
  • ManipulateMicrophone: Управляет микрофоном, записывает звук, проигрывает звук. Функии, относящиеся к классу IntruderDetection перенесены в класс CManipulateMicrophone. Больше информации о ManipulateMicrophone можно найти в разделе «Использование кода» статьи: Отправка и проигрывание микрофонного аудиопотока по сети.
  • WavStream: Читает .wav-файл, сохраняет данные в .wav-файле. Класс CManipulateMicrophone использует WavStream.dll чтобы сохранить аудиоданные в .wav-файле. Полезен следующий код:

WaveStreamWriter wavwrite = WaveStreamWriter(FileName, SamplingRate, Channels, BitPerSample);
// SoundBuffer _ массив, содержащий аудиоданные, которые необходимо сохранить
wavwrite.Write(SoundBuffer, BufferLength);

  • IntruderDetection: Главное приложение, требует DirectShowLib.dll, ManipuateMicrophone.dll, WavStream.dll.

DirectShowLib, ManipulateMicrophone и WavStream – независимые проекты. Вы можете использовать в приложении DirectShowLib чтобы взаимодействовать с веб-камерой. используйте ManipulateMicrophone для взаимодействия микрофоном. UИспользуйте WavStream для управления .wav-файлом. Конечно, применяйте IntruderDetection для регистрации вторжения.

Какработает IntruderDetection

...

Хотя математика и травмирует мой мозг, я думаю крайне интересно посмотреть, как это делается непосредственно, а не с помощью компонент сторонних фирм…

Базовые знания об IntruderDetection

Регистрация видео

Для видео определим расстояние между двумя изображениями a(i,j) (ra,ga,ba) и b(i,j)(rb,gb,bb) следующим образом

D1=∑((|ra-rb|+|ga-gb|+|ba-bb|)/3) i=1,2...; j=1,2,... или

D2=∑((|ra-rb|2+|ga-gb|2+|ba-bb|2)/3) i=1,2...; j=1,2,... или

D3=max((|ra-rb|+|ga-gb|+|ba-bb|)/3) i=1,2...; j=1,2,...

Если D1,D2 или D3 оказываются больше определенного порогового значения, мы полагаем, что что-то произошло.

Вот пара снимков решения:

clip_image004clip_image006

И снимок кода функции сравнения видеоизображений:

 private bool CompareImage(Bitmap a, Bitmap b)
{
     int width = b.Width;
     int height = b.Height;
     BitmapData data_a = a.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
     BitmapData data_b = b.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
     unsafe
     {
         byte* pa = (byte*)data_a.Scan0;
         byte* pb = (byte*)data_b.Scan0;
         int offset = data_b.Stride - width * 3;
         double Ra, Ga, Ba, Rb, Gb, Bb;
         double temp1 = 0, temp2 = 0;
         double max = 0;
         for (int y = 0; y < height; y++)
         {
             for (int x = 0; x < width; x++)
             {
                 Ra = (double)pa[2];
                 Ga = (double)pa[1];
                 Ba = (double)pa[0];
                 Rb = (double)pb[2];
                 Gb = (double)pb[1];
                 Bb = (double)pb[0];
 
                 temp1 = (Math.Abs(Ra - Rb) + Math.Abs(Ga - Gb) + Math.Abs(Ba - Bb)) / 3;
                 temp2 += temp1;
 
                 if (temp1 > max)
                 {
                     max = temp1;
                 }
                 pa += 3;
                 pb += 3;
 
             }
             pa += offset;
             pb += offset;
         }
         temp2 = temp2 / (height * width);
         a.UnlockBits(data_a);
         b.UnlockBits(data_b);
 
         if (max > 200 || temp2 > 5)
         {
             return true;
         }
         else
         {
             return false;
         }
     }
}

Я также считаю, что проект DirectShowLib замечателен и сам по себе.

Целью этой библиотеки является предоставление доступа к функциональности Microsoft DirectShow из приложений .NET. Эта библиотека поддерживает Visual Basic .NET и C# и теоретически должна работать с любым языком .NET.

Управляемые решения Microsoft допускающие доступ к DirectShow из .NET не настолько полны как интерфейсы DirectShow для С++. Для разработчиков, желающих иметь всю функциональность DirectShow в .NET, эта библиотека обеспечивает перечисления, структуры и определения интерфейсов для доступа к ним.

Обзор исходного кода показывает, что в библиотеке содержится не так много исполняемого кода. Есть несколько вспомогательных функций (главным образом в DsUtils.cs), а все остальное составляют просто определения.

Хотя в исходном коде определено порядка 540 интерфейсов, только некоторые из них проверены на работоспособность. См файл ReadMe.rtf для обсуждения различий между протестированными и непротестированными.

Вот снимок библиотеки:

clip_image008

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