OpenCV Python 系列教程2 - OpenCV 的 GUI 特性

圖像入門

學(xué)習(xí)目標(biāo):

  • 圖像的讀取凹嘲、顯示添怔、保存
  • 學(xué)習(xí)三個函數(shù):cv2.imread(), cv2.imshow() , cv2.imwrite()
  • 使用 Matplotlib 來顯示圖像
# 導(dǎo)入常用包
#%matplotlib notebook
import numpy as np
import cv2
import matplotlib.pyplot as plt

讀取顯示圖像

img = cv2.imread("img.jpg", 0) # 1: 顯示原始圖撒会, 0:灰度圖  -1:加載圖像包括 alpha 通道
cv2.imshow("image", img) # 第一個參數(shù)為顯示窗口的名稱朦肘,第二個參數(shù)是要顯示的圖像
k = cv2.waitKey(0) & 0xFF # cv2.waitKey()  鍵盤綁定函數(shù)链方,等待鍵盤按下,以毫秒為計數(shù)單位修陡,也可以設(shè)定特定按鍵點擊。64 bit 的機(jī)器要 cv2.waitKey(0) & 0xFF
if k == 27:         # 等待按下 ESC 鍵退出可霎, 
    cv2.destroyAllWindows() # 銷毀所有窗口魄鸦,也可以用 cv2.destroyWindow() 銷毀特定的窗口。
elif k == ord('s'): # 指定某個按鍵按下后指定某種操作癣朗,如這里是保存
    cv2.imwrite('image_write.png',img)
    cv2.destroyAllWindows()

結(jié)果:
image
cv2.namedWindow("image_new", cv2.WINDOW_NORMAL) # 創(chuàng)建一個新的窗口拾因,這個窗口大小可以進(jìn)行調(diào)節(jié)的
cv2.imshow("image_new", img)
cv2.waitKey(0)
cv2.destroyWindow("image_new")
image

寫圖像(保存圖像)

cv2.imwrite("image_write.png", img) # 保存圖像,可以指定保存圖像的格式
True
image

使用 matplotlib 顯示圖像

Matplotlib是一個用于Python的繪圖庫旷余,它提供了多種繪圖方法绢记。在這里,將學(xué)習(xí)如何使用 Matplotlib 顯示圖像正卧〈老ǎ可以使用 Matplotlib 放大圖片,保存圖片等炉旷。

img = cv2.imread("img.jpg", 0)
plt.imshow(img, cmap = 'gray', interpolation = 'bicubic') # interpolation 插值
plt.xticks([])
plt.yticks([])  # 隱藏 X签孔、Y 坐標(biāo)的刻度值
plt.show()
image

OpenCV 加載的彩色圖像為 BGR 模式。但是 Matplotlib 以 RGB 模式顯示窘行。因此饥追,如果使用 OpenCV 讀取圖像,Matplotlib 中的彩色圖像將不能正確顯示罐盔。

以下是解決辦法:對圖像的模式進(jìn)行轉(zhuǎn)換但绕,使之與 Matplotlib 或 OpenCV 匹配

img_cv = cv2.imread("img.jpg") # OpenCV 讀取圖像
b, g, r = cv2.split(img_cv) # OpenCV 中圖像顯示是 BGR 模式,提取
img_matplot = cv2.merge([r, g, b])
plt.subplot(121)
plt.imshow(img_cv) # 預(yù)計圖像會是異常的
plt.subplot(122)
plt.imshow(img_matplot) # 預(yù)計是真實的圖像
plt.show()

cv2.imshow('bgr image',img_cv) # 預(yù)計圖像會是異常的
cv2.imshow('rgb image',img_matplot) # 預(yù)計是真實的圖像
cv2.waitKey(0)
cv2.destroyAllWindows()
image

更多資料

matplotlib 詳細(xì) API

視頻入門

學(xué)習(xí)目標(biāo):

  • 顯示視頻惶看、保存視頻
  • 從相機(jī)進(jìn)行捕獲
  • cv2.VideoCapture(), cv2.VideoWriter() 函數(shù)使用

從相機(jī)捕獲視頻

筆記本自帶攝像頭

import cv2
# 創(chuàng)建一個 VideoCapture 對象捏顺,參數(shù)是設(shè)備的索引即攝像機(jī)的編號或者 Video 的文件名
# 這里的 0 是指第一臺攝像機(jī),以此類推
cap = cv2.VideoCapture(0)
while (True):
    # while cap.isOpened():
    # 一幀一幀的捕獲
    ret, frame = cap.read()

    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    # 顯示
    cv2.imshow("frame", gray)  # 窗口名為 frame
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
cap.release()  # 關(guān)閉視頻文件或設(shè)備
cv2.destroyAllWindows()

image

cap.read() 返回一個bool (True/False)碳竟。如果幀被正確讀取草丧,它將為真。通過檢查這個返回值來檢查視頻的結(jié)尾莹桅。

有時昌执,cap 可能沒有初始化捕獲。在這種情況下诈泼,這段代碼顯示錯誤懂拾。可以通過方法 cap.isOpened() 檢查它是否初始化铐达。如果為真岖赋,則 ok。否則使用 cap.open() 打開它瓮孙。

可以通過 cap.get(propId) 獲取視頻的一些屬性唐断,propId 值為:0 to 18选脊。每個值代表視頻的一個屬性,詳見 Property Identifier 也可以通過 cap.set(propId, value) 設(shè)置視頻的屬性脸甘。
例如:可以通過 cap.get(3)cap.get(4) 檢查幀的寬和高恳啥,默認(rèn)是 640x480。通過 ret = cap.set(3,320)ret = cap.set(4,240) 將寬和高重新設(shè)定丹诀。

# 創(chuàng)建一個 VideoCapture 對象钝的,參數(shù)是設(shè)備的索引即攝像機(jī)的編號或者 Video 的文件名
# 這里的 0 是指第一臺攝像機(jī),以此類推
cap = cv2.VideoCapture(0)
while (True):
    # while cap.isOpened():
    # 一幀一幀的捕獲
    ret, frame = cap.read()
    ret = cap.set(3, 320)
    ret = cap.set(4, 240)
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    cv2.imshow("frame", gray)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
cap.release()
cv2.destroyAllWindows()
image

從文件進(jìn)行播放

cap = cv2.VideoCapture('vtest.avi')

while(cap.isOpened()):
    ret, frame = cap.read()

    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    cv2.imshow('frame', gray)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()
image

如果視頻播放結(jié)束铆遭,還沒按鍵按下硝桩,會出現(xiàn)錯誤。 改進(jìn)如下:

import cv2
cap = cv2.VideoCapture('vtest.avi')

while(cap.isOpened()):
    ret, frame = cap.read()

    if ret == True:
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        cv2.imshow('frame', gray)
    if ret == False:
        # cap.release() # 釋放掉開啟的視頻
        # print("1") # 測試

        cv2.waitKey(0)  # 暫停在最后一幀
        break  # 關(guān)閉窗口后退出
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

改進(jìn)以后枚荣,程序會一直監(jiān)測視頻是否到最后一幀碗脊,若是最后一幀,則 ret 為 False 橄妆,暫停在最后一幀并且在關(guān)閉窗口后退出

保存視頻

cap = cv2.VideoCapture(0)

# Define the codec and create VideoWriter object
# cv2.VideoWriter_fourcc('X','V','I','D') 功能一樣
fourcc = cv2.VideoWriter_fourcc(*'XVID')

# 創(chuàng)建 VideoWriter 對象望薄,指定輸出文件名 output.avi, FourCC 代碼呼畸,傳遞每秒幀數(shù)和幀大小
out = cv2.VideoWriter('output.avi', fourcc, 20.0, (640, 480))

while(cap.isOpened()):
    ret, frame = cap.read()
    if ret == True:
        # 對每一幀進(jìn)行翻轉(zhuǎn)
        frame = cv2.flip(frame, 0)  # 注釋見下

        # write the flipped frame
        out.write(frame)

        cv2.imshow('frame', frame)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    else:
        break

# Release everything if job is finished
cap.release()
out.release()
cv2.destroyAllWindows()

FourCC 是一個 4 字節(jié)的代碼,用于指定視頻編解碼器颁虐,依賴于平臺蛮原,到時看具體平臺進(jìn)行選擇。更多 FourCC 代碼見 官網(wǎng)

cv2.flip(src, flipCode[, dst]) → dst: flipCode: 0表示繞 x 軸翻轉(zhuǎn)另绩,正值(例如儒陨,1)表示繞 y 軸翻轉(zhuǎn)。負(fù)值(例如 -1)表示在兩個軸上翻轉(zhuǎn)笋籽。

更多資料

opencv documentation

OpenCV 繪圖功能

學(xué)習(xí)目標(biāo):

  • 使用 OpenCV 繪制不同幾何形狀
  • cv2.line(), cv2.circle() , cv2.rectangle(), cv2.ellipse(), cv2.putText()

以下圖像都用 matplotlib 繪制

