iOS手機(jī)攝像頭測(cè)心率

最近在封裝一個(gè)手機(jī)攝像頭測(cè)心率的模塊荒叼,搞得精神各種緊張轿偎,導(dǎo)致吃飯、路上被廓、做夢(mèng)坏晦,甚至都在想這個(gè)東西,就在剛剛終于搞完了嫁乘,寫個(gè)文章慶祝一下昆婿。

原理

簡(jiǎn)單介紹一下,網(wǎng)上可以查到很多關(guān)于手機(jī)測(cè)心率的這種項(xiàng)目蜓斧,大概就是:把手指放在攝像頭和閃光燈上仓蛆,通過(guò)手指處脈搏跳動(dòng)充血導(dǎo)致的細(xì)微顏色變化來(lái)確定心跳波動(dòng),確定波峰波谷挎春,根據(jù)兩個(gè)波峰之間的時(shí)間差來(lái)確定瞬時(shí)心率看疙。

思路

  1. 首先,采集視頻流直奋,根據(jù)拿到的RGB顏色轉(zhuǎn)成HSV顏色集能庆,其實(shí)我們只用到了HSV的H。
  2. 對(duì)拿到的H進(jìn)行一些處理脚线,看跟人喜好或者具體情況搁胆,主要是用于后面的折線圖和計(jì)算瞬時(shí)心率,如果有能力的話可以處理一下噪音數(shù)據(jù)殉挽,因?yàn)榭赡軠y(cè)的時(shí)候手指輕微抖動(dòng)會(huì)造成一些不穩(wěn)定的數(shù)據(jù)丰涉。
  3. 根據(jù)處理后的H就可以進(jìn)行畫折線圖了,我是把處理后的H和時(shí)間戳進(jìn)行了綁定斯碌,用來(lái)后面的計(jì)算心率一死。
  4. 根據(jù)處理后的H來(lái)確定波峰波谷,利用兩個(gè)波谷之間的時(shí)間差計(jì)算心率傻唾。

實(shí)現(xiàn)

大致思路就是上面這樣投慈,下面來(lái)看一下代碼具體實(shí)現(xiàn)以下承耿。

1.首先我先初始化了一些數(shù)據(jù),方便后面使用
// 設(shè)備
@property (strong, nonatomic) AVCaptureDevice           *device;
// 結(jié)合輸入輸出
@property (strong, nonatomic) AVCaptureSession          *session;
// 輸入設(shè)備
@property (strong, nonatomic) AVCaptureDeviceInput      *input;
// 輸出設(shè)備
@property (strong, nonatomic) AVCaptureVideoDataOutput  *output;
// 輸出的所有點(diǎn)
@property (strong, nonatomic) NSMutableArray            *points;

// 記錄浮點(diǎn)變化的前一次的值
static float lastH = 0;
// 用于判斷是否是第一個(gè)福點(diǎn)值
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.設(shè)置視頻采集流,為了節(jié)省內(nèi)存伪煤,我沒(méi)有輸出視頻畫面
 // 開啟閃光燈
  if ([self.device isTorchModeSupported:AVCaptureTorchModeOn]) {
      [self.device lockForConfiguration:nil];
        // 開啟閃光燈
       self.device.torchMode=AVCaptureTorchModeOn;
        // 調(diào)低閃光燈亮度(為了減少內(nèi)存占用和避免時(shí)間長(zhǎng)手機(jī)發(fā)燙)
        [self.device setTorchModeOnWithLevel:0.01 error:nil];
        [self.device unlockForConfiguration];
    }

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

    // 設(shè)置像素輸出格式
    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);
    // 設(shè)置子線程執(zhí)行代理方法
    [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];
    
    // 降低分辨率加袋,減少采樣率(為了減少內(nèi)存占用)
    self.session.sessionPreset = AVCaptureSessionPreset1280x720;
    // 設(shè)置最小的視頻幀輸出間隔
    self.device.activeVideoMinFrameDuration = CMTimeMake(1, 10);

    // 用當(dāng)前的output 初始化connection
    AVCaptureConnection *connection =[self.output connectionWithMediaType:AVMediaTypeVideo];
    [connection setVideoOrientation:AVCaptureVideoOrientationPortrait];

    // 完成編輯
    [self.session commitConfiguration];
    // 開始運(yùn)行
    [self.session startRunning];

這里我降低了閃光燈亮度,降低了分辨率抱既,減少了每秒鐘輸出的幀职烧。主要就是為了減少內(nèi)存的占用。(我手里只有一臺(tái)6防泵,沒(méi)有測(cè)其他設(shè)備可不可以)

3.在output的代理方法中采集視頻流
// captureOutput->當(dāng)前output   sampleBuffer->樣本緩沖   connection->捕獲連接
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
    
    //獲取圖層緩沖
    CVPixelBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
    CVPixelBufferLockBaseAddress(imageBuffer, 0);
    uint8_t*buf = (uint8_t *)CVPixelBufferGetBaseAddress(imageBuffer);
    size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);
    size_t width = CVPixelBufferGetWidth(imageBuffer);
    size_t height = CVPixelBufferGetHeight(imageBuffer);
    
    float r = 0, g = 0,b = 0;
    float h,s,v;
    // 計(jì)算RGB
    TORGB(buf, width, height, bytesPerRow, &r, &g, &b);
    // RGB轉(zhuǎn)HSV
    RGBtoHSV(r, g, b, &h, &s, &v);
    // 獲取當(dāng)前時(shí)間戳(精確到毫秒)
    double t = [[NSDate date] timeIntervalSince1970]*1000;
    // 返回處理后的浮點(diǎn)值
    float p = HeartRate(h);
    // 綁定浮點(diǎn)和時(shí)間戳
    NSDictionary *point = @{[NSNumber numberWithDouble:t]:[NSNumber numberWithFloat:p]};
    //下面按個(gè)人情況可以進(jìn)行計(jì)算心率或者畫心率圖
}

到這里數(shù)據(jù)已經(jīng)處理好了蚀之,后面可以根據(jù)數(shù)據(jù)畫折線圖,或者計(jì)算心率
計(jì)算RGB

void TORGB (uint8_t *buf, float ww, float hh, size_t pr, float *r, float *g, float *b) {
    float wh = (float)(ww * hh );
    for(int y = 0; y < hh; y++) {
        for(int x = 0; x < ww * 4; x += 4) {
            *b += buf[x];
            *g += buf[x+1];
            *r += buf[x+2];
        }
        buf += pr;
    }
    *r /= 255 * wh;
    *g /= 255 * wh;
    *b /= 255 * wh;
}

RGB轉(zhuǎn)HSV

void RGBtoHSV( float r, float g, float b, float *h, float *s, float *v ) {
    float min, max, delta;
    min = MIN( r, MIN(g, b ));
    max = MAX( r, MAX(g, b ));
    *v = max;
    delta = max - min;
    if( max != 0 )
        *s = delta / max;
    else {
        *s = 0;
        *h = -1;
        return;
    }
    if( r == max )
        *h = ( g - b ) / delta;
    else if( g == max )
        *h = 2 + (b - r) / delta;
    else
        *h = 4 + (r - g) / delta;
    *h *= 60;
    if( *h < 0 )
        *h += 360;
}

根據(jù)h處理浮點(diǎn)

float HeartRate (float h) {
    float low = 0;
    count++;
    lastH = (count==1)?h:lastH;
    low = (h-lastH);
    lastH = h;
    return low;
}
4.分析數(shù)據(jù)捷泞,計(jì)算心率

