OpenCV算法學(xué)習(xí)筆記之閾值分割

此系列的其他文章:
OpenCV算法學(xué)習(xí)筆記之初識(shí)OpenCV
OpenCV算法學(xué)習(xí)筆記之幾何變換
OpenCV算法學(xué)習(xí)筆記之對(duì)比度增強(qiáng)
OpenCV算法學(xué)習(xí)筆記之平滑算法
OpenCV算法學(xué)習(xí)筆記之形態(tài)學(xué)處理
OpenCV算法學(xué)習(xí)筆記之邊緣檢測(cè)(一)
OpenCV算法學(xué)習(xí)筆記之邊緣處理(二)
OpenCV算法學(xué)習(xí)筆記之形狀檢測(cè)

更多文章可以訪(fǎng)問(wèn)我的博客Aengus | Blog

閾值分割也被稱(chēng)為二值化處理宾濒,簡(jiǎn)單來(lái)說(shuō)就是將圖像灰度值大于(或小于)閾值的像素調(diào)整為255可都,將小于(或大于)閾值的像素灰度值調(diào)整為0,這樣最終輸出圖像只有兩種灰度值(255和0)截碴。對(duì)對(duì)比度比較弱的圖像進(jìn)行閾值分割前常常要進(jìn)行對(duì)比度增強(qiáng)肴楷。常見(jiàn)的閾值分割技術(shù)有全局閾值分割和自適應(yīng)局部閾值分割。

全局閾值分割

原理

顧名思義,全局閾值分割就是將整個(gè)圖像灰度值大于閾值(thresh)的像素調(diào)為白色,小于或等于閾值的調(diào)整為黑色拧略,也可以反過(guò)來(lái)。用公式表達(dá)就是:
O(r,c)=\left\{ \begin{align} 255,I(r,c)>thresh \\ 0, I(r,c) \leq thresh \end{align} \right.
其中O(r,c)代表輸出圖像位于第r行第c列的像素的灰度值瘪弓,I(r,c)代表輸入圖像位于第r行第c列的像素的灰度值。

實(shí)現(xiàn)

用Python實(shí)現(xiàn)就是

import cv2 as cv
import numpy as np

src = cv.imread("inputImage.png")
thresh = int(input())
dst = src.copy()    # 一般不處理原圖
dst[dst>thresh] = 255
dst[dst<=thresh] = 0

OpenCV提供函數(shù)threshold(InputArray src, OutputArray dst, double thresh, double maxval, int type)實(shí)現(xiàn)了全局閾值分割禽最,其中maxval是圖像二值化顯示時(shí)的最大值腺怯,一般設(shè)置為255;type為類(lèi)型川无,有如下取值:

enum ThresholdTypes {
    THRESH_BINARY     = 0, // 大于thresh的設(shè)為maxval
    THRESH_BINARY_INV = 1, // 大于thresh的設(shè)為0
    THRESH_TRUNC      = 2, // 大于thresh的使用threshold函數(shù)呛占,小于等于的不處理
    THRESH_TOZERO     = 3, // 大于thresh的不處理,小于等于的設(shè)為0
    THRESH_TOZERO_INV = 4, // 大于thresh的設(shè)為0懦趋,小于等于的不處理
    THRESH_MASK       = 7,
    THRESH_OTSU       = 8, // 使用OTSU算法計(jì)算出閾值
    THRESH_TRIANGLE   = 16 // 使用TRIANGLE算法計(jì)算出閾值晾虑,與下文的直方圖技術(shù)法原理類(lèi)似
};

最后兩個(gè)的算法之后再解釋?zhuān)覀兺ǔS眠@兩個(gè)與THRESH_BINARY結(jié)合使用,如type=THRESH_OTSU+THRESH_BINARY代表先用OTSU算法計(jì)算出閾值后再根據(jù)THRESH_BINARY規(guī)則進(jìn)行分割仅叫。

自動(dòng)求取閾值

