SVM+HOG 之牛奶盒檢測(cè)(三膳音、C++實(shí)戰(zhàn)操作)

由于運(yùn)用的是SVM二分類召衔,因此需要準(zhǔn)備2批數(shù)據(jù),一批正樣本數(shù)據(jù)祭陷,一批負(fù)樣本數(shù)據(jù)苍凛。這樣才能讓SVM進(jìn)行學(xué)習(xí),知道哪些是目標(biāo)兵志,哪些不是目標(biāo)醇蝴。

OpenCV中的SVM+HOG,檢測(cè)的尺寸一共有2種毒姨,一種是64 * 128哑蔫,一種是64 * 64。這里我選擇64 * 128的尺寸弧呐。

我要識(shí)別的是蒙牛牛奶盒
圖片.png

我相信我絕對(duì)是全世界第一個(gè)做牛奶盒識(shí)別的闸迷,哈哈哈哈哈

首先是正樣本:各種背景里有一個(gè)要識(shí)別的物體,如下圖所示俘枫。
尺寸必須為 64 * 128(也可以為64 * 64)腥沽,其他尺寸不行


93.jpg

我采集了各種背景下的牛奶盒圖片,一共521張鸠蚪,也就是說正樣本數(shù)量為521


圖片.png

接著是采集負(fù)樣本: 負(fù)樣本尺寸必須和正樣本一樣今阳,也是64 * 128师溅。
負(fù)樣本很好搞,直接去隨便拍一些圖像中沒有牛奶盒的圖片盾舌,然后在圖片上隨機(jī)裁剪出64 * 128尺寸的圖片就行了


圖片.png

以下是我編寫的在圖片上隨機(jī)裁剪的程序墓臭,每張圖片都能輸出一定數(shù)量的負(fù)樣本

#include <iostream>  
#include <iostream>
#include <fstream>  
#include <stdlib.h> //srand()和rand()函數(shù)  
#include <time.h> //time()函數(shù)  
#include <opencv2/core/core.hpp>  
#include <opencv2/highgui/highgui.hpp>  
#include <opencv2/imgproc/imgproc.hpp>  
#include <opencv2/objdetect/objdetect.hpp>  
#include <opencv2/ml/ml.hpp>  

using namespace std;
using namespace cv;

int imageCount = 0; //裁剪出來的負(fù)樣本圖片個(gè)數(shù)  

int main()
{
    Mat src;
    string ImgName;
    string readAddress = "D:\\盒裝牛奶檢測(cè)\\負(fù)樣本\\負(fù)樣本原始數(shù)據(jù)\\";
    string saveAddress = "D:\\盒裝牛奶檢測(cè)\\負(fù)樣本\\裁剪后負(fù)樣本數(shù)據(jù)\\";
    string saveName;//裁剪出來的負(fù)樣本圖片文件名  
    ifstream fin(readAddress+"NegativeSample_Txt.txt");//打開原始負(fù)樣本圖片文件列表  

    //一行一行讀取文件列表  
    while (getline(fin, ImgName))
    {
        ImgName = readAddress + ImgName;

        src = imread(ImgName);//讀取圖片  
        int originalWidth = src.cols;
        int originalHeight = src.rows;
        int width = originalWidth / 4;
        int height = originalHeight / 4;
        resize(src, src, Size(width, height)); //將圖片尺寸壓縮,以獲取更多信息

        //圖片大小應(yīng)該能能至少包含一個(gè)64*128的窗口  
        if (src.cols >= 64 && src.rows >= 128) //圖片尺寸大小滿足要求
        {
            srand(time(NULL));//設(shè)置隨機(jī)數(shù)種子  

            //從每張圖片中隨機(jī)裁剪200個(gè)64*128大小的負(fù)樣本  
            for (int i = 0; i<200; i++)
            {
                int x = (rand() % (src.cols - 64)); //左上角x坐標(biāo)   rand()%a 能夠得到0到a內(nèi)的隨機(jī)數(shù)
                int y = (rand() % (src.rows - 128)); //左上角y坐標(biāo)  
                Mat imgROI = src(Rect(x, y, 64, 128));

                saveName = saveAddress + to_string(++imageCount) + ".jpg";
                imwrite(saveName, imgROI);//保存文件  

                if (imageCount % 10 == 0) //每生成10張圖片輸出一次數(shù)據(jù)
                {
                    system("cls");
                    cout << endl <<"            原始圖像尺寸: " << originalWidth << " * " << originalHeight << endl;
                    cout << "           resize后圖像尺寸: " << width  << " * " << height << endl;
                    cout << endl << "           已裁剪圖片數(shù)量: " << imageCount << endl;
                }
            }
        }
        
        //break; //--------------
    }

    //system("pause");

    return 0;
}

——————————————————————————————————

在程序中有一段這樣的的代碼
while (getline(fin, ImgName))
這個(gè)意思是逐行讀取文件 fin 中的字符妖谴,將其賦給變量 ImgName

fin 中每一行字符都是一張圖片的文件名窿锉,這樣便能一張一張得讀取圖片了。
問題來了膝舅,怎么得到一個(gè)含有所有圖片文件名的txt文件呢嗡载?
用Windows中的.bat批處理程序就行了!
怎么搞呢仍稀?首先新建一個(gè)txt文件洼滚,把下面這段程序?qū)戇M(jìn)去

dir /b *.jpg>addressTxt.txt

保存,然后把txt文件的后綴改為 .bat 就可以了


圖片.png

然后把這個(gè).bat文件放到你存著圖片的文件夾中技潘,雙擊打開 .bat 文件遥巴,然后就能得到一個(gè)寫著該文件夾中所有文件名稱的txt文件了。


圖片.png

有正樣本和負(fù)樣本享幽,就能開始訓(xùn)練了。我的正樣本數(shù)量是518琉闪,負(fù)樣本數(shù)量是113000。
訓(xùn)練之后會(huì)得到一個(gè)XML文件砸彬,這個(gè)文件中保存著可用于檢測(cè)的SVM參數(shù)颠毙,下次要檢測(cè)的時(shí)候,只用讀取這個(gè)XML文件就行了砂碉,不需要重新訓(xùn)練蛀蜜。

訓(xùn)練完畢,在測(cè)試集圖片中進(jìn)行檢測(cè)增蹭,會(huì)發(fā)現(xiàn)有的牛奶盒沒有檢測(cè)到滴某,還有的沒有牛奶盒的地方卻檢測(cè)到了。
這時(shí)候就要把那些本沒有牛奶盒卻檢測(cè)到了的圖片截取下來滋迈,這些稱為“難樣本”霎奢。
還有那些有牛奶盒卻沒有檢測(cè)到的也截取下來,為AugPosImg圖片饼灿。
這2波圖片加入到數(shù)據(jù)集中幕侠,進(jìn)行第二次訓(xùn)練,就能顯著提升準(zhǔn)確率碍彭。
注意晤硕!
注意悼潭!
注意!
——————————————————————————————
OpenCV3.1中使用 svm = SVM::load<SVM>("svm_image.xml");來讀取XML文件舞箍,
而OpenCV3.2中使用svm->load<SVM>("SVM_HOG.xml");來讀取XML文件舰褪,這是一個(gè)不大不小的坑。
——————————————————————————————
注意疏橄!
注意占拍!
注意!
detectMultiScale()函數(shù)詳解:
detectMultiScale是多尺度檢測(cè)的意思软族,因?yàn)橐桓眻D片里待檢測(cè)目標(biāo)有大有小刷喜,但檢測(cè)的滑動(dòng)窗口是固定的大小,這個(gè)怎么辦立砸?就只能對(duì)圖像進(jìn)行縮放來檢測(cè)掖疮,也就是要把圖像縮小或放大到不同的尺寸來進(jìn)行檢測(cè)。
函數(shù)原型如下:

多尺度.png

1颗祝、img : 輸入的圖像浊闪。圖像可以是彩色也可以是灰度的。

2螺戳、foundLocations : 存取檢測(cè)到的目標(biāo)位置搁宾,為矩陣向量vector

3、hitThreshold (可選) : opencv documents的解釋是特征到SVM超平面的距離的閾值倔幼,所以說這個(gè)參數(shù)可能是控制HOG特征與SVM最優(yōu)超平面間的最大距離盖腿,當(dāng)距離小于閾值時(shí)則判定為目標(biāo)。

