iOS利用手机摄像头测心率

2020-01-17 21:54:12 来源:易采站长站 作者:丽君

原理

简单介绍一下,网上可以查到很多关于手机测心率的这种项目,大概就是: 把手指放在摄像头和闪光灯上,通过手指处脉搏跳动充血导致的细微颜色变化来确定心跳波动,确定波峰波谷,根据两个波峰之间的时间差来确定瞬时心率。

思路

首先,采集视频流,根据拿到的RGB颜色转成HSV颜色集,其实我们只用到了HSV的H。
对拿到的H进行一些处理,看跟人喜好或者具体情况,主要是用于后面的折线图和计算瞬时心率,如果有能力的话可以处理一下噪音数据,因为可能测的时候手指轻微抖动会造成一些不稳定的数据。
根据处理后的H就可以进行画折线图了,我是把处理后的H和时间戳进行了绑定,用来后面的计算心率。
根据处理后的H来确定波峰波谷,利用两个波谷之间的时间差计算心率。

实现

大致思路就是上面这样,下面来看一下代码具体实现以下。

1.首先我先初始化了一些数据,方便后面使用


// 设备
@property (strong, nonatomic) AVCaptureDevice      *device;
// 结合输入输出
@property (strong, nonatomic) AVCaptureSession     *session;
// 输入设备
@property (strong, nonatomic) AVCaptureDeviceInput   *input;
// 输出设备
@property (strong, nonatomic) AVCaptureVideoDataOutput *output;
// 输出的所有点
@property (strong, nonatomic) NSMutableArray      *points;

// 记录浮点变化的前一次的值
static float lastH = 0;
// 用于判断是否是第一个福点值
static int  count = 0;

// 初始化
self.device   = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
self.session  = [[AVCaptureSession alloc]init];
self.input   = [[AVCaptureDeviceInput alloc]initWithDevice:self.device error:nil];
self.output   = [[AVCaptureVideoDataOutput alloc]init];
self.points   = [[NSMutableArray alloc]init];

2.设置视频采集流,为了节省内存,我没有输出视频画面


// 开启闪光灯
 if ([self.device isTorchModeSupported:AVCaptureTorchModeOn]) {
   [self.device lockForConfiguration:nil];
    // 开启闪光灯
    self.device.torchMode=AVCaptureTorchModeOn;
    // 调低闪光灯亮度(为了减少内存占用和避免时间长手机发烫)
    [self.device setTorchModeOnWithLevel:0.01 error:nil];
    [self.device unlockForConfiguration];
  }

  // 开始配置input output
  [self.session beginConfiguration];

  // 设置像素输出格式
  NSNumber *BGRA32Format = [NSNumber numberWithInt:kCVPixelFormatType_32BGRA];
  NSDictionary *setting =@{(id)kCVPixelBufferPixelFormatTypeKey:BGRA32Format};
  [self.output setVideoSettings:setting];

  // 抛弃延迟的帧
  [self.output setAlwaysDiscardsLateVideoFrames:YES];
  //开启摄像头采集图像输出的子线程
  dispatch_queue_t outputQueue = dispatch_queue_create("VideoDataOutputQueue", DISPATCH_QUEUE_SERIAL);
  // 设置子线程执行代理方法
  [self.output setSampleBufferDelegate:self queue:outputQueue];

  // 向session添加
  if ([self.session canAddInput:self.input])  [self.session addInput:self.input];
  if ([self.session canAddOutput:self.output]) [self.session addOutput:self.output];

  // 降低分辨率,减少采样率(为了减少内存占用)
  self.session.sessionPreset = AVCaptureSessionPreset1280x720;
  // 设置最小的视频帧输出间隔
  self.device.activeVideoMinFrameDuration = CMTimeMake(1, 10);

  // 用当前的output 初始化connection
  AVCaptureConnection *connection =[self.output connectionWithMediaType:AVMediaTypeVideo];
  [connection setVideoOrientation:AVCaptureVideoOrientationPortrait];

  // 完成编辑
  [self.session commitConfiguration];
  // 开始运行
  [self.session startRunning];


            




              

微信扫一扫

易采站长站微信账号