Комментарии 72
Хотелось бы Фурье образ увидеть в качестве иллюстрации. И ещё вопрос: при каком освещении Вы снимали?
Искусственное освещение может мерцать, идеально проверить ещё при солнечном освещении.
Поддержу.
Даже искусственное освещение может меняться по десятку причин: например, прошёл кто-то в двух метрах от кадра, бросил невнятную тень на стену – привет, картинка расценивается как изменившаяся (на примере видеонаблюдения видел массу таких срабатываний).
А вот 50Гц — самое то.
Очевидно, чтобы заметить пульсации 50Гц, надо получать картинку с камеры чаще, чем 50 раз в секундуНа самом деле не совсем так. Скажем камера с 30 кадрами в секунду тоже даст возможнось заметить пульсации 50гц. Измерить 50гц не сможете, но именно заметить пульсацию — вполне.
И еще надо помнить, что частота кадров не однозначно определяет выдержку камеры. Вполне возможна ситуация 30 к/с камеры с выдержкой кадра 1/90.
ru.dsplib.org/content/discrete_aliasing/discrete_aliasing.html
Можно оцифровывать сигналы из зон Найквиста высших порядков (выше частоты дискретизации АЦП), но в случае света непонятно как быть с фильтрацией. В радиотехнике это работает, а вот в оптике хз.
менно FFT позволит отфильтровать все, кроме частот в заданном диапазоне возможных значений пульса. Пульс достаточно инертно меняется и, обычно, достатчно стабилен, наверно можно искать на фурье-спектре экстремум в заданной области допустимых пульсов, а чтобы помехи мешали еще меньше, применить сверху фильтр калмана или тупо медианный фильтр хотя бы.
Чёрт, а я по описанию вначале подумал, что смарт просто держать в руках, не направляя на себя – и пульс ловит по синхронизированным с ним микродвижениям (есть подобная прога, работающая по акселерометру или гироскопу).
Чем дело кончилось у автора программы, не знаю, но стало интересно проверить, возможно ли это.
Автор упомянутого приложения переодически читает Хабр и просил передать, что у него все хорошо — приложение пока не удалили.
Интересно, что до написания приложения я начинал свои эксперементы с пульсом абсолютно также — с десктопного прототипа на OpenCV. У вас получился очень выразительный код.
Было бы очень интересно почитать продолжение статьи с выдергиванием пульса актера из фильма.
Заменяем строчку:
cap = cv2.VideoCapture(0)
на cap = cv2.VideoCapture("video.mp4")
Тут скорее сложность в том чтобы найти видео, где крупный план и актер неподвижен хотя бы 5 секунд.
Когда я экспериментировал с измерением пульса "по фильмам" у меня были проблемы как раз с тем, что нужно трекать движение лица. Погрешность в треккинге, даже у лучших алгоритмов сильно зашумляла картину.
Было интересно может у кого-нибудь получится выделить пульс лучше.
Так да, нужна привязка к «поверхности», есть программы для программной стабилизации видео с астрономических камер, например astrojolo.com/wp-content/uploads/2019/03/pipp_as_01.jpg Возможно сработает, не знаю.
Зачем стабилизировать? Сегментировать и искать непрерывные участки, похожие на кожу. Заодно выделим области примерно одинаково освещенные, чтобы не возиться с тенями и бликами. Главное смотреть на области. где задеектировано лицо.
Усреднять, наверно, имеет смысл, но что если нормировать и считать БПФ от всех точек кожи, а фурье-спектры перемножать. Тогда резонансные участки выделятся, а шум помножится на ноль.
…
Спустя 5 минут. Хз что я тут написал. наверно бред полный.
Запустите скрипт и поэкспериментируйте, сразу видно будет.
Очень здравый подход. Правда, если пытаться найти однотонные участки кожи — будут получатся небольшие плавающие пятна, особенно если тело в движении.
Но после небольшого файн-тюнинга, данная идея стабильно улучшает получаемый спектр. Вот строчка, которая работает в подобном пульсометре на проде (после небольшой чистки от ООП):
removeOtherColors(maskedBitmap, getAverageRgb(maskedBitmap), 0.5f)
Насчет перемножения спектров преобразований Фурье — идея интересная. Вы имеете ввиду неперекрывающиеся отрезки видео?
Есть два вида помех:
- Те, которые имеют определенную частоту (шаги человека, если говорить о фитнес-браслетах)
- Случайные шумы
Разберем оба случая.
- Те шумы, которые имеют стабильную частоту — останутся во всех спектрах и умножение просто уменьшит модуль.
- По идее, делая преобразование Фурье от всего видео-ряда, шумы, которые не имеют гармоники затухают сами, потому что вместо синфазного накопления
cуммы sin(Real_freq x) sin (Assumed_freq x) для всех x, когда real_freq = assumed_freq и сигнал находитсяв фазе с синусойдой assumed_freq.
Мы получаем нечто похожее
random() sin (Assumed_freq * x), что стремиться к 0 при делении на количество точек в ряде.
Время редактирования истекло. В последнем примере имеются ввиду не только sin, но и cos, конечно.
Но даже учитывая то, что шумы гасятся сами самим ПФ, такой подход с умножением может быстрее убрать шумы, чем использование всего ряда. Особенно для гармонических шумов, представленных только на каком-то отрезке измерения. Нужно экспериментировать.
Нужно только обезопасить себя и учесть, что частота сердечного ритма у человека тоже плавает и не выкинуть ее как шум.
Да, я имел в виду, что, вроде бы (хотя я могу и ошибаться), изменение тона кожи из-за оксигенации по всей ее поверхности присходит более-менее синфазно. Если так, то спектры разных участков можно перемножать. Конечно спектр нужно брать не от всего ролика, а от некоторого временнОго окна, важно, чтобы длительность окна многократно превышала длину волны амого медленного из возможных человеческих пульсов.
О… и тут до меня доходит. почему фитнес браслеты заставляют довоьно долго ждать… они просто дожидаются пары десятков биений, чтобы поймать и усреднить нужную гармонику.
Хочется-то, показыать пульс уже по факту детектирования пары тройки ударов, но это чревато ошибками. Короче, нужно просто постоянно мерть пльс в браслетах. не так уж это энергетически накладно.
Но вернёмся к теме. Попробуйте анализировать пульсации не на ровном участке кожи, а, к примеру, на глазу. Почему-то у меня в таком случае происходит максимально четкая детекция ритма. Может быть это какая-то гармоника от лампы накаливания? Всё бы ничего. но примерно такуой же "пульс" детектится у стены, если вовсе выйти из кадра.
Тут нужно смотреть на амплитуду (в этих графиках оси масштабируются автоматически, как я понимаю). Пульс стены должен получится гораздо менее мощный (имеющий меньшую амлитуду), чем пульс глаза.
Тут хитростей особо нет, что-то на изображении пульсирует — осталось понять что. В вашем случае это может быть гармоника лампы накаливания (или баг в алгоритме, но вряд ли).
По поводу пульса в глазах отдельно. Зрачок вполне может расширятся и сужаться в ритм с ударами сердца (такие небольшие гидроудары в мышцах хрусталика, не знаю как подобрать слово лучше). Засчет того что он черный т.е. контрастен — достаточно небольших изменений, чтобы дать красивую картину на графике.
Вот, кстати. попался проектик на js. Если положить палец прямо на объектив камеры ноута, работает очень четко и однозначно. Главный плюс — это работа в браузере. Не надо ничего ставить и запускать.
Уже видел что то подобное, но не помню что именно там делалось
FFT прикручу на досуге
Если наложить два графика, «на глаз» видно что пульс выше после зарядки:

Кстати данный скриншот сделан при солнечном освещении, это к вопросу выше о лампочках.
То есть вы берёте цвет кожи, переводите в оттенки серого, и в таком сигнале видите пульсации? Как-то это слишком просто. Удивительно, что это работает. Но, как пишут комментаторы выше, лучше бы в этом убедиться более надёжно.
Камера снимает, наверное, 30 кадров в секунду, лампочка на потолке мерцает 50 раз в секунду, монитор 60 раз. Какие тут получатся результирующие биения, предсказать не берусь. Но всё же предложу померять пульс у обычной фотографии зафиксированной неподвижно. Вполне возможно получите такой же пульс как у живого человека
Просто я писал точно такое же приложение для одного нашего заказчика в пору работы в аутсорс. Наше приложение называлось PulseR :)
Как я понял, тот чувак так и не смог найти инвестиций, точность измерений была крайне сомнительной — адекватный результат выдавался 1 раз из 10
Со смартфоном действительно сложнее, если его в руках держать, тряска будет сильная. С вебкамерой проще. Тут 95% точности, это фиксация камеры
Вообще-то имеет место быть вот этот эффект.
Главную роль играет не цвет, а свет, поэтому можно видеть пульс даже у рубашки.
И эффективней будет брать local binary pattern, нормировать и прогонять через FFT фильтр, который будет отсекать все частоты, кроме диапазона 40-90 герц.
Вероятно речь шла об этой статье:
https://m.habr.com/ru/post/463281/
За полгода после публикации я немного доработал алгоритм, так что адекватный результат получается немного почаще, чем в 10% случаев. Вот ссылка, если захотите протестировать
Хотя такой способ еще может быть удобен для автоматического взвешивания человека :) Тут алгоритмически может быть много тонкостей, как учитывать вес простыней когда человека нет, как учитывать если спят двое, и пр.
Даже на графике было видно вторую гармонику — вариабельность ритма в зависимости от фазы дыхания (heart rate variability). По этой гармонике можно анализировать некоторые параметры здоровья.
www.murata.com/-/media/webrenewal/campaign/ads/europe/healthcare/bcg_flyer_0901.ashx?la=en-gb
habrastorage.org/webt/uo/if/hj/uoifhjgwjxftvb02lzgntnnmo5c.png
Вот не пойму, если тупо с веб-камеры так надежно виден ритм в реальном времени, какого черта спец-датчики во всяких мифитах сяомевских и прочих смарт-часах так четко не работают? там же и подсветка специальная, и матрица однопиксельная… казалось бы фильтруй и показывай в реальном времени, ан нет, ждать приходится усреднения, натягивать на руку туго и все равно через раз фиксит. Может это у меня такая шерсть густая на руке?
Вживить бы пульсоксиметр под кожу. Например в составе кохлеарного импланта с bluetooth
www.youtube.com/watch?v=CLUWDLKAF1M
Неподвижность обьекта это очень важный критерий, но второй по значимости, как мне кажется.
Мы воспринимаем как данность стабильный уровень осещения. На самом деле, если мы не можем обеспечить константное освещение — модель деградирует гораздо быстрее, чем от смещения обьекта (при условии треккинга) вдоль линии постоянной осещенности.
Почему же инжнеры не могут сделать "нормальные" фитнес-брасслеты? Освещенность на Солнце 30 — 100 тысяч люкс, что очень много. Кожа сама по себе имеет небольшую прозрачность для света, а если браслет еще и установлен неплотно, кожа под браслетом может "немного" подсвечиваться солнцем, что само по себе и неплохо. Если бы не два фактора:
- Мощность диода весьма ограничена и он не может тягаться с Солнцем, если браслет надет неплотно
- При беге или ходьбе изменения освещенности от Солнца еще РИТМИЧНО, что делает задачу распознавания пульса в таких условиях очень сложной
Именно поэтому датчик пытаются немного вдавить в кожу. В теории, для точного измерения во время ходьбы нужно просто закрыть браслет ладонью от посторонних источников света.

