首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用HeartBeat检测WebCam?

用HeartBeat检测WebCam?
EN

Stack Overflow用户
提问于 2014-12-05 06:52:01
回答 2查看 3K关注 0票数 6

我试图创建一个应用程序,可以检测心跳使用您的计算机摄像头。我从2周开始就在编写代码,并开发了这个代码,到目前为止我已经完成了。

它是如何工作的?下图..。

  1. 基于opencv的人脸检测
  2. 获取前额图像
  3. 应用过滤器将其转换为灰度图像,您可以跳过它。
  4. 求出每帧绿色像素的平均强度
  5. 将平均值保存到数组中
  6. 应用FFT (我使用了minim )从FFT频谱中提取心脏跳动(这里,我需要一些帮助)

在这里,我需要帮助从FFT频谱中提取心跳。有人能帮我吗。这里是在python中开发的类似的应用程序,但是我无法理解这些代码,所以我正在开发相同的代码。有人能帮助我理解这个python代码中提取心跳的部分吗?

代码语言:javascript
复制
//---------import required ilbrary -----------
import gab.opencv.*;
import processing.video.*;
import java.awt.*;
import java.util.*;
import ddf.minim.analysis.*;
import ddf.minim.*;
//----------create objects---------------------------------
Capture video; // camera object
OpenCV opencv; // opencv object
Minim       minim;
FFT         fft;
//IIRFilter filt;
//--------- Create ArrayList--------------------------------
ArrayList<Float> poop = new ArrayList(); 
float[] sample;
int bufferSize = 128;
int sampleRate = 512;
int bandWidth = 20;
int centerFreq = 80;
//---------------------------------------------------
void setup() {
  size(640, 480); // size of the window
  minim = new Minim(this);
  fft = new FFT( bufferSize, sampleRate);
  video = new Capture(this, 640/2, 480/2); // initializing video object
  opencv = new OpenCV(this, 640/2, 480/2); // initializing opencv object
  opencv.loadCascade(OpenCV.CASCADE_FRONTALFACE);  // loading haar cscade file for face detection
  video.start(); // start video
}

void draw() {
  background(0);
  // image(video, 0, 0 ); // show video in the background
  opencv.loadImage(video);
  Rectangle[] faces = opencv.detect();
  video.loadPixels();
  //------------ Finding faces in the video ----------- 
  float gavg = 0;
  for (int i = 0; i < faces.length; i++) {
    noFill();
    stroke(#FFB700); // yellow rectangle
    rect(faces[i].x, faces[i].y, faces[i].width, faces[i].height); // creating rectangle around the face (YELLOW)
    stroke(#0070FF); //blue rectangle
    rect(faces[i].x, faces[i].y, faces[i].width, faces[i].height-2*faces[i].height/3); // creating a blue rectangle around the forehead
    //-------------------- storing forehead white rectangle part into an image -------------------
    stroke(0, 255, 255);
    rect(faces[i].x+faces[i].width/2-15, faces[i].y+15, 30, 15);
    PImage img = video.get(faces[i].x+faces[i].width/2-15, faces[i].y+15, 30, 15); // storing the forehead aera into a image
    img.loadPixels();
    img.filter(GRAY); // converting capture image rgb to gray
    img.updatePixels();

    int numPixels = img.width*img.height;
    for (int px = 0; px < numPixels; px++) { // For each pixel in the video frame...
      final color c = img.pixels[px];
      final color luminG = c>>010 & 0xFF;
      final float luminRangeG = luminG/255.0;
      gavg = gavg + luminRangeG;
    }

    //--------------------------------------------------------
    gavg = gavg/numPixels;
    if (poop.size()< bufferSize) {
      poop.add(gavg);
    }
    else poop.remove(0);
  }
  sample = new float[poop.size()];
  for (int i=0;i<poop.size();i++) {
    Float f = (float) poop.get(i);
    sample[i] = f;
  }

  if (sample.length>=bufferSize) {
    //fft.window(FFT.NONE); 
    fft.forward(sample, 0);
    //    bpf = new BandPass(centerFreq, bandwidth, sampleRate);
    //    in.addEffect(bpf);
    float bw = fft.getBandWidth(); // returns the width of each frequency band in the spectrum (in Hz).
    println(bw); // returns 21.5332031 Hz for spectrum [0] & [512]

    for (int i = 0; i < fft.specSize(); i++)
    {
      // println( " Freq" + max(sample));
      stroke(0, 255, 0);
      float x = map(i, 0, fft.specSize(), 0, width);
      line( x, height, x, height - fft.getBand(i)*100);
     // text("FFT FREQ " + fft.getFreq(i), width/2-100, 10*(i+1));
     // text("FFT BAND " + fft.getBand(i), width/2+100, 10*(i+1));
    }
  }
  else {
    println(sample.length + " " + poop.size());
  }
}

void captureEvent(Capture c) {
  c.read();
}
EN

回答 2

Stack Overflow用户

发布于 2014-12-05 13:38:11

FFT应用于有128个样本的窗口中。

代码语言:javascript
复制
int bufferSize = 128;

在绘制方法期间,样本被存储在阵列中,直到填充要应用的FFT的缓冲器。然后,缓冲区保持满。若要插入新示例,将删除最旧的样本。gavg是平均灰色通道的颜色。

代码语言:javascript
复制
gavg = gavg/numPixels;
if (poop.size()< bufferSize) {
  poop.add(gavg);
}
else poop.remove(0);

顶便便取样

代码语言:javascript
复制
sample = new float[poop.size()];
for (int i=0;i < poop.size();i++) {
    Float f = (float) poop.get(i);
    sample[i] = f;
}

现在可以将FFT应用于示例数组

代码语言:javascript
复制
fft.forward(sample, 0);

在代码中只显示频谱结果。必须计算心跳频率。对于fft中的每个波段,您必须找到最大值,该位置是心跳的频率。

代码语言:javascript
复制
for(int i = 0; i < fft.specSize(); i++)
{ // draw the line for frequency band i, scaling it up a bit so we can see it
    heartBeatFrequency = max(heartBeatFrequency,fft.getBand(i));
}

然后得到带宽来知道频率。

代码语言:javascript
复制
float bw = fft.getBandWidth();

调整频率。

代码语言:javascript
复制
heartBeatFrequency = fft.getBandWidth() * heartBeatFrequency ;
票数 3
EN

Stack Overflow用户

发布于 2018-08-06 09:51:20

在得到样本大小128个(即bufferSize值或大于这个值)后,用样本数组进行快速傅立叶变换,然后得到光谱的峰值,这将是我们的heartBeatRate,下面的文章解释了相同的内容:

  1. 从视频中测量心率-伊莎贝尔布什-斯坦福- 链接 (图2第4页解释了这一点)。
  2. 使用Webcam . Rahman,M.U. Ahmed,S. Begum,P. Funk - 链接从面部RGB彩色视频实时监测心率(第4页)

在看了你的问题后,我想让我把手放在这个上面,我试着为这个做一个存储库

嗯,如果有人能看一下的话,会有一些问题。

谢谢大卫·克利夫特回答,它帮了很多忙。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27310426

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档