函數(shù)共有參數(shù)說明

  • img: 要操作的圖像
  • color:繪制形狀的顏色蹦漠, RGB 傳入元組如(255, 255, 255), 灰度值只需傳入標(biāo)量
  • thickness:線或圓等的厚度车海。如果對圓形等閉合圖形傳遞 -1 笛园,則填充形狀。默認(rèn)為 1
  • lineType:線的類型

繪制各種形狀

# 需要給定直線的起始和結(jié)束坐標(biāo)

# 創(chuàng)建一個黑色的畫布
img = np.zeros((512, 512, 3), np.uint8)

# 繪制坐標(biāo) (0, 0) -> (510, 128) 直線 藍(lán)色侍芝,厚度為 5px
img = cv2.line(img, (0, 0), (511, 511), (255, 0, 0), 5)  # OpenCV 為 BGR 模式
# 繪制長方形研铆,起始和終點坐標(biāo),顏色州叠,厚度
img = cv2.rectangle(img, (384, 10), (505, 120), (0, 255, 0), 3)
# 繪制圓形棵红,給定圓心,半徑咧栗,最后 -1 為圖形填充
img = cv2.circle(img, (447, 63), 63, (0, 0, 255), -1)
# 繪制橢圓逆甜,橢圓心虱肄,長軸,短軸交煞,角度咏窿,起始結(jié)束角,填充
img = cv2.ellipse(img, (256, 256), (100, 50), 0, 0, 180, 255, -1)
# 繪制多邊形错敢,給定多邊形的頂點坐標(biāo)
pts = np.array([[50, 50], [40, 40], [60, 40], [60, 100]], np.int32)
pts = pts.reshape((-1, 1, 2))
# 若第三個參數(shù)為 False翰灾,則得到連接所有點的折線,而不是一個閉合的形狀稚茅。該函數(shù)可以用來繪制多條直線
img = cv2.polylines(img, [pts], True, (0, 255, 255))
# 添加文字到圖形中
font = cv2.FONT_HERSHEY_SIMPLEX  # 指定字體
cv2.putText(img, 'OpenCV', (10, 500), font, 4, (255, 255, 255),
            2, cv2.LINE_AA)  # 繪制的圖像纸淮,文字,文字左下角的坐標(biāo),字體亚享,字體顏色咽块,厚度等

cv2.imshow("diff type", img)
k = cv2.waitKey(0) & 0xFF
if k == 27:
    cv2.destroyAllWindows()


b, g, r = cv2.split(img)
img = cv2.merge([r, g, b])
plt.subplot(121)
plt.xticks([])
plt.yticks([])
plt.imshow(img)
<matplotlib.image.AxesImage at 0x1d119e3b668>
image

作業(yè):繪制 OpenCV 圖標(biāo)
image

更多資料

鼠標(biāo)作為畫筆

學(xué)習(xí)目標(biāo):

  • 處理鼠標(biāo)事件
  • cv2.setMouseCallback()

簡單 Demo

首先,創(chuàng)建一個鼠標(biāo)回調(diào)函數(shù)欺税,該函數(shù)在鼠標(biāo)事件發(fā)生時執(zhí)行侈沪。鼠標(biāo)事件可以是任何與鼠標(biāo)相關(guān)的東西,如左鍵向下晚凿、左鍵向上亭罪、左鍵雙擊等。它為每個鼠標(biāo)事件提供坐標(biāo) (x,y)歼秽。有了這個事件和位置应役,我們可以做任何我們想做的事情。

# 列出鼠標(biāo)處理的事件
events = [i for i in dir(cv2) if 'EVENT' in i]
events
['EVENT_FLAG_ALTKEY',
 'EVENT_FLAG_CTRLKEY',
 'EVENT_FLAG_LBUTTON',
 'EVENT_FLAG_MBUTTON',
 'EVENT_FLAG_RBUTTON',
 'EVENT_FLAG_SHIFTKEY',
 'EVENT_LBUTTONDBLCLK',
 'EVENT_LBUTTONDOWN',
 'EVENT_LBUTTONUP',
 'EVENT_MBUTTONDBLCLK',
 'EVENT_MBUTTONDOWN',
 'EVENT_MBUTTONUP',
 'EVENT_MOUSEHWHEEL',
 'EVENT_MOUSEMOVE',
 'EVENT_MOUSEWHEEL',
 'EVENT_RBUTTONDBLCLK',
 'EVENT_RBUTTONDOWN',
 'EVENT_RBUTTONUP']