github.com/thearn/webcam-pulse-detector.git
"Синус" соотвествует 75/60 гц, т.е. чуть больше одного герца. Эта "ошибка" часто возникает при переходе от привычных нам удар/мин в систему си.
По теме: насколько это перспективно для камер наблюдения? Кажется, что такие подходы в связке с BigData+AI уже делают мир «особого мнения» не столь фантастичным.
Камеры наблюдения слишком далеко, чтобы там такие детали выделить. В описанном здесь примере, если заткнуть камеру пальцем в ярком помешении, пульс будет снят наиболее четко. Если в кадре обычное ищбражение, фрагмент видимой кожи елозит в кадре туда сюда, тени мельтешат, то вам нужна длинная экспозиция, чтобы накопить достаточно статистики для считывания пульса. пульс за такое время и измениться уже может. Да и кто будет ждать перед камерой столько?
Если речь о камере у оператора в банке, которая (камера, а не банка) смотрит на вас, пока вы рассказываете как регулярно будете отдавать кредит, то пульс можно снять легко и не принуждённо. Если речь о камере наблюдения которая смотрит на ваш подъезд или лифт (обычо сверху), то по трем мельтешащим пикселям вряд ли удастся получить стабильный результат.
Дорогущая 4к камера с зумм-объективом и серво-подвесом в качестве камеры наблюдения да. вполне способна зазумить и трекать лицо, чтобы снять пульс, но это всё того не стоит.
В кино это все для пущего футуризма. На деле принцип паретто говорит, что никому не нужен пульс прохожих, чтобы ради этого делать уличные камеры на два порядка дороже.
Определяем пульс по вебкамере в 50 строчек кода