閾值分割的核心是如何選取閾值帜篇,選取正確的閾值是分割成功的關(guān)鍵。常用的自動(dòng)求全局閾值的算法有直方圖技術(shù)法诫咱,Otsu算法笙隙,熵算法等。

直方圖技術(shù)法

原理

一般來(lái)說(shuō)坎缭,一幅圖如果前景和背景對(duì)比比較明顯的話(huà)竟痰,那么它的直方圖則會(huì)有兩個(gè)比較明顯的峰值签钩。兩個(gè)峰值對(duì)應(yīng)物體內(nèi)部和外部較多數(shù)目的點(diǎn),兩個(gè)峰值之間的波谷對(duì)應(yīng)物體邊緣附近相對(duì)較少數(shù)目的點(diǎn)坏快。直方圖技術(shù)就是首先找到這兩個(gè)峰值铅檩,然后取兩個(gè)峰值之間的波谷位置對(duì)應(yīng)的灰度值,取其作為閾值莽鸿。

上述過(guò)程可能會(huì)有干擾昧旨。由于灰度值在直方圖中的隨機(jī)波動(dòng),兩個(gè)波峰(局部最大值)和它們之間的波谷不能很好的確定富拗,比如兩個(gè)峰值之間可能出現(xiàn)兩個(gè)最小值臼予,為了解決這種干擾, 一般對(duì)直方圖進(jìn)行高斯平滑啃沪,逐漸增加高斯濾波的標(biāo)準(zhǔn)差粘拾,直到能從平滑后的直方圖只存在兩個(gè)唯一的波峰和它們之間唯一的最小值,但這種方式需要手動(dòng)調(diào)節(jié)创千,可以通過(guò)以下方式進(jìn)行自動(dòng)選取波峰和波谷:

第一步:找到灰度直方圖的第一個(gè)峰值缰雇,并找到其對(duì)應(yīng)的灰度值。顯然追驴,灰度直方圖的最大值就是第一個(gè)峰值械哟,將其對(duì)應(yīng)的灰度值用fristPeak表示;

第二步:找到直方圖的第二個(gè)峰值殿雪,并找到其對(duì)應(yīng)的灰度值暇咆,第二個(gè)峰值不一定是第二大值,因?yàn)樗芸赡艹霈F(xiàn)第一個(gè)峰值的附近丙曙,可以用以下公式計(jì)算:
secondPeak = arg_k max\{ (k-firstPeak)^2 * histogram_I(k) \},0 \leq k \leq 255
也可以用絕對(duì)值的形式:
secondPeak = arg_k max\{ |k-firstPeak| * histogram_I(k) \},0 \leq k \leq 255
其中histogram_I(k)代表灰度值等于k的像素的數(shù)量爸业;

第三步:找到這兩個(gè)峰值之間的波谷,如果出現(xiàn)兩個(gè)或多個(gè)波谷亏镰,則取左側(cè)的波谷即可扯旷,其對(duì)應(yīng)灰度值即為閾值。

Python實(shí)現(xiàn)

在利用直方圖計(jì)算閾值時(shí)索抓,會(huì)計(jì)算一個(gè)直方圖最大值的位置索引钧忽,可以利用numpy的where()函數(shù)返回值等于某個(gè)數(shù)的索引,如

import numpy as np

hist = np.array([1, 3, 9, 2, 8])
max_loc = np.where(hist == np.max(hist))    # max_loc = (array([2], dtype=int64))

如果出現(xiàn)多個(gè)最大值逼肯,那么會(huì)返回存儲(chǔ)最大值的所有位置索引的一維數(shù)組組成的元組耸黑。

下面的函數(shù)是利用直方圖法自動(dòng)求取閾值:

