Spaces:
Sleeping
Sleeping
File size: 3,248 Bytes
e698804 |
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 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
import numpy as np
import cv2
import time
from cvzone.FaceDetectionModule import FaceDetector
# Initialization
videoWidth = 160
videoHeight = 120
videoChannels = 3
videoFrameRate = 15
# Helper Methods
def buildGauss(frame, levels):
pyramid = [frame]
for level in range(levels):
frame = cv2.pyrDown(frame)
pyramid.append(frame)
return pyramid
def reconstructFrame(pyramid, index, levels):
filteredFrame = pyramid[index]
for level in range(levels):
filteredFrame = cv2.pyrUp(filteredFrame)
filteredFrame = filteredFrame[:videoHeight, :videoWidth]
return filteredFrame
# Main heart rate function
def heart(video_file_path):
levels = 3
alpha = 170
minFrequency = 1.0
maxFrequency = 2.0
bufferSize = 150
bufferIndex = 0
detector = FaceDetector()
video = cv2.VideoCapture(video_file_path)
firstFrame = np.zeros((videoHeight, videoWidth, videoChannels))
firstGauss = buildGauss(firstFrame, levels + 1)[levels]
videoGauss = np.zeros((bufferSize, firstGauss.shape[0], firstGauss.shape[1], videoChannels))
fourierTransformAvg = np.zeros((bufferSize))
frequencies = (1.0 * videoFrameRate) * np.arange(bufferSize) / (1.0 * bufferSize)
mask = (frequencies >= minFrequency) & (frequencies <= maxFrequency)
bpmCalculationFrequency = 10
bpmBufferIndex = 0
bpmBufferSize = 10
bpmBuffer = np.zeros((bpmBufferSize))
bpmList = []
startTime = time.time()
frameCount = 0
while True:
ret, frame = video.read()
if not ret:
break
elapsedTime = time.time() - startTime
if elapsedTime >= 30:
break
frame, bboxs = detector.findFaces(frame, draw=False)
frameCount += 1
if bboxs:
x1, y1, w1, h1 = bboxs[0]['bbox']
# Check if the bounding box is valid
if x1 >= 0 and y1 >= 0 and w1 > 0 and h1 > 0:
detectionFrame = frame[y1:y1 + h1, x1:x1 + w1]
# Check if detectionFrame is valid and not empty before resizing
if detectionFrame.size != 0:
detectionFrame = cv2.resize(detectionFrame, (videoWidth, videoHeight))
videoGauss[bufferIndex] = buildGauss(detectionFrame, levels + 1)[levels]
fourierTransform = np.fft.fft(videoGauss, axis=0)
fourierTransform[mask == False] = 0
if bufferIndex % bpmCalculationFrequency == 0:
for buf in range(bufferSize):
fourierTransformAvg[buf] = np.real(fourierTransform[buf]).mean()
hz = frequencies[np.argmax(fourierTransformAvg)]
bpm = 60.0 * hz
bpmBuffer[bpmBufferIndex] = bpm
bpmBufferIndex = (bpmBufferIndex + 1) % bpmBufferSize
bpmList.append(bpmBuffer.mean())
bufferIndex = (bufferIndex + 1) % bufferSize
else:
# If no face is detected, skip to the next frame
continue
avgBPM = np.mean(bpmList) if bpmList else 0
video.release()
return avgBPM, frameCount
|