YOLOv5目標(biāo)檢測(cè)全流程:從標(biāo)注數(shù)據(jù)到檢測(cè)模型

1. 對(duì)原始圖片打標(biāo)

利用LabelImg工具打標(biāo)厘灼,輸出格式選擇為PascalVOC倒庵,得到xml格式的文件

2. 數(shù)據(jù)預(yù)處理

(1)將打標(biāo)后的文件拷貝到當(dāng)前工作目錄脸候,即放在和代碼同一級(jí)目錄下的datasets文件夾中

"""將打標(biāo)好的圖片和xml分別放在img和xml文件夾中"""
import os
import glob
import shutil

root_path = os.getcwd()  # 當(dāng)前工作目錄
xml_file_path = r'D:\YOLO\0506\labels\\'  # 存放打標(biāo)后xml文件的路徑
png_file_path = r'D:\YOLO\0506\images\\'  # 原始圖片數(shù)據(jù)集的路徑
png_name_list = []
xml_name_list = []
for xml_name in glob.glob(xml_file_path + "*.xml"):
    filepath, temp_file_name = os.path.split(xml_name)  # 將全路徑分割成目錄和文件名
    filename, extension = os.path.splitext(temp_file_name)  # 分離文件名與擴(kuò)展名
    png_name_list.append(filename + '.png')
    xml_name_list.append(filename + '.xml')

new_dataset_png = root_path + '\\datasets\\HDA\\img\\'  # 新的存放圖片文件的目錄
if not os.path.exists(new_dataset_png):
    os.makedirs(new_dataset_png)
new_dataset_xml = root_path + '\\datasets\\HDA\\xml\\'  # 新的存放xml文件的目錄
if not os.path.exists(new_dataset_xml):
    os.makedirs(new_dataset_xml)

for i in range(len(png_name_list)):  # 將源文件的內(nèi)容復(fù)制到目標(biāo)文件
    shutil.copy(png_file_path + str(png_name_list[i]), new_dataset_png)
    shutil.copy(xml_file_path + str(xml_name_list[i]), new_dataset_xml)

運(yùn)行以上代碼后婿脸,當(dāng)前代碼路徑下的目錄框架如下:


image.png

(2)將xml文件轉(zhuǎn)換成txt文件

目標(biāo)檢測(cè)的坐標(biāo)格式有:

VOC(XML)格式:
(Xmin, Ymin, Xmax, Ymax),分別代表左上角和右下角的兩個(gè)坐標(biāo)

YOLO(TXT)格式:
(Xcenter, Ycenter, W, H)烛占,其中x,y,w,h為歸一化后的數(shù)值,分別代表中心點(diǎn)坐標(biāo)和寬沟启、高

COCO(JSON)格式:
(Xmin, Ymin, W, H)忆家,其中x,y,w,h均不是歸一化后的數(shù)值,分別代表左上角坐標(biāo)和寬美浦、高

由于不同格式的坐標(biāo)表示方式不同弦赖,所以需要進(jìn)行轉(zhuǎn)換,將轉(zhuǎn)換后的坐標(biāo)文件存放到txt目錄下

"""將xml格式的坐標(biāo)轉(zhuǎn)換成txt格式浦辨,放入txt文件夾中"""
import xml.etree.ElementTree as ET
import os
import glob

classes = ["A", "T"]

# 將xml格式的坐標(biāo)轉(zhuǎn)換成txt格式的坐標(biāo):(Xmin蹬竖,Ymin沼沈,Xmax,Ymax)–>(X币厕,Y列另,W,H)
def convert(size, box):
    dw = 1.0 / size[0]
    dh = 1.0 / size[1]
    x = (box[0] + box[1]) / 2.0
    y = (box[2] + box[3]) / 2.0
    w = box[1] - box[0]
    h = box[3] - box[2]
    x = x * dw
    y = y * dh
    w = w * dw
    h = h * dh
    return x, y, w, h


def convert_annotation(img_name, xml_path, txt_path):
    in_file = open(xml_path + img_name[:-3] + 'xml')  # xml文件路徑
    out_file = open(txt_path + img_name[:-3] + 'txt', 'w')  # 轉(zhuǎn)換后的txt文件存放路徑

    xml_text = in_file.read()
    root = ET.fromstring(xml_text)
    in_file.close()
    size = root.find('size')
    w = int(size.find('width').text)
    h = int(size.find('height').text)

    for obj in root.iter('object'):
        cls = obj.find('name').text
        if cls not in classes:
            print(cls)
            continue
        cls_id = classes.index(cls)
        xmlbox = obj.find('bndbox')
        b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),
             float(xmlbox.find('ymax').text))
        bb = convert((w, h), b)
        out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')