4.winStride(可選) : HoG檢測(cè)窗口移動(dòng)時(shí)的步長(水平及豎直)损同。
winStride和scale都是比較重要的參數(shù)翩腐,需要合理的設(shè)置。一個(gè)合適參數(shù)能夠大大提升檢測(cè)精確度膏燃,同時(shí)也不會(huì)使檢測(cè)時(shí)間太長茂卦。

5.padding(可選) : 在原圖外圍添加像素。我自己的經(jīng)驗(yàn)是padding設(shè)為0能很大提高檢測(cè)速度
常見的pad size 有(8, 8), (16, 16), (24, 24), (32, 32).

6.scale(可選)组哩,縮放的尺度等龙。scale參數(shù)可以具體控制金字塔的層數(shù),參數(shù)越小伶贰,層數(shù)越多蛛砰,檢測(cè)時(shí)間也長。通常scale在1.01-1.5這個(gè)區(qū)間黍衙。


scale.png

7.finalThreshold(可選): 這個(gè)參數(shù)不太清楚暴备,據(jù)說是為了優(yōu)化最后的bounding box。我設(shè)為默認(rèn)

8.useMeanShiftGrouping(可選) :bool 類型们豌,決定是否應(yīng)用meanshift 來消除重疊涯捻。default為false浅妆,通常也設(shè)為false,另行應(yīng)用non-maxima supperssion效果更好障癌。

——————————————————————————————

SVM中有一些參數(shù)需要調(diào)整凌外,比如懲罰參數(shù)C,網(wǎng)上沒查到一勞永逸的調(diào)參數(shù)方法涛浙,大部分人都是用的交叉驗(yàn)證康辑,我一般用的默認(rèn)參數(shù),不過OpenCV中提供了SVM的自動(dòng)訓(xùn)練模塊:

                      SVM的自動(dòng)訓(xùn)練模塊
Ptr<cv::ml::TrainData>tdata;    //將訓(xùn)練數(shù)據(jù)和標(biāo)簽整合成tdata
    tdata = TrainData::create(trainingDataMat, cv::ml::SampleTypes::ROW_SAMPLE, labelsMat);
    svm->trainAuto(tdata, 10,
        SVM::getDefaultGrid(SVM::C),
        SVM::getDefaultGrid(SVM::GAMMA),
        SVM::getDefaultGrid(SVM::P),
        SVM::getDefaultGrid(SVM::NU),
        SVM::getDefaultGrid(SVM::COEF),
        SVM::getDefaultGrid(SVM::DEGREE),
        true);

    k_fold: 交叉驗(yàn)證參數(shù)轿亮。訓(xùn)練集被分成k_fold的自子集疮薇,
            其中一個(gè)子集是用來測(cè)試模型,其他子集則成為訓(xùn)練集我注,
            所以按咒,SVM算法復(fù)雜度是執(zhí)行k_fold的次數(shù)。
    *Grid: (6個(gè))對(duì)應(yīng)的SVM迭代網(wǎng)格參數(shù)但骨。
    balanced: 如果是true則這是一個(gè)2類分類問題励七。這將會(huì)創(chuàng)建更多的平衡交叉驗(yàn)證子集。

另外OpenCV中還有關(guān)于SVM+HOG檢測(cè)的GPU加速模塊奔缠,OpenCV官網(wǎng)中有介紹 https://docs.opencv.org/2.4/modules/gpu/doc/object_detection.html

————————————————————————————

這是我訓(xùn)練后的檢測(cè)結(jié)果


2.jpg
3.jpg
4.jpg

可以看到掠抬,其中有一些誤判,本來沒有牛奶盒的地方也框出來了校哎。
我并沒有截出難樣本進(jìn)行第二次訓(xùn)練两波,而且我只要518張正樣本,因此有些誤判也正常闷哆。不過原本我只是做實(shí)驗(yàn)的雨女,就沒進(jìn)行第二次訓(xùn)練了。

后來我又用這個(gè)做過交通錐桶的識(shí)別阳准,可以看出,效果還是很好的馏臭,只是運(yùn)算速度有點(diǎn)慢


交通錐桶識(shí)別.jpg

總代碼:

#include <iostream>
#include <fstream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/ml/ml.hpp>
#include <stdlib.h>
#include<ctime>  //時(shí)間

using namespace std;
using namespace cv;
using namespace cv::ml;

#define PosSamNO 518  //正樣本數(shù)量  519
#define NegSamNO 113000 // 負(fù)樣本數(shù)量 113400
#define HardExampleNO 0 // 難例數(shù)量
#define AugPosSamNO 0 //未檢測(cè)出的正樣本數(shù)量

#define TRAIN 0  //若值為1野蝇,則開始訓(xùn)練

void train_SVM_HOG();
void SVM_HOG_detect();

int main(){

    if (TRAIN)
        train_SVM_HOG();

    SVM_HOG_detect();

    return 0;
}

void train_SVM_HOG()
{

    //                檢測(cè)窗口(64,128),       塊尺寸(16,16),     塊步長(8,8),   cell尺寸(8,8), 直方圖bin個(gè)數(shù)9   
    HOGDescriptor hog(Size(64, 128),        Size(16, 16),       Size(8, 8),     Size(8, 8),         9);
    int DescriptorDim; //HOG描述子的維數(shù),由圖片大小括儒、檢測(cè)窗口大小绕沈、塊大小、細(xì)胞單元中直方圖bin個(gè)數(shù)決定  
    
    Ptr<SVM> svm = SVM::create();
    svm->setType(SVM::C_SVC);
//  svm->setC(0.01); //設(shè)置懲罰參數(shù)C帮寻,默認(rèn)值為1
    svm->setKernel(SVM::LINEAR); //線性核
    svm->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 3000, 1e-6)); //3000是迭代次數(shù)乍狐,1e-6是精確度。
    //setTermCriteria是用來設(shè)置算法的終止條件固逗, SVM訓(xùn)練的過程就是一個(gè)通過 迭代 方式解決約束條件下的二次優(yōu)化問題浅蚪,這里我們指定一個(gè)最大迭代次數(shù)和容許誤

差藕帜,以允許算法在適當(dāng)?shù)臈l件下停止計(jì)算


    string ImgName;//圖片的名字
    string PosSampleAdress = "D:\\盒裝牛奶檢測(cè)\\64_128__牛奶圖片\\";
    string NegSampleAdress = "D:\\盒裝牛奶檢測(cè)\\負(fù)樣本\\裁剪后負(fù)樣本數(shù)據(jù)\\";
    string HardSampleAdress = "";

    ifstream finPos(PosSampleAdress + "PosSamAddressTxt.txt"); //正樣本地址txt文件
    ifstream finNeg(NegSampleAdress + "NegSampleAdressTxt.txt");         //負(fù)樣本地址txt文件

    if (!finPos){
        cout << "正樣本txt文件讀取失敗" << endl;
        return;
    }
    if (!finNeg){
        cout << "負(fù)樣本txt文件讀取失敗" << endl;
        return;
    }

    Mat sampleFeatureMat; // 所有訓(xùn)練樣本的特征向量組成的矩陣,行數(shù)等于所有樣本的個(gè)數(shù)惜傲,列數(shù)為HOG描述子維數(shù)  
    Mat sampleLabelMat;   // 所有訓(xùn)練樣本的類別向量洽故,行數(shù)等于所有樣本的個(gè)數(shù), 列數(shù)為1: 1表示有目標(biāo)盗誊,-1表示無目標(biāo)  

    //---------------------------逐個(gè)讀取正樣本圖片时甚,生成HOG描述子-------------
    for (int num = 0; num < PosSamNO && getline(finPos, ImgName); num++) //getline(finPos, ImgName) 從文件finPos中讀取圖像的名稱ImgName
    {
        system("cls");
        cout << endl << "正樣本處理: " << ImgName << endl;
        ImgName = PosSampleAdress + ImgName;
        Mat src = imread(ImgName);

        vector<float> descriptors; //浮點(diǎn)型vector(類似數(shù)組),用于存放HOG描述子
        hog.compute(src, descriptors, Size(8, 8));//計(jì)算HOG描述子哈踱,檢測(cè)窗口移動(dòng)步長(8,8)

        if (0 == num) //處理第一個(gè)樣本時(shí)初始化特征向量矩陣和類別矩陣荒适,因?yàn)橹挥兄懒颂卣飨蛄康木S數(shù)才能初始化特征向量矩陣 
        {
            DescriptorDim = descriptors.size(); //HOG描述子的維數(shù)   
            //初始化所有訓(xùn)練樣本的特征向量組成的矩陣,行數(shù)等于所有樣本的個(gè)數(shù)开镣,列數(shù)等于HOG描述子維數(shù)sampleFeatureMat  
            sampleFeatureMat = Mat::zeros(PosSamNO + AugPosSamNO + NegSamNO + HardExampleNO, DescriptorDim, CV_32FC1); 
            //初始化訓(xùn)練樣本的類別向量刀诬,行數(shù)等于所有樣本的個(gè)數(shù),列數(shù)等于1   
            sampleLabelMat = Mat::zeros(PosSamNO + AugPosSamNO + NegSamNO + HardExampleNO, 1, CV_32SC1);//sampleLabelMat的數(shù)據(jù)類型必須為有符號(hào)

整數(shù)型
        }

        
        for (int i = 0; i<DescriptorDim; i++)
            sampleFeatureMat.at<float>(num, i) = descriptors[i];

        sampleLabelMat.at<int>(num, 0) = 1;  //樣本標(biāo)簽矩陣 值為1
    }

    if (AugPosSamNO > 0)
    {
        cout << endl << "處理在測(cè)試集中未被被檢測(cè)到的樣本: " << endl;
        ifstream finAug("DATA/AugPosImgList.txt");
        if (!finAug){
            cout << "Aug positive txt文件讀取失敗" << endl;
            return;
        }

        for (int num = 0; num < AugPosSamNO && getline(finAug, ImgName); ++num)
        {
            ImgName = "DATA/INRIAPerson/AugPos/" + ImgName;
            Mat src = imread(ImgName);
            vector<float> descriptors;
            hog.compute(src, descriptors, Size(8, 8));
            for (int i = 0; i < DescriptorDim; ++i)
                sampleFeatureMat.at<float>(num + PosSamNO, i) = descriptors[i];
            sampleLabelMat.at<int>(num + PosSamNO, 0) = 1;
        }
    }

    
    for (int num = 0; num < NegSamNO && getline(finNeg, ImgName); num++)
    {
        system("cls");
        cout << "負(fù)樣本圖片處理: " << ImgName << endl;
        ImgName = NegSampleAdress + ImgName;
        Mat src = imread(ImgName);

        vector<float> descriptors;
        hog.compute(src, descriptors, Size(8, 8));

        for (int i = 0; i<DescriptorDim; i++)
            sampleFeatureMat.at<float>(num + PosSamNO, i) = descriptors[i];

        sampleLabelMat.at<int>(num + PosSamNO + AugPosSamNO, 0) = -1;
    }


    if (HardExampleNO > 0)
    {
        ifstream finHardExample(HardSampleAdress+"HardSampleAdressTxt.txt");
        if (!finHardExample){
            cout << "難樣本txt文件讀取失敗" << endl;
            return;
        }

        for (int num = 0; num < HardExampleNO && getline(finHardExample, ImgName); num++)
        {
            system("cls");
            cout << endl << "處理難樣本圖片: " << ImgName << endl;
            ImgName = HardSampleAdress + ImgName;
            Mat src = imread(ImgName);

            vector<float> descriptors;
            hog.compute(src, descriptors, Size(8, 8));

            for (int i = 0; i<DescriptorDim; i++)
                sampleFeatureMat.at<float>(num + PosSamNO + NegSamNO, i) = descriptors[i];
            sampleLabelMat.at<int>(num + PosSamNO + AugPosSamNO + NegSamNO, 0) = -1;
        }
    }

    cout << endl << "       開始訓(xùn)練..." << endl;
    svm->train(sampleFeatureMat, ROW_SAMPLE, sampleLabelMat);
//  svm->trainAuto(sampleFeatureMat, ROW_SAMPLE, sampleLabelMat,10);


    svm->save("SVM_HOG.xml");
    cout << "       訓(xùn)練完畢哑子,XML文件已保存" << endl;

}