import cv2
import numpy as np
# 功能函數(shù)燥筷,在鼠標(biāo)處左鍵雙擊箩祥,繪制白色填充的圓
def draw_circle(event, x, y, flags, param):
    if event == cv2.EVENT_LBUTTONDBLCLK:
        cv2.circle(img, (x, y), 100, (255, 255, 255), -1)


# 創(chuàng)建一個黑色畫布
img = np.zeros((512, 512, 3), np.uint8)
cv2.namedWindow("image")
# 創(chuàng)建鼠標(biāo)回調(diào)函數(shù),綁定功能函數(shù)
cv2.setMouseCallback("image", draw_circle)

while(1):
    cv2.imshow("image", img)
    if cv2.waitKey(20) & 0xFF == 27:
        break
cv2.destroyAllWindows()
image

高級 Demo

現(xiàn)在我們要做更多更好的應(yīng)用肆氓。在這里袍祖,通過拖動鼠標(biāo)來繪制矩形或圓形(這取決于我們選擇的模式),就像在 Paint 應(yīng)用程序中所做的那樣谢揪。我們的鼠標(biāo)回調(diào)函數(shù)有兩部分蕉陋,一部分用來畫矩形,另一部分用來畫圓键耕。這個具體的例子將非常有助于創(chuàng)建和理解一些交互式應(yīng)用程序寺滚,如對象跟蹤,圖像分割等屈雄。

import cv2
import numpy as np

drawing = False # 鼠標(biāo)按下為 True
mode = True # 按鍵 'm' 切換模式
ix, iy = -1, -1


def draw(event, x, y, flags, param):
    global ix, iy, drawing, mode

    if event == cv2.EVENT_LBUTTONDOWN: # 鼠標(biāo)放下
        drawing = True
        ix, iy = x, y # 鼠標(biāo)放下時的坐標(biāo)

    elif event == cv2.EVENT_MOUSEMOVE: # 鼠標(biāo)移動
        if drawing == True:
            if mode == True:
                cv2.rectangle(img, (ix, iy), (x, y), (0, 255, 0), -1)
            else:
                cv2.circle(img, (x, y), 5, (0, 0, 255), -1)

    elif event == cv2.EVENT_LBUTTONUP: # 鼠標(biāo)提起村视,結(jié)束繪制
        drawing = False
        # ------------- 中間這一段要不要?
        if mode == True:
            cv2.rectangle(img, (ix, iy), (x, y), (0, 255, 0), -1)
        else:
            cv2.circle(img, (x, y), 5, (0, 0, 255), -1)    
        # -------------


img = np.zeros((512, 512, 3), np.uint8)
cv2.namedWindow("image")
cv2.setMouseCallback("image", draw) # 功能綁定

while(1):
    cv2.imshow("image", img)
    k = cv2.waitKey(1) & 0xFF
    if k == ord('m'): # 按鍵 'm' 切換模式
        mode = not mode
    elif k == 27:
        break
        
cv2.destroyAllWindows()
image

軌跡欄作為調(diào)色板

學(xué)習(xí)目標(biāo):

  • 將軌跡欄綁定到 OpenCV 窗口
  • cv2.getTrackbarPos(), cv2.createTrackbar()

Demo

創(chuàng)建簡單的應(yīng)用程序酒奶,通過滑動軌跡條調(diào)節(jié) BGR 的值從而改變畫布顏色蚁孔,初始顏色為黑色奶赔。

cv2.createTrackbar() 函數(shù),第一個參數(shù)是 trackbar 名稱杠氢,第二個參數(shù)是將用作創(chuàng)建的 trackbar 的父窗口的名稱站刑,第三個參數(shù)是默認(rèn)值,第四個參數(shù)是最大值鼻百,第五個參數(shù)是回調(diào)函數(shù)绞旅,每次 trackbar 值發(fā)生變化時都會執(zhí)行回調(diào)函數(shù)∥峦В回調(diào)函數(shù)總是有一個默認(rèn)參數(shù)因悲,即 trackbar 位置。在我們的例子中勺爱,函數(shù)什么也不做晃琳,所以我們只是傳遞。

trackbar 的另一個重要應(yīng)用是將其用作按鈕或開關(guān)琐鲁。默認(rèn)情況下卫旱,OpenCV 沒有按鈕功能。所以你可以使用 trackbar 來獲得這樣的功能围段。在我們的應(yīng)用程序中顾翼,我們已經(jīng)創(chuàng)建了一個開關(guān),在這個開關(guān)中應(yīng)用程序只在開關(guān)打開時才工作奈泪,否則屏幕總是黑色的暴构。