這里我糾結(jié)了好長(zhǎng)時(shí)間足删,試了幾種不同的方法,都沒(méi)有一個(gè)比較理想的結(jié)果锁右,計(jì)算出來(lái)的特別不準(zhǔn)失受。后來(lái)看了http://ios.jobbole.com/88158/ 這篇文章,后面優(yōu)化的部分有一個(gè)基音算法咏瑟,雖不明拂到,但覺(jué)厲,對(duì)此表示非常感謝响蕴。吼吼吼谆焊。

原理: 就是說(shuō)劃一個(gè)時(shí)間段,在這個(gè)時(shí)間段里面找到一個(gè)最低峰值,然后確定一個(gè)周期,然后分別在這個(gè)峰值前間隔0.5個(gè)周期1周期里這個(gè)峰值后間隔0.5個(gè)周期1周期里找到一個(gè)最低峰值浦夷。 然后根據(jù)這幾個(gè)值來(lái)確定瞬時(shí)心率辖试。

    - (void)analysisPointsWith:(NSDictionary *)point {
    
    [self.points addObject:point];
    if (self.points.count<=30) return;
    int count = (int)self.points.count;
    
    if (self.points.count%10 == 0) {
        
        int d_i_c = 0;          //最低峰值的位置 姑且算在中間位置 c->center
        int d_i_l = 0;          //最低峰值左面的最低峰值位置 l->left
        int d_i_r = 0;          //最低峰值右面的最低峰值位置 r->right
        
        
        float trough_c = 0;     //最低峰值的浮點(diǎn)值
        float trough_l = 0;     //最低峰值左面的最低峰值浮點(diǎn)值
        float trough_r = 0;     //最低峰值右面的最低峰值浮點(diǎn)值
        
        // 1.先確定數(shù)據(jù)中的最低峰值
        for (int i = 0; i < count; i++) {
            float trough = [[[self.points[i] allObjects] firstObject] floatValue];
            if (trough < trough_c) {
                trough_c = trough;
                d_i_c = i;
            }
        }
        
        // 2.找到最低峰值以后  以最低峰值為中心 找到前0.5-1.5周期中的最低峰值  和后0.5-1.5周期的最低峰值
        
        if (d_i_c >= 1.5*T) {
            
            // a.如果最低峰值處在中心位置, 即距離前后都至少有1.5個(gè)周期
            if (d_i_c <= count-1.5*T) {
                // 左面最低峰值
                for (int j = d_i_c - 0.5*T; j > d_i_c - 1.5*T; j--) {
                    float trough = [[[self.points[j] allObjects] firstObject] floatValue];
                    if (trough < trough_l) {
                        trough_l = trough;
                        d_i_l = j;
                    }
                }
                // 右面最低峰值
                for (int k = d_i_c + 0.5*T; k < d_i_c + 1.5*T; k++) {
                    float trough = [[[self.points[k] allObjects] firstObject] floatValue];
                    if (trough < trough_r) {
                        trough_r = trough;
                        d_i_r = k;
                    }
                }
                
            }
            // b.如果最低峰值右面不夠1.5個(gè)周期 分兩種情況 不夠0.5個(gè)周期和夠0.5個(gè)周期
            else {
                // b.1 夠0.5個(gè)周期
                if (d_i_c <count-0.5*T) {
                    // 左面最低峰值
                    for (int j = d_i_c - 0.5*T; j > d_i_c - 1.5*T; j--) {
                        float trough = [[[self.points[j] allObjects] firstObject] floatValue];
                        if (trough < trough_l) {
                            trough_l = trough;
                            d_i_l = j;
                        }
                    }
                    // 右面最低峰值
                    for (int k = d_i_c + 0.5*T; k < count; k++) {
                        float trough = [[[self.points[k] allObjects] firstObject] floatValue];
                        if (trough < trough_r) {
                            trough_r = trough;
                            d_i_r = k;
                        }
                    }
                }
                // b.2 不夠0.5個(gè)周期
                else {
                    // 左面最低峰值
                    for (int j = d_i_c - 0.5*T; j > d_i_c - 1.5*T; j--) {
                        float trough = [[[self.points[j] allObjects] firstObject] floatValue];
                        if (trough < trough_l) {
                            trough_l = trough;
                            d_i_l = j;
                        }
                    }
                }
            }
            
        }
        // c. 如果左面不夠1.5個(gè)周期 一樣分兩種情況  夠0.5個(gè)周期 不夠0.5個(gè)周期
        else {
            // c.1 夠0.5個(gè)周期
            if (d_i_c>0.5*T) {
                // 左面最低峰值
                for (int j = d_i_c - 0.5*T; j > 0; j--) {
                    float trough = [[[self.points[j] allObjects] firstObject] floatValue];
                    if (trough < trough_l) {
                        trough_l = trough;
                        d_i_l = j;
                    }
                }
                // 右面最低峰值
                for (int k = d_i_c + 0.5*T; k < d_i_c + 1.5*T; k++) {
                    float trough = [[[self.points[k] allObjects] firstObject] floatValue];
                    if (trough < trough_r) {
                        trough_r = trough;
                        d_i_r = k;
                    }
                }

            }
            // c.2 不夠0.5個(gè)周期
            else {
                // 右面最低峰值
                for (int k = d_i_c + 0.5*T; k < d_i_c + 1.5*T; k++) {
                    float trough = [[[self.points[k] allObjects] firstObject] floatValue];
                    if (trough < trough_r) {
                        trough_r = trough;
                        d_i_r = k;
                    }
                }
            }
            
        }
        
        // 3. 確定哪一個(gè)與最低峰值更接近 用最接近的一個(gè)最低峰值測(cè)出瞬時(shí)心率 60*1000兩個(gè)峰值的時(shí)間差
        if (trough_l-trough_c < trough_r-trough_c) {
        
            NSDictionary *point_c = self.points[d_i_c];
            NSDictionary *point_l = self.points[d_i_l];
            double t_c = [[[point_c allKeys] firstObject] doubleValue];
            double t_l = [[[point_l allKeys] firstObject] doubleValue];
            NSInteger fre = (NSInteger)(60*1000)/(t_c - t_l);
            if (self.frequency)
                self.frequency(fre);
            if ([self.delegate respondsToSelector:@selector(startHeartDelegateRateFrequency:)])
                [self.delegate startHeartDelegateRateFrequency:fre];
        } else {
            NSDictionary *point_c = self.points[d_i_c];
            NSDictionary *point_r = self.points[d_i_r];
            double t_c = [[[point_c allKeys] firstObject] doubleValue];
            double t_r = [[[point_r allKeys] firstObject] doubleValue];
            NSInteger fre = (NSInteger)(60*1000)/(t_r - t_c);
            if (self.frequency)
                self.frequency(fre);
            if ([self.delegate respondsToSelector:@selector(startHeartDelegateRateFrequency:)])
                [self.delegate startHeartDelegateRateFrequency:fre];
        }
        // 4.刪除過(guò)期數(shù)據(jù)
        for (int i = 0; i< 10; i++) {
            [self.points removeObjectAtIndex:0];
        }
    }
}