void SVM_HOG_detect()
{
    
    Ptr<SVM> svm = SVM::load<SVM>("SVM_HOG.xml"); //或者svm = Statmodel::load<SVM>("SVM_HOG.xml"); static function
            //Ptr<SVM> svm = SVM::load(path);
            //  cv::Ptr<cv::ml::SVM> svm_ = cv::ml::SVM::load<SVM>(path);
    // svm->load<SVM>("SVM_HOG.xml"); 這樣使用不行

    if (svm->empty()){ //empty()函數(shù) 字符串是空的話返回是true
        cout << "讀取XML文件失敗舅列。" << endl;
        return;
    }
    else{
        cout << "讀取XML文件成功。" << endl;
    }

    
    Mat svecsmat = svm->getSupportVectors();//svecsmat元素的數(shù)據(jù)類型為float

    int svdim = svm->getVarCount();

    int numofsv = svecsmat.rows;

    Mat alphamat = Mat::zeros(numofsv, svdim, CV_32F);//alphamat和svindex必須初始化卧蜓,否則getDecisionFunction()函數(shù)會(huì)報(bào)錯(cuò)
    Mat svindex = Mat::zeros(1, numofsv, CV_64F);

    Mat Result;
    double rho = svm->getDecisionFunction(0, alphamat, svindex);
    alphamat.convertTo(alphamat, CV_32F);//將alphamat元素的數(shù)據(jù)類型重新轉(zhuǎn)成CV_32F

    cout << "1" << endl;
    Result = -1 * alphamat * svecsmat;//float
    cout << "2" << endl;

    vector<float> vec;
    for (int i = 0; i < svdim; ++i)
    {
        vec.push_back(Result.at<float>(0, i));
    }
    vec.push_back(rho);
    
    //保存HOG檢測(cè)的文件
    ofstream fout("HOGDetectorForOpenCV.txt");
    for (int i = 0; i < vec.size(); ++i)
    {
        fout << vec[i] << endl;
    }
    cout << "保存完畢" << endl;

    //----------讀取圖片進(jìn)行檢測(cè)----------------------------
//  HOGDescriptor hog_test;
    HOGDescriptor hog_test(Size(64, 128), Size(16, 16), Size(8, 8), Size(8, 8), 9);
    hog_test.setSVMDetector(vec);

    Mat src = imread("3.jpg",0);
    if (!src.data){
        cout << "測(cè)試圖片讀取失敗" << endl;
        return;
    }
    vector<Rect> found, found_filtered;

    int p = 1;
    resize(src, src, Size(src.cols / p, src.rows / p));

    clock_t startTime, finishTime;
    cout << "開始檢測(cè)" << endl;

    startTime = clock();                                                //1.05
    hog_test.detectMultiScale(src, found, 0, Size(8, 8), Size(32, 32), 1.05, 2);   //多尺度檢測(cè)
    finishTime = clock();
    cout << "檢測(cè)所用時(shí)間為" <<  (finishTime - startTime)*1.0/CLOCKS_PER_SEC << " 秒 " << endl;

    cout << endl << "矩形框的尺寸為 : " << found.size() << endl;

    //找出所有沒有嵌套的矩形,并放入found_filtered中,如果有嵌套的話,則取外面最大的那個(gè)矩形放入found_filtered中
    for (int i = 0; i < found.size(); i++)
    {
        Rect r = found[i];
        int j = 0;
        for (; j < found.size(); j++)
        if (j != i && (r & found[j]) == r)
            break;
        if (j == found.size())
            found_filtered.push_back(r);
    }
    cout << endl << "嵌套矩形框合并完畢" << endl;

    //畫矩形框帐要,因?yàn)閔og檢測(cè)出的矩形框比實(shí)際的框要稍微大些,所以這里需要做一些調(diào)整
    for (int i = 0; i<found_filtered.size(); i++)
    {
        Rect r = found_filtered[i];

        r.x += cvRound(r.width*0.1); //int cvRound(double value) 對(duì)一個(gè)double型的數(shù)進(jìn)行四舍五入,并返回一個(gè)整型數(shù)弥奸!
        r.width = cvRound(r.width*0.8);
        r.y += cvRound(r.height*0.07);
        r.height = cvRound(r.height*0.8);

        rectangle(src, r.tl(), r.br(), Scalar(0, 255, 0), 3);
    }

    imwrite("ImgProcessed.jpg", src);
    namedWindow("src", 0);
    imshow("src", src);
    waitKey(0);
}



