Найти - Пользователи
Полная версия: Получение пульса по веб камере, OpenCV, FFT
Начало » Python для экспертов » Получение пульса по веб камере, OpenCV, FFT
1
dem66
Здравствуйте, пишу детектор пульса с использованием OpenCV, дело дошло до того из спектра надо выбрать нужную частоту смены цветов.

В области лба вычисляются средние значения красного и синего цвета для текущего кадра. Формируется массив разностей значений цвета для n последних кадров

Делаю я это вот так:
import random
from PIL import Image
def averageColor(cv, image, frequency = 1):
	size = cv.GetSize(image)
	
	width  = size[0]
	height = size[1]
	count  = int(round((frequency * (width * height)) / 100))
	
	sumR = 0
	sumB = 0
	squareR = 0
	squareB = 0
	
	rgb = []
	
	i=0
	while i < count:
		x = random.randint(0, width  - 1)
		y = random.randint(0, height  - 1)
		
		color = image[y, x]
		
		sumR += color[0];
                sumB += color[2];
		
		averR = int((sumR / count) << 16)
		averB = int( sumB / count)
		
		i += 1
      return (averR, averB)

Получаю массив разностей:
colors = average.averageColor(cv, image)
diff = colors[0] ^ colors[1]

Дальше к нему надо применить БПФ:
К массиву применяется быстрое преобразование Фурье. В полученном спектре ищется частота, удовлетворяющая следующим условиям: лежит в диапазоне, соответствующем пульсу (0.9-2.0 Гц); является максимальной в указанном диапазоне.

И тут собственно и застрял. Пробовал сделать как на скрине, не помогло.

Взято отсюда http://www.mce.su/rus/presentations/p184924/
Singularity
dem66
В первом сообщении сделал опечатку, массив разностей получаю вот так:
c = 1
red = []
blue = []
while True:
	#тут находится лицо и производятся прочие операции..
	
	#передаем на обработку участок лба
	av = average.averageColor(cv, forehead)
	red.append(av[0])
	blue.append(av[1])
	
	#каждые десять кадров получаем массив различий пикселей
	if c == 10:
		red = set(red)
		blue = set(blue)
		
		diff = list(red ^ blue)
		
		print diff
		
		c = 1
		red = []
		blue = []
	else:
		c += 1

Вроде даже удалось получить нечто похожее на спектр:
import numpy as np
import matplotlib.pyplot as plt
Fs = 100                        # sampling rate
Ts = 1.0/Fs                      # sampling interval
signal = [10,11,12,13,-5,-6,-7,8,10,11,12]
n = len(signal)                       # length of the signal
k = np.arange(n)
T = n/Fs
frq = k/T # two sides frequency range
freq = frq[range(n/2)]           # one side frequency range
print freq
print "\n"
Y = np.fft.fft(signal)/n              # fft computing and normalization
Y = abs(Y[range(n/2)])
print Y
plt.plot(freq, Y, 'r-')
plt.xlabel('freq (Hz)')
plt.ylabel('|Y(freq)|')
plt.show()

Правильно ли я делаю?

doza_and
dem66
Правельно ли я делаю?
:) Нет. Правельно -> Правильно
С точки зрения подхода думаю тут надо действовать по другому. Фурье преобразование это вторичный метод улучшения распознавания
От плетизмографии реализуемый вами метод мало отличается. Думаю вам надо начать с обычной плетизмографии. Для нее сигнал будет хорошо выделяться даже по амплитуде. Относя детектор от поверхности и снижая внешнюю подсветку вы можете постепенно отточить алгоритмы обработки. Будет очень полезно обучение с известным сигналом (т.е. настройка в случае когда одновременно пишется обычная электрокардиограмма и видеоряд) . Далее надо оценить какое количество информации несет RGB (среднее по лбу) о давлении. Это можно сделать на глаз или количественно. А дальше(если информация есть) надо построить функцию P(R,G,B) или P(R,G,B,R1,G1,B1) с единицами это сигнал с образцовой поверхности. Для построения функции можно воспользоваться например http://scikit-learn.org/stable/ Будет время в выходные, может получу для вас синхронизированные кардиограму и видеоряд.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB