<
  • Главная
Статьи

Детектор руху або Delphi + DsPack

Раніше я часто задавався питанням як проконтролювати хто підходив до комп'ютера, або бродив по кабінету поки мене не було Раніше я часто задавався питанням як проконтролювати хто підходив до комп'ютера, або бродив по кабінету поки мене не було. Відповідь знайшлася. Ця відповідь DsPack + Delphi. Сьогодні я покажу як змусити Web камеру стежити за приміщенням, реєструвати рух і записувати все це у вигляді bmp файлів. Для початку трохи про сам пакеті DsPack. DSPack являє собою набір компонентів і класів для створення додатків працюють з мультимедіа використовують MS Direct Show і DirectX технології. DSPack призначений для роботи з DirectX 9 на Win9x, ME, 2000 і Windows XP операційних системах.

Цей пакет можна завантажити з офіційного сайту http://www.progdigy.com/ або прямо звідси . За другою посиланням наведено пакет який вже містить версії для Delphi 5, 6, 7, 2005, 2007 і без проблем ставиться на Delphi 2007 яку я і буду використовувати.

установка DsPack

В установці немає нічого складного. Вона описана в файлі ReadMe. Але про всяк випадок:
0) Розпаковуємо DsPack архів
1) Запускаємо Delphi
2) Відкриваємо налаштування Tools -> Options
3) Список каталогів бібліотек Delphi Options -> Library - Win32
4) У правій частині вікна тиснемо Library Path і додаємо шляху до розпакованим файлів:
\ .. \ DsPack \ src \ DirectX9
і
\ .. \ DsPack \ src \ DSPack

Тепер залишилося встановити DsPack. По черзі відкриваємо проекти і компілюємо їх:
DSPack_D2006.dproj
потім
DirectX9_D2006.dproj
Тепер відкриваємо DSPackDesign_D2006.dproj і тиснемо Install.
От і все. DsPack встановлений.

створення форми

Створюємо новий проект Delphi. Кинемо на форму TFilterGraph. У властивостях компонента параметр Mode потрібно встановити в gmCapture.
Так само додамо TVideoWindow з тієї ж закладки DsPack, він буде використовуватися для відображення картинки з нашої web камери. У властивості FilterGraph встановимо FilterGraph1.
Далі додамо TFilter, це компонент який буде керувати фільтром. Саме для нього джерелом даних буде web камера. У властивості FilterGraph вибираємо FilterGraph1
Залишився тільки TSampleGrabber. Додаємо його і у властивості FitlerGraph вибираємо FitlerGraph1. Форма готова.

пишемо програму

Для початку підключимо в Uses DSUtil і DirectShow9 і оголосимо змінну яка буде відповідати за отримання списку пристроїв у нашій системі.

1 2 3 4 public {Public declarations} CamItem: TSysDevEnum; end; public {Public declarations} CamItem: TSysDevEnum; end;

Тепер отримаємо список встановлених в системі пристроїв, Зробимо це при створенні форми FormCreate (Sender: TObject);

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 procedure TForm1. FormCreate (Sender: TObject); var i: integer; begin CamItem: = TSysDevEnum. Create (CLSID_VideoInputDeviceCategory); if CamItem. CountFilters> 0 then begin FilterGraph1. ClearGraph; FilterGraph1. Active: = false; // Задаємо пристрій з короторого будемо отримувати зображення // 0 це індекс пристрої загальне колічесвтво можна дізнатися за допомогою CamItem.CountFilters Filter1. BaseFilter. Moniker: = CamItem. GetMoniker (0); FilterGraph1. Active: = true; // Звідки отримувати і куди показувати. with FilterGraph1 as ICaptureGraphBuilder2 do RenderStream (@PIN_CATEGORY_PREVIEW, nil, Filter1 as IBaseFilter, SampleGrabber1 as IBaseFilter, VideoWindow1 as IbaseFilter); // Виводимо зображення з камери. FilterGraph1. Play; end; end; procedure TForm1.FormCreate (Sender: TObject); var i: integer; begin CamItem: = TSysDevEnum.Create (CLSID_VideoInputDeviceCategory); if CamItem.CountFilters> 0 then begin FilterGraph1.ClearGraph; FilterGraph1.Active:=false; // Задаємо пристрій з короторого будемо отримувати зображення // 0 це індекс пристрої загальне колічесвтво можна дізнатися за допомогою CamItem.CountFilters Filter1.BaseFilter.Moniker: = CamItem.GetMoniker (0); FilterGraph1.Active:=true; // Звідки отримувати і куди показувати. with FilterGraph1 as ICaptureGraphBuilder2 do RenderStream (@PIN_CATEGORY_PREVIEW, nil, Filter1 as IBaseFilter, SampleGrabber1 as IBaseFilter, VideoWindow1 as IbaseFilter); // Виводимо зображення з камери. FilterGraph1.Play; end; end;

Тепер можна спробувати запустити програму. Після запуску, програма буде використовувати першу ж знайдену камеру і почне трансляцію в компоненті VideoWindow1.

детекція руху