import cv2
import numpy as np


def nothing(x):
    pass


img = np.zeros((300, 512, 3), np.uint8)
cv2.namedWindow("image")

cv2.createTrackbar('R', 'image', 0, 255, nothing)
cv2.createTrackbar('G', 'image', 0, 255, nothing)
cv2.createTrackbar('B', 'image', 0, 255, nothing)

switch = '0 : OFF \n1 : ON'
cv2.createTrackbar(switch, 'image', 0, 1, nothing)

while(1):
    cv2.imshow('image', img)
    k = cv2.waitKey(1) & 0xFF
    if k == 27:
        break
    r = cv2.getTrackbarPos('R', 'image')
    g = cv2.getTrackbarPos('G', 'image')
    b = cv2.getTrackbarPos('B', 'image')
    s = cv2.getTrackbarPos(switch, 'image')

    if s == 0:
        img[:] = 0
    else:
        img[:] = [b, g, r]

cv2.destroyAllWindows()
image

練習(xí)

創(chuàng)建一個畫筆顏色和筆刷半徑可調(diào)的滑動軌跡條

import cv2
import numpy as np


def nothing(x):
    pass


radius_t = 1
bt, gt, rt = 255, 255, 255


def draw_circle(event, x, y, radius, b=255, g=255, r=255):
    global radius_t, bt, gt, rt
    radius = radius_t
    b, g, r = bt, gt, rt
    if event == cv2.EVENT_LBUTTONDBLCLK:
        cv2.circle(img, (x, y), radius, (b, g, r), -1)


img = np.zeros((1366, 768, 3), np.uint8)
cv2.namedWindow("image")

# --------- 畫筆顏色
cv2.createTrackbar('brush_radius', 'image', 1, 10, nothing)
cv2.createTrackbar('pen_B', 'image', 0, 255, nothing)
cv2.createTrackbar('pen_G', 'image', 0, 255, nothing)
cv2.createTrackbar('pen_R', 'image', 0, 255, nothing)


# 創(chuàng)建鼠標(biāo)回調(diào)函數(shù),綁定功能函數(shù)
cv2.setMouseCallback("image", draw_circle)

while(1):
    cv2.imshow('image', img)
    k = cv2.waitKey(1) & 0xFF
    if k == 27:
        break
    
    brush_radius = cv2.getTrackbarPos('brush_radius', 'image')
    pen_B = cv2.getTrackbarPos('pen_B', 'image')
    pen_G = cv2.getTrackbarPos('pen_G', 'image')
    pen_R = cv2.getTrackbarPos('pen_R', 'image')

    # 對鼠標(biāo)函數(shù)參數(shù)進(jìn)行賦值
    radius_t = brush_radius 
    bt, gt, rt = pen_B, pen_G, pen_R

cv2.destroyAllWindows()
image

更多資料

createtrackbar API

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末段磨,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子耗绿,更是在濱河造成了極大的恐慌苹支,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件误阻,死亡現(xiàn)場離奇詭異债蜜,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)究反,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進(jìn)店門寻定,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人精耐,你說我怎么就攤上這事狼速。” “怎么了卦停?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵向胡,是天一觀的道長恼蓬。 經(jīng)常有香客問我,道長僵芹,這世上最難降的妖魔是什么处硬? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮拇派,結(jié)果婚禮上荷辕,老公的妹妹穿的比我還像新娘。我一直安慰自己件豌,他們只是感情好疮方,可當(dāng)我...
    茶點故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著苟径,像睡著了一般案站。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上棘街,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天蟆盐,我揣著相機(jī)與錄音,去河邊找鬼遭殉。 笑死石挂,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的险污。 我是一名探鬼主播痹愚,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼蛔糯!你這毒婦竟也來了拯腮?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤蚁飒,失蹤者是張志新(化名)和其女友劉穎动壤,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體淮逻,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡琼懊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了爬早。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片哼丈。...
    茶點故事閱讀 39,919評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖筛严,靈堂內(nèi)的尸體忽然破棺而出醉旦,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布髓抑,位于F島的核電站咙崎,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏吨拍。R本人自食惡果不足惜褪猛,卻給世界環(huán)境...
    茶點故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望羹饰。 院中可真熱鬧伊滋,春花似錦、人聲如沸队秩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽馍资。三九已至筒主,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間鸟蟹,已是汗流浹背乌妙。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留建钥,地道東北人藤韵。 一個月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像熊经,于是被迫代替她去往敵國和親泽艘。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,864評論 2 354

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