if __name__ == '__main__':
    path = os.getcwd()
    xml_path = path + '\\datasets\\HDA\\xml\\'
    img_path = path + '\\datasets\\HDA\\img\\'
    txt_path = path + '\\datasets\\HDA\\txt\\'
    if not os.path.exists(txt_path):
        os.makedirs(txt_path)
    for image_path in glob.glob(img_path + "*.png"):
        # 每一張圖片都對(duì)應(yīng)一個(gè)xml文件旦装,這里寫xml對(duì)應(yīng)的圖片的路徑
        image_name = image_path.split('\\')[-1]
        try:
            convert_annotation(image_name, xml_path, txt_path)
        except:
            print('This picture has not xml file')

運(yùn)行以上代碼后页衙,當(dāng)前代碼路徑下的目錄框架如下所示,可以看到阴绢,多了一個(gè)txt目錄

image.png

(3)將數(shù)據(jù)集劃分成訓(xùn)練集店乐、測(cè)試集、驗(yàn)證集

"""
將數(shù)據(jù)集劃分成訓(xùn)練集呻袭、測(cè)試集眨八、驗(yàn)證集
僅僅是把劃分好的png和xml文件名寫入到不同集合的txt文件
"""
import os
import random

root_path = os.getcwd()
xml_file_path = root_path + '\\datasets\\HDA\\xml'
config_txt_save_path = root_path + '\\datasets\\HDA\\config'

if not os.path.exists(config_txt_save_path):
    os.makedirs(config_txt_save_path)

train_test_percent = 0.9   # (訓(xùn)練集+驗(yàn)證集) / (訓(xùn)練集+驗(yàn)證集+測(cè)試集)
train_val_percent = 0.9  # 訓(xùn)練集 / (訓(xùn)練集+驗(yàn)證集)

total_xml = os.listdir(xml_file_path)
num = len(total_xml)
train_val_size = int(num * train_test_percent)  # 訓(xùn)練集+驗(yàn)證集數(shù)量
test_size = int(num - train_val_size)  # 測(cè)試集數(shù)量
val_size = int(train_val_size * train_val_percent)  # 驗(yàn)證集數(shù)量
train_size = int(train_val_size - val_size)  # 訓(xùn)練集數(shù)量
train_val = random.sample(range(num), train_val_size)
train = random.sample(train_val, val_size)

print("train and valid size:", train_val_size)
print("train size:", train_size)
print("test size:", test_size)
print("valid size:", val_size)

test_txt = open(config_txt_save_path + '\\test.txt', 'w')
train_txt = open(config_txt_save_path + '\\train.txt', 'w')
val_txt = open(config_txt_save_path + '\\val.txt', 'w')

img_test_txt = open(config_txt_save_path + '\\img_test.txt', 'w')
img_train_txt = open(config_txt_save_path + '\\img_train.txt', 'w')
img_val_txt = open(config_txt_save_path + '\\img_val.txt', 'w')

for i in range(num):
    txt_name = total_xml[i][:-4] + '.txt' + '\n'
    img_name = total_xml[i][:-4] + '.png' + '\n'
    if i in train_val:
        if i in train:
            train_txt.write(txt_name)
            img_train_txt.write(img_name)
        else:
            val_txt.write(txt_name)
            img_val_txt.write(img_name)
    else:
        test_txt.write(txt_name)
        img_test_txt.write(img_name)

train_txt.close()
val_txt.close()
test_txt.close()

img_train_txt.close()
img_val_txt.close()
img_test_txt.close()

運(yùn)行以上代碼后,當(dāng)前代碼路徑下的目錄框架如下所示左电,可以看到廉侧,多了一個(gè)config目錄

image.png

(4)重構(gòu)數(shù)據(jù)集

"""重構(gòu)數(shù)據(jù)集,根據(jù)txt文件劃分圖片篓足,分別創(chuàng)建訓(xùn)練集段誊、驗(yàn)證集、測(cè)試集的圖片文件夾"""
import os
import shutil

# 獲取分割好的train\test\valid名稱
img_train_txt = []
img_test_txt = []
img_valid_txt = []
label_train_txt = []
label_test_txt = []
label_valid_txt = []

path = os.getcwd() + '\\datasets\\HDA\\config\\'
for line in open(path + "img_train.txt"):
    line = line.strip('\n')
    img_train_txt.append(line)