def thresh_two_peaks(image):
    """
    :param image: 輸入圖像
    :return 閾值和閾值分割后結(jié)果組成的二元元組
    """
    # 計(jì)算灰度直方圖
    histogram = calcGrayHist(image)
    # 找到灰度直方圖的最大峰值對(duì)應(yīng)的灰度值
    max_loc = np.where(histogram == np.max(histogram))
    first_peak = max_loc[0][0]
    # 尋找灰度直方圖第二個(gè)峰值對(duì)應(yīng)的灰度值
    measure_dists = np.zeros([256], np.float32)
    for k in range(256):
        measure_dists[k] = pow(k-first_peak, 2) * histogram[k]
    max_loc2 = np.where(measure_dists == np.max(measure_dists))
    second_peak = max_loc2[0][0]
    # 找到兩個(gè)峰之間的最小值對(duì)應(yīng)的灰度值,作為閾值
    thresh = 0
    # 第一個(gè)峰值在第二個(gè)峰值的右邊
    if first_peak > second_peak:
        temp = histogram[int(second_peak): int(first_peak)]
        min_loc = np.where(temp == np.min(temp))
        thresh = second_peak + min_loc[0][0] + 1
    else:
        temp = histogram[int(first_peak): int(second_peak)]
        min_loc = np.where(temp == np.min(temp))
        thresh = first_peak + min_loc[0][0] + 1
    # 找到閾值后進(jìn)行閾值處理汉矿,得到二值圖
    thresh_img = image.copy()
    thresh_img[thresh_img > thresh] = 255
    thresh_img[thresh_img <= thresh] = 0
    
    return (thresh, thresh_img)

上面使用的函數(shù)calcGrayHist()是在《OpenCV算法學(xué)習(xí)筆記之對(duì)比度增強(qiáng)》中的函數(shù)崎坊。

需要注意的是在求兩個(gè)峰值之前的波谷時(shí),需要判斷第二個(gè)峰值是在第一個(gè)峰值的右側(cè)還是左側(cè)洲拇。

C++實(shí)現(xiàn)

int threshTwoPeaks(const Mat &image, Mat &threshOut)
{
    // 計(jì)算灰度直方圖
    Mat histtogram = calcGrayHist(image);
    // 找到灰度直方圖中最大峰值對(duì)應(yīng)的灰度值
    Point firstPeakLoc;
    minMaxLoc(histogram, NULL, NULL, NULL, &firstPeakLoc);
    int firstPeak = firstPeakLoc.x;
    // 尋找灰度直方圖第二個(gè)峰值對(duì)應(yīng)的灰度值
    Mat measureDists = Mat::zeros(Size(256, 1), CV_32FC1);
    for (int k=0; k<256; k++){
        int histK = histogram.at<int>(0, k);
        measureDists.at<float>(0, k) = pow(float(k - firstPeak), 2)*histK;
    }
    Point secondPeakLoc;
    minMaxLoc(measureDists, NULL, NULL, NULL, &secondPeakLoc);
    int secondPeak = secondPeakLoc.x;
    // 找到兩個(gè)峰值之間最小值對(duì)應(yīng)的灰度值奈揍,作為閾值
    Point threshLoc;
    int thresh = 0;
    // 第一個(gè)峰值在第二個(gè)峰值左側(cè)
    if (firstPeak < secondPeak){
        minMaxLoc(histogram.colRange(firstPeak, secondPeak), NULL, NULL, &threshLoc);
        thresh = firstPeak + threshLoc.x + 1;
    }else{
        minMaxLoc(histogram.colRange(secondPeak, firstPeak), NULL, NULL, &threshLoc);
        thresh = secondPeak + threshLoc.x + 1;
    }
    // 閾值分割
    threshold(image, threshOut, thresh, 255, THRESH_BINARY);
    
    return thresh;
}

Otsu算法

原理

Otsu其實(shí)是利用最大方差法曲尸。假設(shè)輸入圖像I的高為H,寬為W男翰,histogram_I代表其歸一化所獲得的圖像灰度直方圖另患,histogram_I (k)代表灰度值等于k的像素點(diǎn)的個(gè)數(shù)在圖像中占的比例,0 \leq k \leq 255蛾绎,則步驟為:

第一步:計(jì)算灰度直方圖的零階累積矩昆箕,也稱(chēng)為累加直方圖:
zeroCumuMoment(k) = \sum^k_{i=0}histogram_I(i), k \in [0, 255]
第二步:計(jì)算灰度直方圖的一階累積矩:
oneCumuMoment(k) = \sum^k_{i=0} (i * histogram_I(i)), k \in [0, 255]
第三步:計(jì)算圖像I總體的灰度平均值mean,其實(shí)就是k=255時(shí)的一階累積矩租冠,即:
mean = oneCumuMoment(255)
第四步:計(jì)算每一個(gè)灰度級(jí)作為閾值時(shí)鹏倘,前景區(qū)域的平均灰度、背景區(qū)域的平均灰度與整幅圖像的平均灰度的方差顽爹,對(duì)方差的衡量采用以下度量:
\sigma^2(k) = \frac{(mean * zeroCumuMoment(k) - oneCumuMoment(k))^2}{zeroCumuMoment(k) * (1 - zeroCumuMoment(k))}, k \in [0, 255]
第五步:找到上述最大\sigma^2(k)纤泵,然后對(duì)應(yīng)的k即為Otsu自動(dòng)選取的閾值,即:
thresh = arg_{k \in [0, 255]} max(\sigma^2(k))

C++實(shí)現(xiàn)

需要注意的是在求方差時(shí)可能出現(xiàn)分母為0的情況镜粤。

/**
 * Otsu算法
 *
 * @param image 輸入的單通道8位圖
 * @param otsuThreshImage Otsu算法閾值分割后的圖像
 * @return Otsu得到的閾值
 */
int otsu(const Mat &image, Mat &otsuThreshImage)
{
    // 計(jì)算灰度直方圖
    Mat histogram = calcGrayHist(image);
    // 歸一化灰度直方圖
    Mat normHist;
    histogram.convertTo(normHist, CV_32FC1, 1.0/(image.rows*image.cols), 0.0);
    // 計(jì)算累加直方圖(零階累積矩)和一階累積矩
    Mat zeroCumuMoment = Mat::zeros(Size(256, 1), CV_32FC1);
    Mat oneCumuMoment = Mat::zeros(Size(245, 1), CV_32FC1);
    for (int i = 0; i < 256; i++)
    {
        if (i == 0)
        {
            zeroCumuMoment.at<float>(0, i) = normHist.at<float>(0, i);
            oneCumuMoment.at<float>(0, i) = i * normHist.at<float>(0, i);
        } else {
            zeroCumuMoment.at<float>(0, i) = normHist.at<float>(0, i-1) + normHist.at<float>(0, i);
            oneCumuMoment.at<float>(0, i) = normHist.at<float>(0, i-1) + i * normHist.at<float>(0, i);
        }
    } 
    // 計(jì)算類(lèi)間方差
    Mat variance = Mat::zeros(Size(256, 1), CV_32FC1);
    // 總平均值
    float mean = oneCumuMoment.at<float>(0, 255);
    for (int i = 0; i < 255; i++)
    {
        if (zeroCumuMoment.at<float>(0, i) == 0 || zeroCumuMoment.at<float>(0, i) == 1)
        {
            variance.at<float>(0, i) = 0;
        } else {
            float cofficient = zeroCumuMoment.at<float>(0, i) * (1.0-zeroCumuMoment.at<float>(0, i));
            variance.at<float>(0, i) = pow(mean*zeroCumuMoment.at<float>(0, i)-oneCumuMoment.at<float>(0, i), 2.0) / cofficient;
        }
    }
    // 找到閾值
    Point maxLoc;
    mimMaxLoc(variance, NULL, NULL, NULL, &maxLoc);
    int otsuThresh = maxLoc.x;
    // 閾值處理
    threshold(image, otsuThreshImage, otsuThresh, 255, THRESH_BINARY);
    
    return otsuThresh;
}