我目前是這樣處理的劈狐,后面是用的前后兩個(gè)峰值與最低峰值最接近的那個(gè)峰值的時(shí)間差罐孝,測(cè)了幾次又和別的app比較了一下,基本都是正確的肥缔,最多也就是上下差1-2次每分鐘莲兢。(在數(shù)據(jù)比較穩(wěn)定的情況下,如果有更好的方法請(qǐng)推薦续膳,謝謝)

5.畫折線圖 這里用到了 CoreGraphics

PS:首先改艇,使用這個(gè)CoreGraphics要在View里面,并且要在View的drawRect:方法中使用坟岔,不然拿不到畫布谒兄。我是為了封裝單獨(dú)建立了一個(gè)UIView的類。

a.首先還是數(shù)據(jù)社付,沒(méi)有數(shù)據(jù)怎么畫
@property (strong, nonatomic) NSMutableArray *points;
// 在init中初始化數(shù)組
self.points = [[NSMutableArray alloc]init];
// 這個(gè)可以翻譯過(guò)來(lái)承疲,也是在init中
self.clearsContextBeforeDrawing = YES;

// 外部調(diào)用方法
- (void)drawRateWithPoint:(NSNumber *)point {
    // 倒敘插入數(shù)組
    [self.points insertObject:point atIndex:0];
    
    // 刪除溢出屏幕數(shù)據(jù)
    if (self.points.count > self.frame.size.width/6) {
        [self.points removeLastObject];
    }
    
    dispatch_async(dispatch_get_main_queue(), ^{
        // 這個(gè)方法自動(dòng)調(diào)取 drawRect:方法
        [self setNeedsDisplay];
    });
}