for line1 in open(path + "img_test.txt"):
    line1 = line1.strip('\n')
    img_test_txt.append(line1)
for line2 in open(path + "img_val.txt"):
    line2 = line2.strip('\n')
    img_valid_txt.append(line2)

for line3 in open(path + "train.txt"):
    line3 = line3.strip('\n')
    label_train_txt.append(line3)
for line4 in open(path + "test.txt"):
    line4 = line4.strip('\n')
    label_test_txt.append(line4)
for line5 in open(path + "val.txt"):
    line5 = line5.strip('\n')
    label_valid_txt.append(line5)

# 建立圖片的3種集合文件夾
new_train_img_dir = 'datasets\\HDA\\split\\images\\train\\'
new_test_img_dir = 'datasets\\HDA\\split\\images\\test\\'
new_valid_img_dir = 'datasets\\HDA\\split\\images\\val\\'
# 建立label的3種集合文件夾
new_train_label_dir = 'datasets\\HDA\\split\\labels\\train\\'
new_test_label_dir = 'datasets\\HDA\\split\\labels\\test\\'
new_valid_label_dir = 'datasets\\HDA\\split\\labels\\val\\'

if not os.path.exists(new_train_img_dir):
    os.makedirs(new_train_img_dir)
if not os.path.exists(new_test_img_dir):
    os.makedirs(new_test_img_dir)
if not os.path.exists(new_valid_img_dir):
    os.makedirs(new_valid_img_dir)
if not os.path.exists(new_train_label_dir):
    os.makedirs(new_train_label_dir)
if not os.path.exists(new_test_label_dir):
    os.makedirs(new_test_label_dir)
if not os.path.exists(new_valid_label_dir):
    os.makedirs(new_valid_label_dir)

# 將圖片從原始目錄移動(dòng)到訓(xùn)練集栈拖、驗(yàn)證集连舍、測(cè)試集目錄
origin_img_dir = 'datasets\\HDA\\img\\'
origin_label_dir = 'datasets\\HDA\\txt\\'

# 小數(shù)據(jù)建議:copy 大數(shù)據(jù)建議:move
for i in range(len(img_train_txt)):
    shutil.copy(origin_img_dir + str(img_train_txt[i]), new_train_img_dir)
    shutil.copy(origin_label_dir + str(label_train_txt[i]), new_train_label_dir)

for j in range(len(img_test_txt)):
    shutil.copy(origin_img_dir + str(img_test_txt[j]), new_test_img_dir)
    shutil.copy(origin_label_dir + str(label_test_txt[j]), new_test_label_dir)

for k in range(len(img_valid_txt)):
    shutil.copy(origin_img_dir + str(img_valid_txt[k]), new_valid_img_dir)
    shutil.copy(origin_label_dir + str(label_valid_txt[k]), new_valid_label_dir)

運(yùn)行以上代碼后,當(dāng)前代碼路徑下的目錄框架如下所示辱魁,可以看到烟瞧,多了一個(gè)split目錄,split目錄下又包括images和labels目錄染簇,分別代表圖片和標(biāo)簽参滴,這2個(gè)目錄下都分別有訓(xùn)練集、驗(yàn)證集和測(cè)試集的目錄锻弓。

image.png

至此砾赔,對(duì)原始圖片數(shù)據(jù)集的預(yù)處理完成,可以開始訓(xùn)練了

3.訓(xùn)練

(1)從GitHub下載YOLOv5代碼和pt文件

YOLOv5項(xiàng)目地址

pt文件也就是PyTorch的模型文件青灼,我使用的是yolov5x.pt

其他類型的model也可以在GitHub找到暴心,進(jìn)入https://github.com/ultralytics/yolov5/releases/tag/v6.1,劃到頁面最下方杂拨,Assets下有各種模型

下載好的YOLOv5項(xiàng)目結(jié)構(gòu)如下所示:


image.png

(2)將代碼上傳到服務(wù)器专普,并創(chuàng)建相應(yīng)目錄

  1. 將下載好的YOLOv5代碼上傳到有GPU的服務(wù)器

  2. 在服務(wù)器的YOLOv5文件夾中新建一個(gè)目錄weights,存放yolov5x.pt

  3. 在服務(wù)器的YOLOv5文件夾中新建一個(gè)目錄datasets弹沽,并新建一個(gè)當(dāng)前項(xiàng)目的目錄(便于日后針對(duì)不同項(xiàng)目管理)檀夹,存放之前split目錄下的images和labels筋粗,我這里是datasets/0506HDA

    注:上傳到服務(wù)器的時(shí)候需要將images和labels打成壓縮包,例如dataset.zip炸渡,然后使用 unzip dataset.zip解壓縮

  4. 在models目錄下新建一個(gè)針對(duì)當(dāng)前任務(wù)制定的模型配置文件娜亿,我的是yolov5x_hdl.yaml,具體細(xì)節(jié)參見(3)

  5. 在datasets/0506HDA目錄下新建一個(gè)訓(xùn)練所用的yaml文件蚌堵,我的是hdl.yaml买决,具體細(xì)節(jié)參見(3)