對(duì)于我們?cè)谧铋_(kāi)始的全局閾值分割里提到的OpenCV提供的函數(shù)threshold中捏题,也可以將參數(shù)type設(shè)置為THRESH_OTSU以實(shí)現(xiàn)OTSU算法求取閾值。

熵算法

原理

信息熵的概念來(lái)源于信息論肉渴。

假設(shè)某個(gè)符號(hào)uN種取值公荧,分別為u_1, u_2, u_3, \dots ,u_N,每種符號(hào)出現(xiàn)的概率分別為p_1, p_2, p_3, \dots , p_N同规,那么該符號(hào)的信息熵為
entropy(u) = - \sum^N_{i=1}p_i log(p_i)
將8位圖圖片看作一種符號(hào)循狰,那么圖片就有256種灰度取值,設(shè)normHist_I為圖片歸一化后的灰度直方圖券勺,每一種取值的概率為normHist(k)晤揣,0 \leq k \leq 255,利用熵計(jì)算閾值的步驟為:

第一步:計(jì)算圖片的累加概率直方圖朱灿,也稱(chēng)為零階累積矩,記為:
cumuHist(k) = \sum^k_{i=0}normHist_I(i), k \in [0, 255]
第二步:計(jì)算各個(gè)灰度值的熵:
entropy(t) = - \sum^t_{k=0}normHist_I (k)log(normHist_I (k)), 0 \leq k \leq 255
第三步:計(jì)算使f(t)=f_1(t) + f_2(t)最大值的t值钠四,該值記為需要的閾值盗扒,其中:
f_1(t) = \frac{entropy(t)}{entropy(255)} \frac{log(cumuHist(t))}{log(max \{ cumuHist(0),cumuHist(1), \dots ,cumuHist(t) \})} \\ f_2(t) =(1 - \frac{entropy(t)}{entropy(255)}) \frac{log(1 - cumuHist(t))}{log(max \{ cumuHist(t+1), \dots ,cumuHist(255) \})}

Python實(shí)現(xiàn)

在第二步的實(shí)現(xiàn)中,由于對(duì)數(shù)的自變量不能為0缀去,如果判斷normHist_I(k)=0侣灶,那么直接令entropy(k)=entropy(k - 1)即可。具體代碼如下:

def thresh_entropy(image):
    rows, cols = image.shape
    # 計(jì)算灰度直方圖
    gray_hist =calcGrayHist(image)
    # 歸一化灰度直方圖缕碎,即概率直方圖
    norm_gray_hist = gray_hist / float(rows*cols)
    # 第一步:計(jì)算累加直方圖褥影,也稱(chēng)為零階累積矩
    zero_cumu_moment = np.zeros([256], np.float32)
    for k in range(256):
        if k == 0:
            zero_cumu_moment[k] = norm_fray_hist[k]
        else:
            zero_cumu_moment[k] = zero_cumu_moment[k-1] + norm_gray_hist[k]
    # 第二步:計(jì)算各個(gè)灰度級(jí)的熵
    entropy = np.zeros([256], np.float32)
    for k in range(256):
        if k == 0:
            if norm_gray_hist[k] == 0:
                entropy[k] = 0
            else:
                entropy[k] = -norm_gray_hist[k] * math.log10(norm_gray_hist[k])
        else:
            if norm_hist_gray[k] == 0:
                entropy[k] = entropy[k-1]
            else:
                entropy[k] = entropy[k-1] - 
                norm_gray_hist[k]*math.log10(norm_hist_gray[k])
    # 第三步:找閾值
    f_t = np.zeros([256], np.float32)
    ft1, ft2 = 0.0, 0.0
    total_entropy = entropy[255]
    for k in range(255):
        # 找最大值
        max_front = np.max(norm_gray_hist[0:k+1])
        max_back = np.max(norm_gray_hist[k+1:256])
        if max_front == 0 or zero_cumu_moment[k] == 0 or 
           max_front == 1 or zero_cumu_moment[k] ==1 or total_entropy == 0:
            ft1 = 0
        else:
            ft1 = entropy[k] / total_entropy*(math.log10(zero_cumu_moment[k]) / math.log10(max_front))
        if max_back == 0 or 1-zero_cumu_moment[k] == 0 or max_back == 1
           or 1-zero_cumu_moment[k] == 1:
            ft2 = 0
        else:
            if total_entropy == 0:
                ft2 = (math.log10(1-zero_cumu_moment[k]) / math.log10(max_back))
            else:
                ft2 = (1-entropy[k]/total_entropy)*(math.log10(1-zero_cumu_moment[k])/math.log10(max_back))
        f_t[k] = ft1 + ft2
    # 找到最大值的索引,作為閾值
    thresh_loc = np.where(ft == np.max(f_t))
    thresh = thresh_loc[0][0]
    # 閾值處理
    threshold = np.copy(image)
    threshold[threshold > thresh] = 255
    threshold[threshold < thrseh] = 0
    return threshold

