Що таке посилення руху? Посилення руху, це коли ми передбачаємо в який бік сигнал змішається і зрушуємо його в цю сторону далі.
Нехай у нас є одновимірний приймач. На цьому приймачі ми бачимо сигнал I (x, t) = f (x). На зображенні від намальований чорним (для деякого моменту t) .В наступний момент часу сигнал I (x, t + 1) = f (x + Δ) (синій). Посилити цей сигнал, це означає отримати сигнал I '(x, t + 1) = f (x + (1 + α) Δ). Тут α - коефіцієнт посилення. Розклавши його в ряд Тейлора його можна виразити як:
нехай:
Що таке B? Грубо кажучи це I (x, t + 1) - I (x, t). намалюємо:
Звичайно, це неточно, але в якості грубого наближення зійде (блакитний графік показиает форму такого «прібліженонго» сигналу). Якщо ми домножимо B на (1 + α) це і буде «посилення» сигналу. Отримуємо (червоний графік):
У реальних кадрах може бути присутнім кілька рухів, кожне з яких буде йти з різною швидкістю. Наведений вище спосіб - лінійний прогноз, без доопрацювання він обломиться. Але, є класичний підхід для вирішення цієї проблеми, який і використовувався в роботі - розкласти руху по частотним характеристикам (як просторовим, так і тимчасовим).
На першому етапі відбувається розкладання зображення по просторовим частотах. Цей етап, крім того, реалізує отримання диференціала ∂f (x) / ∂x. У першій роботі не розказано, як вони його реалізують. У другій роботі, при використанні фазового підходу, амплітуда і фаза вважалася фільтрами Габбора різного порядку:
Приблизно так я і вчинив, взявши фільтр:
І нормовані його значення, щоб
Тут l - відстані пікселя від центру фільтра. Звичайно, я трохи схалтурив, взявши такий фільтр тільки для одного значення вікна σ. Це дозволило значно прискорити обчислення. При цьому виходить трохи більше розмазана картинка, але я вирішив не прагнути за високою точністю.
Повернемося до формул. Нехай ми хочемо посилити сигнал, що дає характерний відгук на частоті ω в нашій часовій послідовності кадрів. Ми вже підібрали характерний просторовий фільтр з вікном σ. Це дає нам приблизний диференціал в кожній точці. Як зрозуміло з формул - залишається тільки тимчасова функція, що дає відгук на наш рух і коефіцієнт посилення. Множимо на синус тієї частоти, яку хочемо посилити (це і буде функція, що дає тимчасової відгук). отримуємо:
Звичайно, куди простіше, ніж в оригінальній статті, зате трохи менше проблем зі швидкістю.
Код і результат.
Вихідні тексти до першої статті викладені у відкритому доступі на Матлаб. Здавалося б, навіщо винаходити велосипед і писати самому? Але був цілий ряд причин, багато в чому зав'язаних на Матлаб:
- Використання кадру зі зменшеним розміром. Значно прискорює роботу. На форму не став виводити управління розміром кадру, але якщо відкриєте код, то рядок: "_capture.QueryFrame (). Convert
() .PyrDown (). PyrDown (); "це воно - Використання тільки одного просторового фільтра. Для ситуації, коли відомо бажане рух втрати некритичні. Управління параметром фільтру з форми (довжина хвилі фільтра Габора).
- Використання тільки однієї частоти, що підкреслює тимчасової ряд. Звичайно, можна було робити згортку з заздалегідь розрахованим вікном зі спектром майже без втрати продуктивності, але цей спосіб теж непогано працює. З форми управляється або повзунком, або введенням граничних значень.
Маленька ремарка. Всі результати отримані на звичайній веб-камері в домашніх умовах. При використанні камери з хорошими параметрами + штатива + правильного освітлення + придушення 50ГЦ перешкоди якість значно покращиться. Моєю метою не було отримання гарної картинки або поліпшеного алгоритму. Мета - домогтися результату в домашніх умовах. Ну, як бонус, хотілося б ще зробити запис пульсу коли я граю в Starctaft 2 ... Цікаво ж, наскільки e-sport таки спорт.
В результаті логіка роботи виходить:
Все просто до неподобства. Наприклад підсумовування прирощення з кадром реалізовано взагалі так:
(Так, я знаю, що при наявності OpenCV це не оптимальний спосіб)
Десь 90% коду це не ядро, я обвіс навколо нього. Але реалізація ядра дає вже непоганий результат. Видно як роздувається грудна клітка на пару десятків сантиметрів при диханні, видно як набухає вена, як гойдається голова в такт пульсу.
Ось тут докладно пояснюється, чому гойдається голова від пульсу. По суті це віддача від вкидання крові серцем:
Трошки про красу
кількісних характеристики
Видно явний пік на частотах 0.6-1.3, не властивий шуму. Так як дихання не синусоїдальний процес, а процес, що має два явних сплеску (при вдиху-видиху), то частота разностной картинки повинна дорівнювати подвійній частоті дихання. Частота дихання у мене була десь 10 вдихів за 30 секунд (0.3 HZ). Її подвоєння - 0.6HZ. Що приблизно дорівнює виявленому максимуму спектрограми. Але, зрозуміло, про точному значенні говорити не доводиться. Крім дихання витягується безліч дрібної моторики тіла, яка значно псує картину.
Є цікавий пік на 2.625HZ. Судячи з усього це пробивається наводка електромережі на матрицю. По матриці повзуть смуги, які успішно дають максимум на цій частоті.
Між іншим, подвійна частота пульсу повинна лежати приблизно в тому ж діапазоні, а значить цей метод не повинен на ній спрацювати. І дійсно:
В такому спектрі знайти пульс не можна.
В одній з робіт MIT наведено інший спосіб для вимірювання частоти пульсу: обчислювати оптичний потік на обличчі і визначати його по частоті цього потоку. Так я і зробив (на графіку теж спектри):
Краще видно на графіку на якому я відкладав кількість максимумів спектру:
Чому максимум на частоті пульсу * 3 я не знаю як пояснити, але цей максимум точно є і зав'язаний на пульс :)
Хотілося б відзначити тільки, що для отримання пульсу таким способом потрібно сидіти прямо і не рухатися. При грі в Старкрафт це неможливо, частота не знімається. Ех ... А така задумка! Доведеться добувати пульсометр, адже цікаво тепер стало!
Отже, результат
Нічого не ново під місяцем
І наостанок: програміст, будь акуратний!
Алгоритм, судячи з позначками на сайті, патентується. Використання дозволено в освітніх цілях. Звичайно, в Росії не існує патентування алгоритмів. Але будьте обережні, якщо зробите щось на його базі. Поза межами Росії це може стати нелегально.
З.Ю. А підкажіть пульсометр, який би міг дані на комп скидати і, бажано, какой-нить інтерфейс під Android мав?