之前調(diào)setNeedsDisplay,一直沒(méi)有走drawRect:方法邻耕,或者就直走了一次,然后去百度是說(shuō)setNeedsDisplay會(huì)在系統(tǒng)空閑的時(shí)候執(zhí)行drawRect:,然后我嘗試著回歸到主線程中調(diào)用燕鸽,就好了兄世。具體原因不是很清楚,也可能是因?yàn)橐谥骶€程中修改View啊研。

b.畫折線的方法御滩,具體怎么調(diào)整看個(gè)人心情了。
    CGFloat ww = self.frame.size.width;
    CGFloat hh = self.frame.size.height;
    CGFloat pos_x = ww;
    CGFloat pos_y = hh/2;
    // 獲取當(dāng)前畫布
    CGContextRef context = UIGraphicsGetCurrentContext();
    // 折線寬度
    CGContextSetLineWidth(context, 1.0);
    //消除鋸齒
    //CGContextSetAllowsAntialiasing(context,false);
    // 折線顏色
    CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
    CGContextMoveToPoint(context, pos_x, pos_y);
    for (int i = 0; i < self.points.count; i++) {
        float h = [self.points[i] floatValue];
        pos_y = hh/2 + (h * hh/2) ;
        CGContextAddLineToPoint(context, pos_x, pos_y);
        pos_x -=6;
    }
    CGContextStrokePath(context);
c.為了看起來(lái)好看悲伶,我還加了網(wǎng)格艾恼,當(dāng)然也是在drawRect:中調(diào)用的
static CGFloat grid_w = 30.0f;
- (void)buildGrid {
    
    CGFloat wight  = self.frame.size.width;
    CGFloat height = self.frame.size.height;

    // 獲取當(dāng)前畫布
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    CGFloat pos_x = 0.0f;
    CGFloat pos_y = 0.0f;
    
    // 在wight范圍內(nèi)畫豎線
    while (pos_x < wight) {
        // 設(shè)置網(wǎng)格線寬度
        CGContextSetLineWidth(context, 0.2);
        // 設(shè)置網(wǎng)格線顏色
        CGContextSetStrokeColorWithColor(context, [UIColor greenColor].CGColor);
        // 起點(diǎn)
        CGContextMoveToPoint(context, pos_x, 1.0f);
        // 終點(diǎn)
        CGContextAddLineToPoint(context, pos_x, height);
        pos_x +=grid_w;
        //開始劃線
        CGContextStrokePath(context);
    }
    
    // 在height范圍內(nèi)畫橫線
    while (pos_y < height) {
        
        CGContextSetLineWidth(context, 0.2);
        CGContextSetStrokeColorWithColor(context, [UIColor greenColor].CGColor);
        CGContextMoveToPoint(context, 1.0f, pos_y);
        CGContextAddLineToPoint(context, wight, pos_y);
        pos_y +=grid_w;
        CGContextStrokePath(context);
    }
    pos_x = 0.0f; pos_y = 0.0f;
    
    // 在wight范圍內(nèi)畫豎線
    while (pos_x < wight) {
        CGContextSetLineWidth(context, 0.1);
        CGContextSetStrokeColorWithColor(context, [UIColor greenColor].CGColor);
        CGContextMoveToPoint(context, pos_x, 1.0f);
        CGContextAddLineToPoint(context, pos_x, height);
        pos_x +=grid_w/5;
        CGContextStrokePath(context);
    }
    
    // 在height范圍內(nèi)畫橫線
    while (pos_y < height) {
        CGContextSetLineWidth(context, 0.1);
        CGContextSetStrokeColorWithColor(context, [UIColor greenColor].CGColor);
        CGContextMoveToPoint(context, 1.0f, pos_y);
        CGContextAddLineToPoint(context, wight, pos_y);
        pos_y +=grid_w/5;
        CGContextStrokePath(context);
    }

}