自適應(yīng)閾值

對(duì)于不均勻光照的圖片咏雌,如果設(shè)定一個(gè)全局的閾值凡怎,可能只會(huì)得到一張局部分割效果好但是光照不足(充分)的地方效果不好校焦,為此我們可以利用自適應(yīng)閾值針對(duì)圖片的不同部分得到不同的閾值,這樣整張圖片的分割效果就會(huì)好很多统倒。

原理

利用不同的平滑算子可以計(jì)算出當(dāng)前像素為中心的鄰域的灰度“平均值”寨典,所以使用平滑處理后的輸出結(jié)果作為每個(gè)像素設(shè)置閾值的參考值。在自適應(yīng)閾值處理中房匆,平滑算子的尺寸決定了分割出來(lái)的物體尺寸耸成,如果濾波器的尺寸太小,那么估計(jì)出的局部閾值將不理想浴鸿。一般來(lái)說(shuō)井氢,平滑算子的寬度必須大于被識(shí)別物體的寬度,平滑算子尺寸越大岳链, 則結(jié)果能更好的的作為每個(gè)像素閾值的參考花竞,當(dāng)然也不能無(wú)限大。

假設(shè)輸入圖像為I宠页,高為H左胞,寬為W,平滑算子的尺寸記為h \times w且都為奇數(shù)举户。步驟如下:

第一步:對(duì)圖像進(jìn)行平滑處理烤宙,平滑后的結(jié)果記為f_{smooth}(I),平滑可以使用均值平滑俭嘁、高斯平滑躺枕、中值平滑;

第二步:自適應(yīng)閾值矩陣Thresh = (1 - ratio) * f_{smooth}(I)供填,一般令ration = 0.15拐云;

