精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

使用 OCR 識別手寫文本

人工智能
GNHK手寫筆記數據集由GoodNotes提供,包含來自世界各地學生的數百份英文手寫筆記。本文實現了基于微調TrOCR模型進行手寫文本識別。

本文實現了基于微調TrOCR模型進行手寫文本識別。

1.GNHK手寫筆記數據集

GNHK(GoodNotes Handwriting Kollection)手寫筆記數據集由GoodNotes提供,包含來自世界各地學生的數百份英文手寫筆記。

下載數據集

訪問GNHK數據集官方網站:

(https://www.goodnotes.com/gnhk),滾動到底部,同意使用條款和條件;點擊第二個鏈接下載數據集。

下載后會得到兩個文件:train_data.zip 和 test_data.zip。解壓這兩個文件后,數據集的目錄結構如下:

├── test_data
│   └── test
│       ├── eng_AF_004.jpg
│       ├── eng_AF_004.json
│       ├── eng_AF_007.jpg
│       ├── eng_AF_007.json
│       ...
│       ├── eng_NA_142.jpg
│       └── eng_NA_142.json
├── train_data
    └── train
        ├── eng_AF_001.jpg
        ├── eng_AF_001.json
        ├── eng_AF_002.jpg
        ├── eng_AF_002.json
        ...
        ├── eng_NA_146.jpg
        └── eng_NA_146.json
4 directories, 1375 files
  • 訓練集:包含515個樣本
  • 測試集:包含172個樣本
  • 圖像文件:從1080p到4K的高分辨率圖像
  • 標注文件:每個圖像文件對應一個JSON文件,包含圖像中每個單詞的標注信息

以下是數據集中的一些手寫筆記圖像樣本。

每個圖像文件對應一個JSON文件,文件內容格式如下:

[
    {
        "text": "%math%",
        "polygon": {
            "x0": 112, "y0": 556,
            "x1": 285, "y1": 563,
            "x2": 245, "y2": 776,
            "x3": 112, "y3": 783
        },
        "line_idx": 1,
        "type": "H"
    },
    {
        "text": "%math%",
        "polygon": {
            "x0": 2365, "y0": 202,
            "x1": 2350, "y1": 509,
            "x2": 2588, "y2": 527,
            "x3": 2632, "y3": 195
        },
        "line_idx": 0,
        "type": "H"
    },
    ...
    {
        "text": "ownership",
        "polygon": {
            "x0": 1347, "y0": 1606,
            "x1": 2238, "y1": 1574,
            "x2": 2170, "y2": 1884,
            "x3": 1300, "y3": 1747
        },
        "line_idx": 4,
        "type": "H"
    }
]

其中:

  • text:表示單詞的內容。如果單詞是數學符號、特殊字符或不可理解的內容(例如劃線),則用%%符號包裹的特殊詞表示。否則,text鍵包含實際的單詞。
  • polygon:表示單詞的多邊形坐標,用于精確標注單詞的位置。
  • line_idx:表示單詞所在的行索引。
  • type:表示單詞的類型,通常為"H"(手寫)。

2.項目目錄結構

├── input
│   └── gnhk_dataset
│       ├── test_data
│       ├── test_processed
│       ├── train_data
│       ├── train_processed
│       ├── test_processed.csv
│       └── train_processed.csv
├── pretrained_model_inference  [10066 entries exceeds filelimit, not opening dir]
├── trocr_handwritten
│   ├── checkpoint-6093
│   │   ├── config.json
│   │   ├── generation_config.json
│   │   ├── model.safetensors
│   │   ├── optimizer.pt
│   │   ├── preprocessor_config.json
│   │   ├── rng_state.pth
│   │   ├── scheduler.pt
│   │   ├── trainer_state.json
│   │   └── training_args.bin
│   ├── checkpoint-6770
│   │   ├── config.json
│   │   ├── generation_config.json
│   │   ├── model.safetensors
│   │   ├── optimizer.pt
│   │   ├── preprocessor_config.json
│   │   ├── rng_state.pth
│   │   ├── scheduler.pt
│   │   ├── trainer_state.json
│   │   └── training_args.bin
│   └── runs
│       └── Aug27_11-30-05_f57a2dab37c7
├── Fine_Tune_TrOCR_Handwritten.ipynb
├── preprocess_gnhk_dataset.py
└── Pretrained_Model_Inference.ipynb

目錄說明:

  • input/gnhk_dataset:包含下載并解壓的數據集
  • pretrained_model_inference:包含使用預訓練的TrOCR手寫模型對驗證數據集進行推理的結果。
  • trocr_handwritten:包含微調TrOCR模型后的結果。
  • Fine_Tune_TrOCR_Handwritten.ipynb:用于微調TrOCR模型的Jupyter Notebook
  • preprocess_gnhk_dataset.py:包含預處理GNHK數據集的Python腳本
  • Pretrained_Model_Inference.ipynb:用于使用預訓練模型進行推理的Jupyter Notebook

3.安裝依賴項

在繼續進行數據預處理、推理和訓練之前,我們需要安裝以下依賴項。

pip install transformers
pip install sentencepiece
pip install jiwer
pip install datasets
pip install evaluate
pip install -U accelerate

pip install matplotlib
pip install protobuf==3.20.1
pip install tensorboard

4.GNHK數據集預處理

預訓練的TrOCR模型只能識別單個單詞或單行句子,而GNHK數據集中的圖像是整個文檔的圖像。因此需要對數據集進行預處理,以便模型能夠更好地處理這些圖像。

數據集預處理的關鍵步驟如下:

  • 轉換多邊形坐標為四點邊界框坐標。
  • 裁剪每個單詞并存儲在單獨的目錄中。
  • 創建兩個 CSV 文件,一個用于訓練集,一個用于測試集。這些文件將包含裁剪后的圖像名稱和標簽文本。

代碼實現:

import os
import json
import csv
import cv2
import numpy as np
from tqdm import tqdm
 
def create_directories():
   """
   創建必要的目錄
   """
   dirs = [
       'input/gnhk_dataset/train_processed/images',
       'input/gnhk_dataset/test_processed/images',
   ]
   for dir_path in dirs:
       os.makedirs(dir_path, exist_ok=True)
 
def polygon_to_bbox(polygon):
    """
    將多邊形坐標轉換為四點邊界框坐標
    """
   points = np.array([(polygon[f'x{i}'], polygon[f'y{i}']) for i in range(4)], dtype=np.int32)
   x, y, w, h = cv2.boundingRect(points)
   return x, y, w, h
 
def process_dataset(input_folder, output_folder, csv_path):
    """
    處理數據集,裁剪圖像并生成 CSV 文件
    """
   with open(csv_path, 'w', newline='') as csvfile:
       csv_writer = csv.writer(csvfile)
       csv_writer.writerow(['image_filename', 'text'])
       
       for filename in tqdm(os.listdir(input_folder), desc=f"Processing {os.path.basename(input_folder)}"):
           if filename.endswith('.json'):
               json_path = os.path.join(input_folder, filename)
               img_path = os.path.join(input_folder, filename.replace('.json', '.jpg'))
               
               with open(json_path, 'r') as f:
                   data = json.load(f)
               
               img = cv2.imread(img_path)
               
               for idx, item in enumerate(data):
                   text = item['text']
                   if text.startswith('%') and text.endswith('%'):
                       text = 'SPECIAL_CHARACTER'
                   
                   x, y, w, h = polygon_to_bbox(item['polygon'])
                   
                   cropped_img = img[y:y+h, x:x+w]
                   
                   output_filename = f"{filename.replace('.json', '')}_{idx}.jpg"
                   output_path = os.path.join(output_folder, output_filename)
                   cv2.imwrite(output_path, cropped_img)
                   
                   csv_writer.writerow([output_filename, text])
                   
def main():
    """
    主函數,創建目錄并處理數據集
    """
   create_directories()

   process_dataset(
       'input/gnhk_dataset/train_data/train',
       'input/gnhk_dataset/train_processed/images',
       'input/gnhk_dataset/train_processed.csv'
   )
   process_dataset(
       'input/gnhk_dataset/test_data/test',
       'input/gnhk_dataset/test_processed/images',
       'input/gnhk_dataset/test_processed.csv'
   )

if __name__ == '__main__':
   main()

將上述代碼保存為preprocess_gnhk_dataset.py文件。在終端中運行腳本。

python preprocess_gnhk_dataset.py

運行腳本后,將會在 input/gnhk_dataset 目錄下創建以下子目錄和文件:

子目錄:

  • train_processed/images:存儲訓練集的裁剪圖像。
  • test_processed/images:存儲測試集的裁剪圖像。

CSV 文件:

  • train_processed.csv:包含訓練集的圖像文件名和對應的標簽文本。
  • test_processed.csv:包含測試集的圖像文件名和對應的標簽文本。

以下是一些經過處理后的裁剪圖像示例:

csv文件示例如下圖所示:

每個csv文件包括裁剪后的圖像文件名和對應圖像的標簽文本。每一行表示一個裁剪后的圖像及其對應的標簽文本。

處理后的數據集包括:

  • 訓練集:32495張裁剪圖像
  • 測試集:10066張裁剪圖像

5.微調TrOCR模型

首先,導入必要的庫,并定義一些全局設置。

import os
import torch
import evaluate
import numpy as np
import pandas as pd
import glob as glob
import torch.optim as optim
import matplotlib.pyplot as plt
import torchvision.transforms as transforms
 
from PIL import Image
from tqdm.notebook import tqdm
from dataclasses import dataclass
from torch.utils.data import Dataset
from transformers import (
   VisionEncoderDecoderModel,
   TrOCRProcessor,
   Seq2SeqTrainer,
   Seq2SeqTrainingArguments,
   default_data_collator
)
 
block_plot = False
plt.rcParams['figure.figsize'] = (12, 9)
 
os.environ["TOKENIZERS_PARALLELISM"] = 'false'

接著,為確保實驗的可重復性,設置隨機種子,并初始化計算設備。

def seed_everything(seed_value):
   np.random.seed(seed_value)
   torch.manual_seed(seed_value)
   torch.cuda.manual_seed_all(seed_value)
   torch.backends.cudnn.deterministic = True
   torch.backends.cudnn.benchmark = False

seed_everything(42)

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

定義一些重要的配置項,包括訓練和數據集的路徑。這里設置批次大小batch size為48,訓練輪數10,基礎學習率0.00005。

@dataclass(frozen=True)
class TrainingConfig:
   BATCH_SIZE:    int = 48
   EPOCHS:        int = 10
   LEARNING_RATE: float = 0.00005
 
@dataclass(frozen=True)
class DatasetConfig:
   DATA_ROOT:     str = 'input/gnhk_dataset'
 
@dataclass(frozen=True)
class ModelConfig:
   MODEL_NAME: str = 'microsoft/trocr-small-handwritten'

可視化訓練樣本,以幫助我們驗證路徑、CSV文件準備和標簽是否正確。

def visualize(dataset_path, df):
   all_images = df.image_filename
   all_labels = df.text
   
   plt.figure(figsize=(15, 3))
   for i in range(15):
       plt.subplot(3, 5, i+1)
       image = plt.imread(f"{dataset_path}/test_processed/images/{all_images[i]}")
       label = all_labels[i]
       plt.imshow(image)
       plt.axis('off')
       plt.title(label)
   plt.show()
sample_df = pd.read_csv(
   os.path.join(DatasetConfig.DATA_ROOT, 'test_processed.csv'),
   header=None,
   skiprows=1,
   names=['image_filename', 'text'],
   nrows=50
)
 
visualize(DatasetConfig.DATA_ROOT, sample_df)

GNHK手寫文本識別數據集具有自定義的目錄結構和CSV文件,我們需要編寫自定義的數據集準備代碼。

  • 讀取csv文件
train_df = pd.read_csv(
   os.path.join(DatasetConfig.DATA_ROOT, 'train_processed.csv'),
   header=None,
   skiprows=1,
   names=['image_filename', 'text']
)
 
 
test_df = pd.read_csv(
   os.path.join(DatasetConfig.DATA_ROOT, 'test_processed.csv'),
   header=None,
   skiprows=1,
   names=['image_filename', 'text']
)
  • 為了減少過擬合,應用一些輕微的數據增強,主要包括顏色抖動和高斯模糊。
# 定義數據增強
train_transforms = transforms.Compose([
    transforms.ColorJitter(brightness=0.5, hue=0.3),
    transforms.GaussianBlur(kernel_size=(3, 3), sigma=(0.1, 5)),
])
  • 需要創建一個自定義的PyTorch數據集類。
class CustomOCRDataset(Dataset):
    def __init__(self, root_dir, df, processor, max_target_length=128):
        self.root_dir = root_dir
        self.df = df
        self.processor = processor
        self.max_target_length = max_target_length

        # 填充空值
        self.df['text'] = self.df['text'].fillna('')

    def __len__(self):
        return len(self.df)

    def __getitem__(self, idx):
        # 圖像文件名
        file_name = self.df['image_filename'][idx]
        # 文本(標簽)
        text = self.df['text'][idx]

        # 讀取圖像,應用數據增強,并獲取轉換后的像素值
        image = Image.open(os.path.join(self.root_dir, file_name)).convert('RGB')
        image = train_transforms(image)
        pixel_values = self.processor(image, return_tensors='pt').pixel_values

        # 通過分詞器對文本進行分詞,并獲取標簽
        labels = self.processor.tokenizer(
            text,
            padding='max_length',
            max_length=self.max_target_length
        ).input_ids

        # 使用 -100 作為填充標記
        labels = [label if label != self.processor.tokenizer.pad_token_id else -100 for label in labels]

        encoding = {
            "pixel_values": pixel_values.squeeze(),
            "labels": torch.tensor(labels)
        }
        return encoding
  • 初始化TrOCR處理器,并準備訓練和驗證數據集。
# 初始化處理器
processor = TrOCRProcessor.from_pretrained(ModelConfig['MODEL_NAME'])

# 準備訓練數據集
train_dataset = CustomOCRDataset(
    root_dir=os.path.join(DatasetConfig['DATA_ROOT'], 'train_processed/images/'),
    df=train_df,
    processor=processor
)

# 準備驗證數據集
valid_dataset = CustomOCRDataset(
    root_dir=os.path.join(DatasetConfig['DATA_ROOT'], 'test_processed/images/'),
    df=test_df,
    processor=processor
)

初始化和配置模型,并統計模型的參數數量。

  • 加載模型
# 初始化模型
model = VisionEncoderDecoderModel.from_pretrained(ModelConfig['MODEL_NAME'])
model.to(device)
print(model)

# 統計總參數和可訓練參數
total_params = sum(p.numel() for p in model.parameters())
print(f"{total_params:,} total parameters.")

total_trainable_params = sum(
    p.numel() for p in model.parameters() if p.requires_grad
)
print(f"{total_trainable_params:,} training parameters.")
  • 手動設置一些配置。
# 設置特殊 token 用于從標簽創建 decoder_input_ids
model.config.decoder_start_token_id = processor.tokenizer.cls_token_id
model.config.pad_token_id = processor.tokenizer.pad_token_id
# 設置正確的詞匯表大小
model.config.vocab_size = model.config.decoder.vocab_size
model.config.eos_token_id = processor.tokenizer.sep_token_id

# 設置最大輸出長度
model.config.max_length = 64
# 啟用提前停止
model.config.early_stopping = True
# 設置不重復 n-gram 的大小
model.config.no_repeat_ngram_size = 3
# 設置長度懲罰
model.config.length_penalty = 2.0
# 設置 beam search 的束寬
model.config.num_beams = 4

# 打印模型配置
print(model.config)
  • 定義AdamW優化器,并配置學習率和權重衰減。
# 定義 AdamW 優化器
optimizer = optim.AdamW(
    model.parameters(), lr=TrainingConfig['LEARNING_RATE'], weight_decay=0.0005
)
  • 使用字符錯誤率CER對模型進行評估。
cer_metric = evaluate.load('cer')


def compute_cer(pred):
   # 提取標簽的 ID
   labels_ids = pred.label_ids
   # 提取預測的 ID
   pred_ids = pred.predictions

   # 將預測的 ID 解碼為字符串,跳過特殊 token
   pred_str = processor.batch_decode(pred_ids, skip_special_tokens=True)
   # 將標簽中的 -100 轉換為 pad_token_id,以避免影響評估結果
   labels_ids[labels_ids == -100] = processor.tokenizer.
   # 將標簽的 ID 解碼為字符串,跳過特殊 token
   label_str = processor.batch_decode(labels_ids, skip_special_tokens=True)

   # 使用 cer_metric 計算 CER
   cer = cer_metric.compute(predictions=pred_str, references=label_str)

   return {"cer": cer}

訓練和驗證模型。在開始訓練之前,需要初始化訓練參數和 Trainer API。

  • 定義 Seq2SeqTrainingArguments 對象,設置訓練和驗證的相關參數。
# 初始化訓練參數
training_args = Seq2SeqTrainingArguments(
    predict_with_generate=True,
    evaluation_strategy='epoch',
    per_device_train_batch_size=TrainingConfig['BATCH_SIZE'],
    per_device_eval_batch_size=TrainingConfig['BATCH_SIZE'],
    fp16=True,
    output_dir='trocr_handwritten/',
    logging_strategy='epoch',
    save_strategy='epoch',
    save_total_limit=2,
    report_to='tensorboard',
    num_train_epochs=TrainingConfig['EPOCHS'],
    dataloader_num_workers=8
)
  • 使用 Seq2SeqTrainer API 初始化訓練器。Seq2SeqTrainer 接受模型、處理器、訓練參數、數據集和數據收集器作為參數。
# 初始化訓練器
trainer = Seq2SeqTrainer(
    model=model,
    tokenizer=processor.feature_extractor,
    args=training_args,
    compute_metrics=compute_cer,
    train_dataset=train_dataset,
    eval_dataset=valid_dataset,
    data_collator=default_data_collator
)
  • 開始微調模型。
# 開始訓練
trainer.train()

以下是訓練10個epoch后的日志示例:

在訓練完成后,我們得到了最佳的驗證 CER 值。接下來,我們將使用最后一個epoch的檢查點對驗證集進行推理。

如圖所示,驗證CER圖表在整個訓練過程中持續下降,直到最后一個 epoch。這表明模型仍在學習,并且可能通過適當的學習率調度進一步訓練幾個 epoch 以獲得更好的性能。

6.使用訓練好的TrOCR模型推理

接下來,將使用訓練好的trOCR模型對一組圖像進行推理。

  • 加載處理器和訓練好的模型檢查點。
# 定義模型和處理器
processor = TrOCRProcessor.from_pretrained(ModelConfig.MODEL_NAME)
trained_model = VisionEncoderDecoderModel.from_pretrained('trocr_handwritten/checkpoint-'+str(res.global_step)).to(device)
  • 定義一些輔助函數,用于讀取圖像、通過模型進行前向傳播以及繪制結果。
def read_and_show(image_path):
    """
    :param image_path: String, path to the input image.
    
    Returns:
        image: PIL Image.
    """
    image = Image.open(image_path).convert('RGB')
    return image
def ocr(image, processor, model):
    """
    :param image: PIL Image.
    :param processor: Huggingface OCR processor.
    :param model: Huggingface OCR model.
    
    Returns:
        generated_text: the OCR'd text string.
    """
    pixel_values = processor(image, return_tensors='pt').pixel_values.to(device)
    generated_ids = model.generate(pixel_values)
    generated_text = processor.batch_decode(generated_ids, skip_special_tokens=True)[0]
    return generated_text
def eval_new_data(data_path=None, num_samples=50, df=None):
    all_images = df.image_filename
    all_labels = df.text
    
    plt.figure(figsize=(15, 3))
    for i in range(num_samples):
        plt.subplot(3, 5, i+1)
        image = read_and_show(os.path.join(data_path, all_images[i]))
        text = ocr(image, processor, trained_model)
        plt.imshow(image)
        plt.title(text)
        plt.axis('off')
    plt.show()
  • 運行推理并可視化結果
# 運行推理并可視化結果
eval_new_data(
    data_path=data_path,
    num_samples=num_samples,
    df=sample_df
)

推理結果如下圖所示。

由此可以看出,模型成功地正確預測了所有單詞。這表明經過微調后,模型在驗證集上的表現非常出色。

附錄(完整代碼)

鏈接:https://pan.baidu.com/s/1R5-JB7zKTeb1pJ0kS2Tmnw

提取碼:d388

責任編輯:趙寧寧 來源: 小喵學AI
相關推薦

2023-09-07 10:37:43

OCR項目字符串

2023-09-29 08:45:38

截圖工具Windows

2021-04-09 20:49:44

PythonOCR圖像

2023-12-25 19:21:55

ocr人工智能

2015-07-09 13:58:28

tesseract教程OCR教程

2009-03-28 09:13:11

AndroidGoogle移動OS

2023-09-12 14:46:24

人工智能自然語言

2023-06-25 07:37:54

谷歌Chrome

2020-03-27 20:22:53

數據集裝箱網絡

2018-04-02 10:45:11

深度學習PaddlePaddl手寫數字識別

2023-07-06 08:41:20

TTS?Mac?系統

2022-10-08 08:36:02

UbuntuLinux語音識別

2023-04-17 08:59:14

OCRChatGPT識別食品

2009-09-22 12:16:29

ibmdwLotus

2014-11-12 10:16:43

人工智能靈云

2023-03-16 17:19:50

開源OCR識別項目

2023-05-17 15:22:45

識別開源工具

2017-09-21 15:43:02

深度序列學習

2023-11-12 23:01:44

PaddleOCR深度學習

2023-09-27 08:51:52

PythonOCR技術
點贊
收藏

51CTO技術棧公眾號

韩日欧美一区二区三区| 亚洲福利合集| 亚洲视频资源在线| 国产伦精品一区二区三区照片91| 成年人免费看毛片| 欧美自拍偷拍| 日韩三级高清在线| 毛片av免费在线观看| 精品欧美色视频网站在线观看| 成人福利视频在线看| 国产精品久久久久久久久久久不卡 | 视频一区二区国产| 久久91亚洲人成电影网站| 黄色正能量网站| 精品精品视频| 欧洲精品在线观看| 青草青青在线视频| 黄色精品免费看| 国产亚洲美州欧州综合国| 亚洲最大的网站| 中文字幕第315页| 一道本一区二区| 欧美成人三级视频网站| 亚洲av成人无码久久精品| jazzjazz国产精品久久| 777午夜精品视频在线播放| 成人在线观看a| 678在线观看视频| 樱花草国产18久久久久| 亚洲一区三区| 成年人视频网站在线| 99精品国产视频| 91大片在线观看| 91九色蝌蚪91por成人| 老司机精品视频网站| 69**夜色精品国产69乱| 国产一级免费观看| 欧美黄在线观看| 久久精品色欧美aⅴ一区二区| a级大片在线观看| 女同另类激情重口| 亚洲国产成人精品电影| 国产chinesehd精品露脸| 欧美一级做a| 欧美日韩一区国产| 色综合色综合色综合色综合| 日韩欧美一区二区三区免费观看 | 26uuu欧美日本| 国产精品二区在线观看| av高清一区二区| 国内精品伊人久久久久av影院| 国产精品久久中文| 一本色道久久综合精品婷婷| 久久99国产精品免费网站| 国产欧美va欧美va香蕉在| 伊人久久国产精品| 激情亚洲综合在线| 99在线观看视频| 黄色三级网站在线观看| 成年人网站91| 鲁丝片一区二区三区| 可以免费看污视频的网站在线| 91麻豆免费观看| 视频一区三区| 黄色在线观看网站| 亚洲综合av网| 国产深夜男女无套内射| 制服诱惑亚洲| 在线播放中文一区| 18深夜在线观看免费视频| 亚洲午夜免费| 国产视频久久久| 最新中文字幕av| 婷婷伊人综合| 久久人人爽国产| 亚洲av无码精品一区二区| 奇米精品一区二区三区在线观看一| 国产精品入口尤物| 亚洲精品久久久蜜桃动漫| 91色乱码一区二区三区| 亚洲永久激情精品| 国产在线拍揄自揄拍视频| 欧美视频在线视频| 亚洲xxx在线观看| 97se亚洲| 一个色综合导航| 久久久久久天堂| 日日夜夜精品免费视频| 666精品在线| 久久精品蜜桃| 亚洲精品va在线观看| 亚洲 高清 成人 动漫| 成人在线视频免费| 精品国产凹凸成av人导航| 男生草女生视频| 自拍欧美日韩| 国产成人精品久久二区二区| 国产高清第一页| 久久久午夜电影| 黄色片免费在线观看视频| 欧美一级大黄| 亚洲精品在线三区| 天天色影综合网| 亚洲欧美日韩一区在线观看| 亚洲自拍偷拍色片视频| 精品三级久久久久久久电影聊斋| 亚洲女人的天堂| 欧美亚洲日本在线观看| jizz性欧美23| 久久激情五月丁香伊人| 国产中文字幕视频| 国产aⅴ精品一区二区三区色成熟| 青青草国产精品| av影院在线免费观看| 欧美丰满少妇xxxbbb| 成人午夜剧场视频网站| 在线看片一区| 91香蕉亚洲精品| 91精品专区| 一本久道久久综合中文字幕| 国产女主播在线播放| 999国产精品永久免费视频app| 91成人性视频| 蜜桃av噜噜一区二区三区麻豆| 中文av字幕一区| 免费av网址在线| 狼人精品一区二区三区在线| 欧美国产中文字幕| av中文字幕免费| 亚洲欧洲日韩一区二区三区| 97xxxxx| 欧美一区 二区| 久久久免费在线观看| 成 人 黄 色 片 在线播放| 国产精品久久久久影院亚瑟| 久久精品影视大全| 欧美色爱综合| 国产精品久久婷婷六月丁香| 国产一级网站视频在线| 色狠狠色噜噜噜综合网| 李宗瑞91在线正在播放| 亚洲永久视频| 欧美激情第一页在线观看| 午夜不卡影院| 亚洲欧美在线x视频| 久久一区二区三区视频| 91麻豆国产精品久久| 777久久久精品一区二区三区| 欧美三级电影在线| 欧美一级电影久久| 国产女主播在线写真| 欧美怡红院视频| 一本在线免费视频| 国产做a爰片久久毛片| 国产日本欧美在线| 视频在线亚洲| 午夜精品福利视频| 青青九九免费视频在线| 在线免费不卡视频| 少妇高潮一区二区三区喷水| 激情久久五月天| 欧洲xxxxx| 大型av综合网站| 青青精品视频播放| 在线播放毛片| 欧美一区二区黄色| 黄网在线观看视频| 国产亚洲成aⅴ人片在线观看| 天天干天天玩天天操| 亚洲天天影视网| 国产精品久久精品视| 欧美xxx网站| 久久精品国产亚洲精品2020| 亚洲爆乳无码一区二区三区| 欧美日韩国产在线看| 亚洲av毛片基地| 国产精品18久久久久久久久久久久| 午夜免费福利小电影| 国产欧美高清视频在线| 3d蒂法精品啪啪一区二区免费| 69av成人| 精品国产欧美一区二区三区成人| 免费观看黄一级视频| 在线观看av不卡| 麻豆亚洲av成人无码久久精品| av网站免费线看精品| 九色91popny| 亚洲狠狠婷婷| 五月天国产一区| 99re8这里有精品热视频免费| 日韩av电影国产| gogogogo高清视频在线| 亚洲久久久久久久久久| 国产三级小视频| 一本色道a无线码一区v| 国产性猛交普通话对白| 国产欧美日韩激情| 69亚洲乱人伦| 精品一区二区三区不卡 | 青青国产91久久久久久| 日韩欧美一级在线| 日韩dvd碟片| 九九九九久久久久| 国产一区二区视频在线看| 日本中文字幕成人| 久久电影网站| 日韩一区二区欧美| 精品无人乱码| 亚洲国产欧美一区二区丝袜黑人 | 韩国毛片一区二区三区| 国产真实乱子伦| 激情综合亚洲| 精品一区二区成人免费视频| 久久97视频| 久久亚洲免费| 国产精品久久久久久久久久白浆 | 成人黄色一区二区| 樱桃成人精品视频在线播放| 国产免费一区二区三区四在线播放 | 久久午夜激情| 人妻av中文系列| 亚洲一级网站| 欧美日韩午夜爽爽| 欧美第一精品| 深夜福利成人| 国产亚洲一区| 久久99久久99精品蜜柚传媒| silk一区二区三区精品视频 | 性生交免费视频| 性xx色xx综合久久久xx| 国产av国片精品| 欧美色图麻豆| 中文字幕日韩精品无码内射| 一本一道久久a久久精品蜜桃| 亚洲欧美日韩精品在线| 欧美一区电影| 亚洲精品中字| 98精品视频| 色乱码一区二区三区熟女| 99久久久久国产精品| 午夜精品福利一区二区| 欧洲三级视频| 欧洲一区二区在线| 欧美日韩一区二区三区视频播放| 日韩欧美精品在线不卡| 欧美艳星介绍134位艳星| 欧美一区二区三区四区在线观看地址 | 久久深夜福利| 北条麻妃av高潮尖叫在线观看| 久久亚洲影院| 五月婷婷丁香综合网| 欧美aaaaaa午夜精品| 小明看看成人免费视频| 国产精品91一区二区| 中文字幕无码毛片免费看| 成人黄色av网站在线| 成人性生活免费看| 久久久精品免费观看| 自拍偷拍你懂的| 国产精品久久久久一区| 久久精品亚洲a| 一区二区三区小说| 日韩乱码一区二区| 日本二三区不卡| 怡红院成永久免费人全部视频| 777xxx欧美| 四虎在线视频免费观看| 亚洲网站视频福利| 免费av在线| 欧美黑人狂野猛交老妇| 综合日韩av| 成人性生交大片免费观看嘿嘿视频| 九色精品蝌蚪| 久久久久久久免费| 日韩在线观看| 每日在线观看av| 三级一区在线视频先锋 | 欧美精品一区二区三区三州| 日韩成人一级大片| 丰满饥渴老女人hd| 久久尤物电影视频在线观看| 国内毛片毛片毛片毛片毛片| 午夜精品影院在线观看| 波多野结衣电车痴汉| 日韩欧美一区中文| 男人天堂亚洲二区| 美女福利视频一区| 欧美日韩免费看片| 亚洲综合精品一区二区| 亚洲品质自拍| 懂色av粉嫩av蜜臀av| 亚洲欧美日韩国产| 波多野结衣在线免费观看| 久久久综合视频| 九九免费精品视频| 欧美三日本三级三级在线播放| 精品人妻伦一二三区久久| 亚洲视频999| 福利网站在线观看| 国产日韩在线精品av| 亚洲ab电影| 加勒比成人在线| 激情久久久久久久久久久久久久久久| 91精品国产自产| 亚洲专区一二三| 一级久久久久久久| 亚洲欧美制服另类日韩| 国产乱码在线| 91色p视频在线| 久久久影院免费| 国产91在线免费| 国产98色在线|日韩| 中文天堂资源在线| 一本一道久久a久久精品综合蜜臀| 成人av一区二区三区在线观看| 国产一区二区三区精品久久久| 理论不卡电影大全神| 亚洲综合日韩在线| 亚洲成人日韩| 国模私拍视频在线观看| 国产欧美日韩综合精品一区二区| 青青草av在线播放| 欧美精品一区二区三区蜜桃视频| caopen在线视频| 成人在线视频网站| 欧美电影免费播放| 在线观看av日韩| 国产女人水真多18毛片18精品视频| 日韩三级av在线| 欧美精品一区二区不卡| 牛牛精品视频在线| 91香蕉电影院| 欧美91视频| 国产成人精品综合久久久久99 | 国产免费一区二区三区最新不卡| 中日韩美女免费视频网站在线观看| 亚洲国产欧美日本视频| 玛丽玛丽电影原版免费观看1977 | 欧美性极品xxxx娇小| 午夜av免费观看| 欧美一区在线直播| 亚洲人成精品久久久| 黑人糟蹋人妻hd中文字幕| 99国产一区二区三精品乱码| 日韩av男人天堂| 日韩经典第一页| 激情开心成人网| 色一情一乱一伦一区二区三区丨| 男人的天堂久久精品| 男人在线观看视频| 日韩免费电影网站| 2018av在线| 另类视频在线观看+1080p| 日韩av网站免费在线| 国产不卡在线观看视频| 4hu四虎永久在线影院成人| 97caopor国产在线视频| 国产嫩草一区二区三区在线观看 | 超碰在线资源站| 亚洲美女屁股眼交3| 丰满熟妇人妻中文字幕| 91国产美女在线观看| 久久av免费| 手机在线国产视频| 亚洲成人福利片| 久草视频在线看| 亚洲mm色国产网站| 亚洲精品黄色| www亚洲色图| 欧美一级一区二区| 亚洲一区资源| 在线看无码的免费网站| 粉嫩一区二区三区性色av| 最新中文字幕一区| 色av吧综合网| 精品一区二区三区中文字幕| 久久国产精品网| 国产精品嫩草影院av蜜臀| 亚洲精品国产片| 日韩免费观看网站| 欧美1区2区视频| av男人的天堂av| 日韩欧美一区二区不卡| 神马电影网我不卡| 国产欧美精品aaaaaa片| 国产三级精品三级| 亚洲精品18在线观看| 国产精品久久久久一区二区 | ●精品国产综合乱码久久久久| 老牛影视av牛牛影视av| 国产精品99导航| 一区二区三区成人精品| 四虎影院中文字幕| 国产婷婷97碰碰久久人人蜜臀| 成人噜噜噜噜| 欧美一级黄色影院| 亚洲第一精品在线| h网站久久久| 日本一区二区三区四区高清视频| 国产盗摄女厕一区二区三区|