(3)回到服務(wù)器中的YOLOv5目錄,然后輸入訓(xùn)練指令:

python train.py --data datasets/0506HDA/hdl.yaml --cfg models/yolov5x_hdl.yaml --weights weights/yolov5x.pt --epoch 400

其中吼畏,--cfg 指定訓(xùn)練所用的模型督赤,--data 指定數(shù)據(jù)文件,默認(rèn)使用data/coco128.yaml宫仗,--weights 指定模型權(quán)重够挂, --epoch 指定訓(xùn)練輪數(shù)

  1. yolov5x_hdl.yaml是在yolov5x.yaml的基礎(chǔ)上稍作修改的文件,這是由于我的目標(biāo)檢測(cè)任務(wù)是二分類的藕夫,所以將nc從80變成了2,其他部分不變枯冈,內(nèi)容如下:
# Parameters
nc: 2  # number of classes
depth_multiple: 1.33  # model depth multiple
width_multiple: 1.25  # layer channel multiple
anchors:
  - [10,13, 16,30, 33,23]  # P3/8
  - [30,61, 62,45, 59,119]  # P4/16
  - [116,90, 156,198, 373,326]  # P5/32

# YOLOv5 v6.0 backbone
backbone:
  # [from, number, module, args]
  [[-1, 1, Conv, [64, 6, 2, 2]],  # 0-P1/2
   [-1, 1, Conv, [128, 3, 2]],  # 1-P2/4
   [-1, 3, C3, [128]],
   [-1, 1, Conv, [256, 3, 2]],  # 3-P3/8
   [-1, 6, C3, [256]],
   [-1, 1, Conv, [512, 3, 2]],  # 5-P4/16
   [-1, 9, C3, [512]],
   [-1, 1, Conv, [1024, 3, 2]],  # 7-P5/32
   [-1, 3, C3, [1024]],
   [-1, 1, SPPF, [1024, 5]],  # 9
  ]

# YOLOv5 v6.0 head
head:
  [[-1, 1, Conv, [512, 1, 1]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 6], 1, Concat, [1]],  # cat backbone P4
   [-1, 3, C3, [512, False]],  # 13

   [-1, 1, Conv, [256, 1, 1]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 4], 1, Concat, [1]],  # cat backbone P3
   [-1, 3, C3, [256, False]],  # 17 (P3/8-small)

   [-1, 1, Conv, [256, 3, 2]],
   [[-1, 14], 1, Concat, [1]],  # cat head P4
   [-1, 3, C3, [512, False]],  # 20 (P4/16-medium)

   [-1, 1, Conv, [512, 3, 2]],
   [[-1, 10], 1, Concat, [1]],  # cat head P5
   [-1, 3, C3, [1024, False]],  # 23 (P5/32-large)

   [[17, 20, 23], 1, Detect, [nc, anchors]],  # Detect(P3, P4, P5)
  ]

  1. hdl.yaml存放訓(xùn)練集毅贮、驗(yàn)證集、測(cè)試集的目錄尘奏,以及類別信息滩褥,這是我在data/coco128.yaml的基礎(chǔ)上修改的

    原始的coco128.yaml指定了訓(xùn)練集、驗(yàn)證集炫加、測(cè)試集的路徑瑰煎,以及分類個(gè)數(shù)和名字,內(nèi)容如下:

    # YOLOv5 ?? by Ultralytics, GPL-3.0 license
    # COCO128 dataset https://www.kaggle.com/ultralytics/coco128 (first 128 images from COCO train2017) by Ultralytics
    # Example usage: python train.py --data coco128.yaml
    # parent
    # ├── yolov5
    # └── datasets
    #     └── coco128  ← downloads here (7 MB)
    
    
    # Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..]
    path: ../datasets/coco128  # dataset root dir
    train: images/train2017  # train images (relative to 'path') 128 images
    val: images/train2017  # val images (relative to 'path') 128 images
    test:  # test images (optional)
    
    # Classes
    nc: 80  # number of classes
    names: ['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck', 'boat', 'traffic light',
            'fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow',
            'elephant', 'bear', 'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee',
            'skis', 'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard',
            'tennis racket', 'bottle', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple',
            'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair', 'couch',
            'potted plant', 'bed', 'dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone',
            'microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors', 'teddy bear',
            'hair drier', 'toothbrush']  # class names
    
    
    # Download script/URL (optional)
    download: https://ultralytics.com/assets/coco128.zip
    

    我根據(jù)自己的需求修改后內(nèi)容如下:

train: ../yolov5/datasets/0506HDA/images/train/  # train images (relative to 'path') 128 images
val: ../yolov5/datasets/0506HDA/images/val/  # val images (relative to 'path') 128 images
test: ../yolov5/datasets/0506HDA/images/test/ # test images (optional)

# Classes
nc: 2  # number of classes
names: ['A', 'T']  # class names

4.檢測(cè)

訓(xùn)練完成后俗孝,模型的各項(xiàng)信息會(huì)保存在yolov5/runs/train/目錄下酒甸,如果是默認(rèn)的話,會(huì)有exp+數(shù)字命名的各種目錄赋铝,此時(shí)進(jìn)入數(shù)字最大的那個(gè)(我的是exp3)插勤,也就是最后一次訓(xùn)練得到的模型,即可看到訓(xùn)練結(jié)果革骨。

訓(xùn)練效果最好的模型參數(shù)保存在exp3/weights/best.pt中

檢測(cè)命令如下:

python detect.py --source /mnt/seqdata2/Public_shared/tmp_cyf/CYCLONE-291/images/20211210171717_LAB256V2_5K_PC28_34_Z3_h49_5C20_J4_AD3_2020SEP_LiuJiaDun --weights ./runs/train/exp3/weights/best.pt --line-thickness 1 --save-txt --save-conf

其中农尖, --source 指定待檢測(cè)的數(shù)據(jù)集目錄,--weights 指定權(quán)重良哲,這里我們使用訓(xùn)練過的最佳模型

檢測(cè)結(jié)果會(huì)存放在yolov5/runs/detect/目錄下

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末盛卡,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子筑凫,更是在濱河造成了極大的恐慌滑沧,老刑警劉巖喇颁,帶你破解...
    沈念sama閱讀 219,270評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異嚎货,居然都是意外死亡岔擂,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門梗肝,熙熙樓的掌柜王于貴愁眉苦臉地迎上來桑谍,“玉大人,你說我怎么就攤上這事洗显⊥馇保” “怎么了?”我有些...
    開封第一講書人閱讀 165,630評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵挠唆,是天一觀的道長(zhǎng)处窥。 經(jīng)常有香客問我,道長(zhǎng)玄组,這世上最難降的妖魔是什么滔驾? 我笑而不...
    開封第一講書人閱讀 58,906評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮俄讹,結(jié)果婚禮上哆致,老公的妹妹穿的比我還像新娘。我一直安慰自己患膛,他們只是感情好摊阀,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著踪蹬,像睡著了一般胞此。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上跃捣,一...
    開封第一講書人閱讀 51,718評(píng)論 1 305
  • 那天漱牵,我揣著相機(jī)與錄音,去河邊找鬼枝缔。 笑死布疙,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的愿卸。 我是一名探鬼主播灵临,決...
    沈念sama閱讀 40,442評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼趴荸!你這毒婦竟也來了儒溉?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,345評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤发钝,失蹤者是張志新(化名)和其女友劉穎顿涣,沒想到半個(gè)月后波闹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,802評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡涛碑,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評(píng)論 3 337
  • 正文 我和宋清朗相戀三年精堕,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蒲障。...
    茶點(diǎn)故事閱讀 40,117評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡歹篓,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出揉阎,到底是詐尸還是另有隱情庄撮,我是刑警寧澤,帶...
    沈念sama閱讀 35,810評(píng)論 5 346
  • 正文 年R本政府宣布毙籽,位于F島的核電站洞斯,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏坑赡。R本人自食惡果不足惜烙如,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望垮衷。 院中可真熱鬧厅翔,春花似錦、人聲如沸搀突。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽仰迁。三九已至,卻和暖如春顽分,著一層夾襖步出監(jiān)牢的瞬間徐许,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工卒蘸, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留雌隅,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,377評(píng)論 3 373
  • 正文 我出身青樓缸沃,卻偏偏與公主長(zhǎng)得像恰起,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子趾牧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評(píng)論 2 355

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