最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末榨惠,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子盛霎,更是在濱河造成了極大的恐慌赠橙,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,509評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件愤炸,死亡現(xiàn)場(chǎng)離奇詭異期揪,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)规个,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門凤薛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人诞仓,你說我怎么就攤上這事缤苫。” “怎么了墅拭?”我有些...
    開封第一講書人閱讀 163,875評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵活玲,是天一觀的道長。 經(jīng)常有香客問我,道長舒憾,這世上最難降的妖魔是什么镀钓? 我笑而不...
    開封第一講書人閱讀 58,441評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮珍剑,結(jié)果婚禮上掸宛,老公的妹妹穿的比我還像新娘。我一直安慰自己招拙,他們只是感情好唧瘾,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著别凤,像睡著了一般饰序。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上规哪,一...
    開封第一講書人閱讀 51,365評(píng)論 1 302
  • 那天求豫,我揣著相機(jī)與錄音,去河邊找鬼诉稍。 笑死蝠嘉,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的杯巨。 我是一名探鬼主播蚤告,決...
    沈念sama閱讀 40,190評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼服爷!你這毒婦竟也來了杜恰?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,062評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤仍源,失蹤者是張志新(化名)和其女友劉穎心褐,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體笼踩,經(jīng)...
    沈念sama閱讀 45,500評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡逗爹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了嚎于。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片掘而。...
    茶點(diǎn)故事閱讀 39,834評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖匾旭,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情圃郊,我是刑警寧澤价涝,帶...
    沈念sama閱讀 35,559評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站持舆,受9級(jí)特大地震影響色瘩,放射性物質(zhì)發(fā)生泄漏伪窖。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評(píng)論 3 328
  • 文/蒙蒙 一居兆、第九天 我趴在偏房一處隱蔽的房頂上張望覆山。 院中可真熱鬧,春花似錦泥栖、人聲如沸簇宽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽魏割。三九已至,卻和暖如春钢颂,著一層夾襖步出監(jiān)牢的瞬間钞它,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評(píng)論 1 269
  • 我被黑心中介騙來泰國打工殊鞭, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留遭垛,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,958評(píng)論 2 370
  • 正文 我出身青樓操灿,卻偏偏與公主長得像锯仪,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子牲尺,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評(píng)論 2 354

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

  • 1卵酪、通過CocoaPods安裝項(xiàng)目名稱項(xiàng)目信息 AFNetworking網(wǎng)絡(luò)請(qǐng)求組件 FMDB本地?cái)?shù)據(jù)庫組件 SD...
    陽明先生_X自主閱讀 15,980評(píng)論 3 119
  • 油井 我已經(jīng)在這個(gè)平凡的小鎮(zhèn)生活了二十幾年了 它對(duì)我來說渺小而無奇 我每天唯一做的事情就是把頭抵在桌子上看著一天天...
    casho閱讀 219評(píng)論 0 2
  • 2017年7月2日晚飯時(shí)間溃卡,我和姥姥在吃飯,爸爸已經(jīng)吃完了蜒简,寶寶一直在玩瘸羡,不吃。 “拉粑粑” 寶寶抱著肚子看著我們...
    信時(shí)光閱讀 184評(píng)論 0 0
  • “我回來了”搓茬,男人關(guān)上門犹赖,走到喜歡的女人和小孩兒邊上說:“每天回家都能說‘我回來了’的感覺真好”。(來自一部電...
    箜蒔閱讀 417評(píng)論 0 0
  • 還記得小時(shí)候卷仑,拿到一毛錢都會(huì)特別興奮峻村!我們不敢賴著別人,就賴著您锡凝,糾纏不放粘昨,到最后,您還是會(huì)給我們幾毛…… 還記得...
    夢(mèng)行烏托邦閱讀 374評(píng)論 0 0