Суть детекції буде зводиться до отримання з камери двох знімків в різний час, і наступні їх порівняння на предмет зміни.
Для реалізації цієї функції нам знадобиться компонент TTimer, а так же додамо на форму компонент Memo для ведення логу, і два компонента Image. Для таймера встановимо параметр Interval дорівнює 2000 (2 секунди.). При його спрацьовуванні буде виходити зображення з камери і порівнюватися з контрольним зображенням. У події OnTimer1 напишемо наступний код:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 procedure TForm1. Timer1Timer (Sender: TObject); var // i-координата пікселя по горизонталі i: integer; // j-координата пікселя по вертикалі j: integer; // Змінні кількості відмінностей k: integer; r1, g1, b1: Byte; r2, g2, b2: Byte; FirstColor, SecondColor: Integer; Color: TColor; ChangeDetect: byte; begin // Робимо перший знімок if Timer1. Tag = 0 then begin SampleGrabber1. GetBitmap (Image1. Picture. Bitmap); Timer1. Tag: = 1; exit; end; // Через деякий час - другий, з яким будемо звіряти SampleGrabber1. GetBitmap (Image2. Picture. Bitmap); Timer1. Tag: = 0; k: = 0; // Починаємо попіксельне порівняння for i: = 1 to Image1. Picture. Bitmap. Height do begin for j: = 1 to Image1. Picture. Bitmap. Width do begin ChangeDetect: = 0; // Отримуємо колір поточного пікселя першої картинки FirstColor: = Image1. Picture. Bitmap. Canvas. Pixels [i, j]; // Отримуємо складові RGB r1: = GetRValue (FirstColor); g1: = GetGValue (FirstColor); b1: = GetBValue (FirstColor); SecondColor: = Image2. Picture. Bitmap. Canvas. Pixels [i, j]; r2: = GetRValue (SecondColor); g2: = GetGValue (SecondColor); b2: = GetBValue (SecondColor); // Починаємо перевірку відмінностей між двома картинками if Abs (r1 -r2)> 20 then inc (ChangeDetect); if Abs (g1 -g2)> 20 then inc (ChangeDetect); if Abs (b1 -b2)> 20 then inc (ChangeDetect); // Якщо зміни суттєві, то збільшуємо лічильник if ChangeDetect = 3 then k: = k + 1; Application. ProcessMessages; end; end; // Якщо змін понад 1500 то повідомляємо про це if k> 1500 then begin Memo1. Lines. Add (FormatDateTime ( 'hh: nn: ss', Now) + 'Виявлено рух!'); Image2. Picture. Bitmap. SaveToFile ( 'alerts \' + FormatDateTime ( 'hhnnss', Now) + '. Bmp'); end; end; procedure TForm1.Timer1Timer (Sender: TObject); var // i-координата пікселя по горизонталі i: integer; // j-координата пікселя по вертикалі j: integer; // Змінні кількості відмінностей k: integer; r1, g1, b1: Byte; r2, g2, b2: Byte; FirstColor, SecondColor: Integer; Color: TColor; ChangeDetect: byte; begin // Робимо перший знімок if Timer1.Tag = 0 then begin SampleGrabber1.GetBitmap (Image1.Picture.Bitmap); Timer1.Tag: = 1; exit; end; // Через деякий час - другий, з яким будемо звіряти SampleGrabber1.GetBitmap (Image2.Picture.Bitmap); Timer1.Tag: = 0; k: = 0; // Починаємо попіксельне порівняння for i: = 1 to Image1.Picture.Bitmap.Height do begin for j: = 1 to Image1.Picture.Bitmap.Width do begin ChangeDetect: = 0; // Отримуємо колір поточного пікселя першої картинки FirstColor: = Image1.Picture.Bitmap.Canvas.Pixels [i, j]; // Отримуємо складові RGB r1: = GetRValue (FirstColor); g1: = GetGValue (FirstColor); b1: = GetBValue (FirstColor); SecondColor: = Image2.Picture.Bitmap.Canvas.Pixels [i, j]; r2: = GetRValue (SecondColor); g2: = GetGValue (SecondColor); b2: = GetBValue (SecondColor); // Починаємо перевірку відмінностей між двома картинками if Abs (r1-r2)> 20 then inc (ChangeDetect); if Abs (g1-g2)> 20 then inc (ChangeDetect); if Abs (b1-b2)> 20 then inc (ChangeDetect); // Якщо зміни суттєві, то збільшуємо лічильник if ChangeDetect = 3 then k: = k + 1; Application.ProcessMessages; end; end; // Якщо змін понад 1500 то повідомляємо про це if k> 1500 then begin Memo1.Lines.Add (FormatDateTime ( 'hh: nn: ss', Now) + 'Виявлено рух!'); Image2.Picture.Bitmap.SaveToFile ( 'alerts \' + FormatDateTime ( 'hhnnss', Now) + '. Bmp'); end; end;

І для більшої гнучкості створимо на формі один CheckBox. Він буде відповідати за включення таймера і початок відстеження змін. Напишемо код для події OnClick для компонента CheckBox:

1 2 3 4 5 6 7 procedure TForm1. CheckBox1Click (Sender: TObject); begin if CheckBox1. Checked = true then Timer1. Enabled: = true else Timer1. Enabled: = false; end; procedure TForm1.CheckBox1Click (Sender: TObject); begin if CheckBox1.Checked = true then Timer1.Enabled: = true else Timer1.Enabled: = false; end;

Ось що у мене вийшло:

Ось що у мене вийшло:

От і все. Додаток готове. У наступній статті я розгляну як отримати зображення з web камери і зберегти його на жорсткому диску в форматі avi.

Тут можна завантажити готову програму з вихідним кодом.



Новости
  • Виртуальный хостинг

    Виртуальный хостинг. Возможности сервера распределяются в равной мере между всеми... 
    Читать полностью

  • Редизайн сайта

    Редизайн сайта – это полное либо частичное обновление дизайна существующего сайта.... 
    Читать полностью

  • Консалтинг, услуги контент-менеджера

    Сопровождение любых интернет ресурсов;- Знание HTML и CSS- Поиск и обновление контента;-... 
    Читать полностью

  • Трафик из соцсетей

    Сравнительно дешевый способ по сравнению с поисковым и контекстным видами раскрутки... 
    Читать полностью

  • Поисковая оптимизация

    Поисковая оптимизация (англ. search engine optimization, SEO) — поднятие позиций сайта в результатах... 
    Читать полностью