第三步:利用局部閾值分割的規(guī)則
O(r, c) = \left\{ \begin{align} 255, I(r, c) > Thresh(r, c) \\ 0, I(r, c) \leq Thresh(r, c) \end{align} \right.
進(jìn)行閾值分割。

Python實(shí)現(xiàn)

def adaptive_thresh(image, win_size, ratio=0.15):
    """
    自適應(yīng)閾值分割
    :param image: 輸入圖像
    :param win_size: 平滑算子尺寸
    :param ratio: 比例系數(shù)
    :return: 自適應(yīng)閾值分割后的結(jié)果
    """
    # 第一步:對(duì)圖像進(jìn)行均值平滑近她,這里使用的是OpenCV提供的函數(shù)
    image_mean = cv2.boxFilter(image, cv2.CV_32FC1, win_size)
    # 第二步:原圖像與平滑結(jié)果做差
    out = image - (1.0-ratio)*image_mean
    # 第三步:當(dāng)差值大于或等于0時(shí)叉瘩,輸出值為255;反之為0
    out[out >= 0] = 255
    out[out < 0] = 0
    out = out.astype(np.uint8)
    return out

OpenCV提供自適應(yīng)閾值分割函數(shù)void adaptiveThreshold(InputArray src, OutputArray dst, double maxValue, int adaptiveMethod, int thresholdType, int blockSize, double C)粘捎,其參數(shù)如下表所示:

參數(shù) 解釋
src 單通道矩陣薇缅,數(shù)據(jù)類(lèi)型為CV_8U
dst 輸出矩陣
maxValue 與函數(shù)threshold類(lèi)似,一般取255
adaptiveMethod ADAPTIVE_THRESH_MEAN_C: 采用均值平滑攒磨;ADAPTIVE_THRESH_GAUSSIAN_C: 采用高斯平滑
thresholdType THRESH_BINARY, THRESH_BINARY_INV
blockSize 平滑算子的尺寸且為奇數(shù)
C 比例系數(shù)

二值圖的邏輯運(yùn)算

“與”和“或”運(yùn)算

“與”運(yùn)算可以理解為集合的交集泳桦,結(jié)果是兩幅圖白色相交的部分;

“或”運(yùn)算可以理解為集合的并集娩缰,結(jié)果是兩幅圖白色區(qū)域的并集灸撰;

OpenCV提供函數(shù)bitwise_andbitwise_or分別實(shí)現(xiàn)了這兩種運(yùn)算;

參考

《OpenCV算法精解——基于Python和C++》(張平)第六章

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市浮毯,隨后出現(xiàn)的幾起案子完疫,更是在濱河造成了極大的恐慌,老刑警劉巖亲轨,帶你破解...
    沈念sama閱讀 217,657評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件趋惨,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡惦蚊,警方通過(guò)查閱死者的電腦和手機(jī)器虾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)蹦锋,“玉大人兆沙,你說(shuō)我怎么就攤上這事±虻啵” “怎么了葛圃?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,057評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)憎妙。 經(jīng)常有香客問(wèn)我库正,道長(zhǎng),這世上最難降的妖魔是什么厘唾? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,509評(píng)論 1 293
  • 正文 為了忘掉前任褥符,我火速辦了婚禮,結(jié)果婚禮上抚垃,老公的妹妹穿的比我還像新娘喷楣。我一直安慰自己,他們只是感情好鹤树,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布铣焊。 她就那樣靜靜地躺著,像睡著了一般罕伯。 火紅的嫁衣襯著肌膚如雪曲伊。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,443評(píng)論 1 302
  • 那天追他,我揣著相機(jī)與錄音熊昌,去河邊找鬼。 笑死湿酸,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的灭美。 我是一名探鬼主播推溃,決...
    沈念sama閱讀 40,251評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼届腐!你這毒婦竟也來(lái)了铁坎?” 一聲冷哼從身側(cè)響起蜂奸,我...
    開(kāi)封第一講書(shū)人閱讀 39,129評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎硬萍,沒(méi)想到半個(gè)月后扩所,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,561評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡朴乖,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評(píng)論 3 335
  • 正文 我和宋清朗相戀三年祖屏,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片买羞。...
    茶點(diǎn)故事閱讀 39,902評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡袁勺,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出畜普,到底是詐尸還是另有隱情期丰,我是刑警寧澤,帶...
    沈念sama閱讀 35,621評(píng)論 5 345
  • 正文 年R本政府宣布吃挑,位于F島的核電站钝荡,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏舶衬。R本人自食惡果不足惜埠通,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望约炎。 院中可真熱鬧植阴,春花似錦、人聲如沸圾浅。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,838評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)狸捕。三九已至喷鸽,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間灸拍,已是汗流浹背做祝。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,971評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留鸡岗,地道東北人混槐。 一個(gè)月前我還...
    沈念sama閱讀 48,025評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像轩性,于是被迫代替她去往敵國(guó)和親声登。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評(píng)論 2 354