總結(jié)

沒(méi)有圖,沒(méi)有效果麸锉,只有思路和代碼,我把封裝好的代碼放在了GitHub上舆声,地址:https://github.com/YvanLiu/HeartBeatsPlugin.git
寫這個(gè)功能的時(shí)候花沉,自己有很多思考,也參考了很多其他人的博客媳握、代碼還有別人的畢業(yè)論文碱屁,呵呵呵,還問(wèn)了幾個(gè)學(xué)醫(yī)的同學(xué)蛾找,代碼不難娩脾,數(shù)據(jù)處理的部分可能不太好弄,但是寫完還是有點(diǎn)成就感的打毛。
代碼里還存在很多問(wèn)題柿赊,心率的計(jì)算還存在很高的錯(cuò)誤率,現(xiàn)在正在想辦法改進(jìn)幻枉,歡迎指正碰声,歡迎批評(píng),歡迎提問(wèn)熬甫。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末胰挑,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子椿肩,更是在濱河造成了極大的恐慌瞻颂,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,406評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件郑象,死亡現(xiàn)場(chǎng)離奇詭異贡这,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)扣唱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,395評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門藕坯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)团南,“玉大人,你說(shuō)我怎么就攤上這事炼彪⊥赂” “怎么了?”我有些...
    開封第一講書人閱讀 167,815評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵辐马,是天一觀的道長(zhǎng)拷橘。 經(jīng)常有香客問(wèn)我,道長(zhǎng)喜爷,這世上最難降的妖魔是什么冗疮? 我笑而不...
    開封第一講書人閱讀 59,537評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮檩帐,結(jié)果婚禮上术幔,老公的妹妹穿的比我還像新娘。我一直安慰自己湃密,他們只是感情好诅挑,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,536評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著泛源,像睡著了一般拔妥。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上达箍,一...
    開封第一講書人閱讀 52,184評(píng)論 1 308
  • 那天没龙,我揣著相機(jī)與錄音,去河邊找鬼缎玫。 笑死硬纤,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的碘梢。 我是一名探鬼主播咬摇,決...
    沈念sama閱讀 40,776評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼煞躬!你這毒婦竟也來(lái)了肛鹏?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,668評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤恩沛,失蹤者是張志新(化名)和其女友劉穎在扰,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體雷客,經(jīng)...
    沈念sama閱讀 46,212評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡芒珠,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,299評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了搅裙。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片皱卓。...
    茶點(diǎn)故事閱讀 40,438評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡裹芝,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出娜汁,到底是詐尸還是另有隱情嫂易,我是刑警寧澤,帶...
    沈念sama閱讀 36,128評(píng)論 5 349
  • 正文 年R本政府宣布掐禁,位于F島的核電站怜械,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏傅事。R本人自食惡果不足惜缕允,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,807評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蹭越。 院中可真熱鬧障本,春花似錦、人聲如沸般又。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,279評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)茴迁。三九已至,卻和暖如春萤衰,著一層夾襖步出監(jiān)牢的瞬間堕义,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,395評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工脆栋, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留倦卖,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,827評(píng)論 3 376
  • 正文 我出身青樓椿争,卻偏偏與公主長(zhǎng)得像怕膛,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子秦踪,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,446評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容