国产秋霞理论久久久电影-婷婷色九月综合激情丁香-欧美在线观看乱妇视频-精品国avA久久久久久久-国产乱码精品一区二区三区亚洲人-欧美熟妇一区二区三区蜜桃视频

完整的文本檢測與識別 | 附源碼

共 33226字,需瀏覽 67分鐘

 ·

2024-07-16 10:12

點擊上方小白學(xué)視覺”,選擇加"星標(biāo)"或“置頂

重磅干貨,第一時間送達(dá)

另外,你還記得每家店鋪都有獨特的名字書寫方式嗎?像Gucci、Sears、Pantaloons和Lifestyle這樣的知名品牌在其商標(biāo)中使用了曲線或圓形字體。雖然這一切吸引了顧客,但對于執(zhí)行文本檢測和識別的深度學(xué)習(xí)(DL)模型來說,它確實提出了挑戰(zhàn)。


當(dāng)你讀取橫幅上的文字時,你會怎么做?你的眼睛首先會檢測到文本的存在,找出每個字符的位置,然后識別這些字符。這正是一個DL模型需要做的!最近,OCR在深度學(xué)習(xí)中成為熱門話題,其中每個新架構(gòu)都在努力超越其他架構(gòu)。


流行的基于深度學(xué)習(xí)的OCR模塊Tesseract在結(jié)構(gòu)化文本(如文件)上表現(xiàn)出色,但在花哨字體的曲線、不規(guī)則形狀的文本方面卻表現(xiàn)不佳。幸運的是,我們有Clova AI提供的這些出色的網(wǎng)絡(luò),它們在真實世界中出現(xiàn)的各種文本外觀方面勝過了Tesseract。在本博客中,我們將簡要討論這些架構(gòu)并學(xué)習(xí)如何將它們整合起來。


使用CRAFT進(jìn)行文本檢測


場景文本檢測是在復(fù)雜背景中檢測文本區(qū)域并用邊界框標(biāo)記它們的任務(wù)。CRAFT是一項2019年提出的主要目標(biāo)是定位單個字符區(qū)域并將檢測到的字符鏈接到文本實例的全稱:Character-Region Awareness For Text detection。

CRAFT采用了基于VGG-16的全卷積網(wǎng)絡(luò)架構(gòu)。簡單來說,VGG16本質(zhì)上是特征提取架構(gòu),用于將網(wǎng)絡(luò)的輸入編碼成某種特征表示。CRAFT網(wǎng)絡(luò)的解碼段類似于UNet。它具有聚合低級特征的跳躍連接。CRAFT為每個字符預(yù)測兩個分?jǐn)?shù):

  • 區(qū)域分?jǐn)?shù):顧名思義,它給出了字符的區(qū)域。它定位字符。 

  • 親和力分?jǐn)?shù):'親和力'是指物質(zhì)傾向于與另一種物質(zhì)結(jié)合的程度。

因此,親和力分?jǐn)?shù)將字符合并為單個實例(一個詞)。CRAFT生成兩個地圖作為輸出:區(qū)域級地圖和親和力地圖。讓我們通過示例來理解它們的含義:

輸入圖像

存在字符的區(qū)域在區(qū)域地圖中標(biāo)記出來:

區(qū)域地圖

親和力地圖以圖形方式表示相關(guān)字符。紅色表示字符具有較高的親和力,必須合并為一個詞:

親和力地圖 

最后,將親和力分?jǐn)?shù)和區(qū)域分?jǐn)?shù)組合起來,給出每個單詞的邊界框。坐標(biāo)的順序是:(左上)、(右上)、(右下)、(左下),其中每個坐標(biāo)都是一個(x,y)對。

為什么不按照四點格式? 

看下面的圖片:你能在僅有4個值的情況下定位“LOVE”嗎?

CRAFT是多語言的,這意味著它可以檢測任何腳本中的文本。


文本識別:四階段場景文本識別框架 

2019年,Clova AI發(fā)表了一篇關(guān)于現(xiàn)有場景文本識別(STR)數(shù)據(jù)集的不一致性,并提出了一個大多數(shù)現(xiàn)有STR模型都適用的統(tǒng)一框架的研究論文。

讓我們討論這四個階段:

  1. 轉(zhuǎn)換:記住我們正在處理的是景觀文本,它是任意形狀和曲線的。如果我們直接進(jìn)行特征提取,那么它需要學(xué)習(xí)輸入文本的幾何形狀,這對于特征提取模塊來說是額外的工作。因此,STR網(wǎng)絡(luò)應(yīng)用了薄板樣條(TPS)變換,并將輸入文本規(guī)范化為矩形形狀。 

  2. 特征提?。?/span>將變換后的圖像映射到與字符識別相關(guān)的一組特征上。字體、顏色、大小和背景都被丟棄了。作者對不同的骨干網(wǎng)絡(luò)進(jìn)行了實驗,包括ResNet、VGG和RCNN。 

  3. 序列建模:如果我寫下'ba_',你很可能猜到填在空格處的字母可能是'd'、'g'、't',而不是'u'、'p'。我們?nèi)绾谓叹W(wǎng)絡(luò)捕捉上下文信息?使用BiLSTMs!但是,BiLSTMs會占用內(nèi)存,因此用戶可以根據(jù)需要選擇或取消這個階段。 

  4. 預(yù)測:這個階段從圖像的已識別特征中估計輸出字符序列。 


作者進(jìn)行了幾個實驗。他們?yōu)槊總€階段選擇了不同的網(wǎng)絡(luò)。準(zhǔn)確性總結(jié)在下表中:


代碼


CRAFT預(yù)測每個單詞的邊界框。四階段STR將單個單詞(作為圖像)作為輸入,并預(yù)測字母。如果你正在處理單個字的圖像(如CUTE80),使用這些DL模塊的OCR將會很輕松。

步驟1:安裝要求

步驟2:克隆代碼庫

步驟3:修改以返回檢測框分?jǐn)?shù) 

CRAFT返回高于一定分?jǐn)?shù)閾值的邊界框。如果你想看到每個邊界框的分?jǐn)?shù)值,我們需要對原始庫進(jìn)行一些更改。打開克隆的CRAFT Repository中的craft_utils.py文件。你需要將第83行和第239行更改為如下所示。

"""Modify to Return Scores of Detection Boxes"""
""" Copyright (c) 2019-present NAVER Corp.MIT License"""
# -*- coding: utf-8 -*-import numpy as npimport cv2import math
""" auxilary functions """# unwarp corodinatesdef warpCoord(Minv, pt): out = np.matmul(Minv, (pt[0], pt[1], 1)) return np.array([out[0]/out[2], out[1]/out[2]])""" end of auxilary functions """

def getDetBoxes_core(textmap, linkmap, text_threshold, link_threshold, low_text): # prepare data linkmap = linkmap.copy() textmap = textmap.copy() img_h, img_w = textmap.shape
""" labeling method """ ret, text_score = cv2.threshold(textmap, low_text, 1, 0) ret, link_score = cv2.threshold(linkmap, link_threshold, 1, 0)
text_score_comb = np.clip(text_score + link_score, 0, 1) nLabels, labels, stats, centroids = cv2.connectedComponentsWithStats(text_score_comb.astype(np.uint8), connectivity=4)
det = [] det_scores = [] mapper = [] for k in range(1,nLabels): # size filtering size = stats[k, cv2.CC_STAT_AREA] if size < 10: continue
# thresholding if np.max(textmap[labels==k]) < text_threshold: continue
# make segmentation map segmap = np.zeros(textmap.shape, dtype=np.uint8) segmap[labels==k] = 255 segmap[np.logical_and(link_score==1, text_score==0)] = 0 # remove link area x, y = stats[k, cv2.CC_STAT_LEFT], stats[k, cv2.CC_STAT_TOP] w, h = stats[k, cv2.CC_STAT_WIDTH], stats[k, cv2.CC_STAT_HEIGHT] niter = int(math.sqrt(size * min(w, h) / (w * h)) * 2) sx, ex, sy, ey = x - niter, x + w + niter + 1, y - niter, y + h + niter + 1 # boundary check if sx < 0 : sx = 0 if sy < 0 : sy = 0 if ex >= img_w: ex = img_w if ey >= img_h: ey = img_h kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(1 + niter, 1 + niter)) segmap[sy:ey, sx:ex] = cv2.dilate(segmap[sy:ey, sx:ex], kernel)
# make box np_contours = np.roll(np.array(np.where(segmap!=0)),1,axis=0).transpose().reshape(-1,2) rectangle = cv2.minAreaRect(np_contours) box = cv2.boxPoints(rectangle)
# align diamond-shape w, h = np.linalg.norm(box[0] - box[1]), np.linalg.norm(box[1] - box[2]) box_ratio = max(w, h) / (min(w, h) + 1e-5) if abs(1 - box_ratio) <= 0.1: l, r = min(np_contours[:,0]), max(np_contours[:,0]) t, b = min(np_contours[:,1]), max(np_contours[:,1]) box = np.array([[l, t], [r, t], [r, b], [l, b]], dtype=np.float32)
# make clock-wise order startidx = box.sum(axis=1).argmin() box = np.roll(box, 4-startidx, 0) box = np.array(box)
det.append(box) mapper.append(k) det_scores.append(np.max(textmap[labels==k]))
return det, labels, mapper, det_scores
def getPoly_core(boxes, labels, mapper, linkmap): # configs num_cp = 5 max_len_ratio = 0.7 expand_ratio = 1.45 max_r = 2.0 step_r = 0.2
polys = [] for k, box in enumerate(boxes): # size filter for small instance w, h = int(np.linalg.norm(box[0] - box[1]) + 1), int(np.linalg.norm(box[1] - box[2]) + 1) if w < 10 or h < 10: polys.append(None); continue
# warp image tar = np.float32([[0,0],[w,0],[w,h],[0,h]]) M = cv2.getPerspectiveTransform(box, tar) word_label = cv2.warpPerspective(labels, M, (w, h), flags=cv2.INTER_NEAREST) try: Minv = np.linalg.inv(M) except: polys.append(None); continue
# binarization for selected label cur_label = mapper[k] word_label[word_label != cur_label] = 0 word_label[word_label > 0] = 1
""" Polygon generation """ # find top/bottom contours cp = [] max_len = -1 for i in range(w): region = np.where(word_label[:,i] != 0)[0] if len(region) < 2 : continue cp.append((i, region[0], region[-1])) length = region[-1] - region[0] + 1 if length > max_len: max_len = length
# pass if max_len is similar to h if h * max_len_ratio < max_len: polys.append(None); continue
# get pivot points with fixed length tot_seg = num_cp * 2 + 1 seg_w = w / tot_seg # segment width pp = [None] * num_cp # init pivot points cp_section = [[0, 0]] * tot_seg seg_height = [0] * num_cp seg_num = 0 num_sec = 0 prev_h = -1 for i in range(0,len(cp)): (x, sy, ey) = cp[i] if (seg_num + 1) * seg_w <= x and seg_num <= tot_seg: # average previous segment if num_sec == 0: break cp_section[seg_num] = [cp_section[seg_num][0] / num_sec, cp_section[seg_num][1] / num_sec] num_sec = 0
# reset variables seg_num += 1 prev_h = -1
# accumulate center points cy = (sy + ey) * 0.5 cur_h = ey - sy + 1 cp_section[seg_num] = [cp_section[seg_num][0] + x, cp_section[seg_num][1] + cy] num_sec += 1
if seg_num % 2 == 0: continue # No polygon area
if prev_h < cur_h: pp[int((seg_num - 1)/2)] = (x, cy) seg_height[int((seg_num - 1)/2)] = cur_h prev_h = cur_h
# processing last segment if num_sec != 0: cp_section[-1] = [cp_section[-1][0] / num_sec, cp_section[-1][1] / num_sec]
# pass if num of pivots is not sufficient or segment widh is smaller than character height if None in pp or seg_w < np.max(seg_height) * 0.25: polys.append(None); continue
# calc median maximum of pivot points half_char_h = np.median(seg_height) * expand_ratio / 2
# calc gradiant and apply to make horizontal pivots new_pp = [] for i, (x, cy) in enumerate(pp): dx = cp_section[i * 2 + 2][0] - cp_section[i * 2][0] dy = cp_section[i * 2 + 2][1] - cp_section[i * 2][1] if dx == 0: # gradient if zero new_pp.append([x, cy - half_char_h, x, cy + half_char_h]) continue rad = - math.atan2(dy, dx) c, s = half_char_h * math.cos(rad), half_char_h * math.sin(rad) new_pp.append([x - s, cy - c, x + s, cy + c])
# get edge points to cover character heatmaps isSppFound, isEppFound = False, False grad_s = (pp[1][1] - pp[0][1]) / (pp[1][0] - pp[0][0]) + (pp[2][1] - pp[1][1]) / (pp[2][0] - pp[1][0]) grad_e = (pp[-2][1] - pp[-1][1]) / (pp[-2][0] - pp[-1][0]) + (pp[-3][1] - pp[-2][1]) / (pp[-3][0] - pp[-2][0]) for r in np.arange(0.5, max_r, step_r): dx = 2 * half_char_h * r if not isSppFound: line_img = np.zeros(word_label.shape, dtype=np.uint8) dy = grad_s * dx p = np.array(new_pp[0]) - np.array([dx, dy, dx, dy]) cv2.line(line_img, (int(p[0]), int(p[1])), (int(p[2]), int(p[3])), 1, thickness=1) if np.sum(np.logical_and(word_label, line_img)) == 0 or r + 2 * step_r >= max_r: spp = p isSppFound = True if not isEppFound: line_img = np.zeros(word_label.shape, dtype=np.uint8) dy = grad_e * dx p = np.array(new_pp[-1]) + np.array([dx, dy, dx, dy]) cv2.line(line_img, (int(p[0]), int(p[1])), (int(p[2]), int(p[3])), 1, thickness=1) if np.sum(np.logical_and(word_label, line_img)) == 0 or r + 2 * step_r >= max_r: epp = p isEppFound = True if isSppFound and isEppFound: break
# pass if boundary of polygon is not found if not (isSppFound and isEppFound): polys.append(None); continue
# make final polygon poly = [] poly.append(warpCoord(Minv, (spp[0], spp[1]))) for p in new_pp: poly.append(warpCoord(Minv, (p[0], p[1]))) poly.append(warpCoord(Minv, (epp[0], epp[1]))) poly.append(warpCoord(Minv, (epp[2], epp[3]))) for p in reversed(new_pp): poly.append(warpCoord(Minv, (p[2], p[3]))) poly.append(warpCoord(Minv, (spp[2], spp[3])))
# add to final result polys.append(np.array(poly))
return polys
def getDetBoxes(textmap, linkmap, text_threshold, link_threshold, low_text, poly=False): boxes, labels, mapper, det_scores = getDetBoxes_core(textmap, linkmap, text_threshold, link_threshold, low_text)
if poly: polys = getPoly_core(boxes, labels, mapper, linkmap) else: polys = [None] * len(boxes)
return boxes, polys, det_scores
def adjustResultCoordinates(polys, ratio_w, ratio_h, ratio_net = 2): if len(polys) > 0: polys = np.array(polys) for k in range(len(polys)): if polys[k] is not None: polys[k] *= (ratio_w * ratio_net, ratio_h * ratio_net) return polys

步驟4:從CRAFT中刪除參數(shù)解析器 

打開test.py并修改如下所示。我們刪除了參數(shù)解析器。

"""Modify to Remove Argument Parser"""
""" Copyright (c) 2019-present NAVER Corp.MIT License"""
# -*- coding: utf-8 -*-import sysimport osimport timeimport argparse
import torchimport torch.nn as nnimport torch.backends.cudnn as cudnnfrom torch.autograd import Variable
from PIL import Image
import cv2from skimage import ioimport numpy as npimport craft_utilsimport imgprocimport file_utilsimport jsonimport zipfile
from craft import CRAFT
from collections import OrderedDictdef copyStateDict(state_dict): if list(state_dict.keys())[0].startswith("module"): start_idx = 1 else: start_idx = 0 new_state_dict = OrderedDict() for k, v in state_dict.items(): name = ".".join(k.split(".")[start_idx:]) new_state_dict[name] = v return new_state_dict
def test_net(net, image, text_threshold, link_threshold, low_text, cuda, poly, args, refine_net=None): t0 = time.time()
# resize img_resized, target_ratio, size_heatmap = imgproc.resize_aspect_ratio(image, args.canvas_size, interpolation=cv2.INTER_LINEAR, mag_ratio=args.mag_ratio) ratio_h = ratio_w = 1 / target_ratio
# preprocessing x = imgproc.normalizeMeanVariance(img_resized) x = torch.from_numpy(x).permute(2, 0, 1) # [h, w, c] to [c, h, w] x = Variable(x.unsqueeze(0)) # [c, h, w] to [b, c, h, w] if cuda: x = x.cuda()
# forward pass with torch.no_grad(): y, feature = net(x)
# make score and link map score_text = y[0,:,:,0].cpu().data.numpy() score_link = y[0,:,:,1].cpu().data.numpy()
# refine link if refine_net is not None: with torch.no_grad(): y_refiner = refine_net(y, feature) score_link = y_refiner[0,:,:,0].cpu().data.numpy()
t0 = time.time() - t0 t1 = time.time()
# Post-processing boxes, polys, det_scores = craft_utils.getDetBoxes(score_text, score_link, text_threshold, link_threshold, low_text, poly)
# coordinate adjustment boxes = craft_utils.adjustResultCoordinates(boxes, ratio_w, ratio_h) polys = craft_utils.adjustResultCoordinates(polys, ratio_w, ratio_h) for k in range(len(polys)): if polys[k] is None: polys[k] = boxes[k]
t1 = time.time() - t1
# render results (optional) render_img = score_text.copy() render_img = np.hstack((render_img, score_link)) ret_score_text = imgproc.cvt2HeatmapImg(render_img)
if args.show_time : print("\ninfer/postproc time : {:.3f}/{:.3f}".format(t0, t1))
return boxes, polys, ret_score_text, det_scores

步驟5:編寫一個單獨的腳本,將圖像名稱和檢測框坐標(biāo)保存到CSV文件中 

這將幫助我們裁剪需要作為四階段STR輸入的單詞。它還幫助我們將所有與邊界框和文本相關(guān)的信息保存在一個地方。創(chuàng)建一個新文件(我將其命名為pipeline.py)并添加以下代碼。

import sysimport osimport timeimport argparse
import torchimport torch.nn as nnimport torch.backends.cudnn as cudnnfrom torch.autograd import Variable
from PIL import Image
import cv2from skimage import ioimport numpy as npimport craft_utilsimport testimport imgprocimport file_utilsimport jsonimport zipfileimport pandas as pd
from craft import CRAFT
from collections import OrderedDict
from google.colab.patches import cv2_imshow
def str2bool(v): return v.lower() in ("yes", "y", "true", "t", "1")
#CRAFTparser = argparse.ArgumentParser(description='CRAFT Text Detection')parser.add_argument('--trained_model', default='weights/craft_mlt_25k.pth', type=str, help='pretrained model')parser.add_argument('--text_threshold', default=0.7, type=float, help='text confidence threshold')parser.add_argument('--low_text', default=0.4, type=float, help='text low-bound score')parser.add_argument('--link_threshold', default=0.4, type=float, help='link confidence threshold')parser.add_argument('--cuda', default=True, type=str2bool, help='Use cuda for inference')parser.add_argument('--canvas_size', default=1280, type=int, help='image size for inference')parser.add_argument('--mag_ratio', default=1.5, type=float, help='image magnification ratio')parser.add_argument('--poly', default=False, action='store_true', help='enable polygon type')parser.add_argument('--show_time', default=False, action='store_true', help='show processing time')parser.add_argument('--test_folder', default='/data/', type=str, help='folder path to input images')parser.add_argument('--refine', default=False, action='store_true', help='enable link refiner')parser.add_argument('--refiner_model', default='weights/craft_refiner_CTW1500.pth', type=str, help='pretrained refiner model')
args = parser.parse_args()

""" For test images in a folder """image_list, _, _ = file_utils.get_files(args.test_folder)
image_names = []image_paths = []
#CUSTOMISE STARTstart = args.test_folder
for num in range(len(image_list)): image_names.append(os.path.relpath(image_list[num], start))

result_folder = './Results'if not os.path.isdir(result_folder): os.mkdir(result_folder)
if __name__ == '__main__':
data=pd.DataFrame(columns=['image_name', 'word_bboxes', 'pred_words', 'align_text']) data['image_name'] = image_names
# load net net = CRAFT() # initialize
print('Loading weights from checkpoint (' + args.trained_model + ')') if args.cuda: net.load_state_dict(test.copyStateDict(torch.load(args.trained_model))) else: net.load_state_dict(test.copyStateDict(torch.load(args.trained_model, map_location='cpu')))
if args.cuda: net = net.cuda() net = torch.nn.DataParallel(net) cudnn.benchmark = False
net.eval()
# LinkRefiner refine_net = None if args.refine: from refinenet import RefineNet refine_net = RefineNet() print('Loading weights of refiner from checkpoint (' + args.refiner_model + ')') if args.cuda: refine_net.load_state_dict(copyStateDict(torch.load(args.refiner_model))) refine_net = refine_net.cuda() refine_net = torch.nn.DataParallel(refine_net) else: refine_net.load_state_dict(copyStateDict(torch.load(args.refiner_model, map_location='cpu')))
refine_net.eval() args.poly = True
t = time.time()
# load data for k, image_path in enumerate(image_list): print("Test image {:d}/{:d}: {:s}".format(k+1, len(image_list), image_path), end='\r') image = imgproc.loadImage(image_path)
bboxes, polys, score_text, det_scores = test.test_net(net, image, args.text_threshold, args.link_threshold, args.low_text, args.cuda, args.poly, args, refine_net) bbox_score={}
for box_num in range(len(bboxes)): key = str (det_scores[box_num]) item = bboxes[box_num] bbox_score[key]=item
data['word_bboxes'][k]=bbox_score # save score text filename, file_ext = os.path.splitext(os.path.basename(image_path)) mask_file = result_folder + "/res_" + filename + '_mask.jpg' cv2.imwrite(mask_file, score_text)
file_utils.saveResult(image_path, image[:,:,::-1], polys, dirname=result_folder)
data.to_csv('/content/Pipeline/data.csv', sep = ',', na_rep='Unknown') print("elapsed time : {}s".format(time.time() - t))

pandas DataFrame(變量data)在單獨的列中存儲圖像名稱和其中包含的單詞的邊界框。我們?nèi)サ袅藞D像的完整路徑,只保留了圖像,以避免笨拙。你當(dāng)然可以根據(jù)自己的需要進(jìn)行定制。現(xiàn)在可以運行腳本了:

在這個階段,CSV看起來像這樣。對于每個檢測,我們都存儲了一個包含分?jǐn)?shù):坐標(biāo)的Python字典。


步驟6:裁剪單詞

現(xiàn)在我們有了每個框的坐標(biāo)和分?jǐn)?shù)。我們可以設(shè)置一個閾值,裁剪我們希望識別字符的單詞。創(chuàng)建一個新腳本crop_images.py。請記住,在提到的地方添加你的路徑。裁剪的單詞保存在'dir'文件夾中。我們?yōu)槊總€圖像創(chuàng)建一個文件夾,并以以下格式保存從中裁剪的單詞:<父圖像>_<由下劃線分隔的8個坐標(biāo)> 這樣做可以幫助你跟蹤每個裁剪單詞來自哪個圖像。

import osimport numpy as npimport cv2import pandas as pdfrom google.colab.patches import cv2_imshow
def crop(pts, image):
""" Takes inputs as 8 points and Returns cropped, masked image with a white background """ rect = cv2.boundingRect(pts) x,y,w,h = rect cropped = image[y:y+h, x:x+w].copy() pts = pts - pts.min(axis=0) mask = np.zeros(cropped.shape[:2], np.uint8) cv2.drawContours(mask, [pts], -1, (255, 255, 255), -1, cv2.LINE_AA) dst = cv2.bitwise_and(cropped, cropped, mask=mask) bg = np.ones_like(cropped, np.uint8)*255 cv2.bitwise_not(bg,bg, mask=mask) dst2 = bg + dst
return dst2

def generate_words(image_name, score_bbox, image):
num_bboxes = len(score_bbox) for num in range(num_bboxes): bbox_coords = score_bbox[num].split(':')[-1].split(',\n') if bbox_coords!=['{}']: l_t = float(bbox_coords[0].strip(' array([').strip(']').split(',')[0]) t_l = float(bbox_coords[0].strip(' array([').strip(']').split(',')[1]) r_t = float(bbox_coords[1].strip(' [').strip(']').split(',')[0]) t_r = float(bbox_coords[1].strip(' [').strip(']').split(',')[1]) r_b = float(bbox_coords[2].strip(' [').strip(']').split(',')[0]) b_r = float(bbox_coords[2].strip(' [').strip(']').split(',')[1]) l_b = float(bbox_coords[3].strip(' [').strip(']').split(',')[0]) b_l = float(bbox_coords[3].strip(' [').strip(']').split(',')[1].strip(']')) pts = np.array([[int(l_t), int(t_l)], [int(r_t) ,int(t_r)], [int(r_b) , int(b_r)], [int(l_b), int(b_l)]]) if np.all(pts) > 0: word = crop(pts, image) folder = '/'.join( image_name.split('/')[:-1])
#CHANGE DIR dir = '/content/Pipeline/Crop Words/'
if os.path.isdir(os.path.join(dir + folder)) == False : os.makedirs(os.path.join(dir + folder))
try: file_name = os.path.join(dir + image_name) cv2.imwrite(file_name+'_{}_{}_{}_{}_{}_{}_{}_{}.jpg'.format(l_t, t_l, r_t ,t_r, r_b , b_r ,l_b, b_l), word) print('Image saved to '+file_name+'_{}_{}_{}_{}_{}_{}_{}_{}.jpg'.format(l_t, t_l, r_t ,t_r, r_b , b_r ,l_b, b_l)) except: continue
data=pd.read_csv('PATH TO CSV')
start = PATH TO TEST IMAGES
for image_num in range(data.shape[0]): image = cv2.imread(os.path.join(start, data['image_name'][image_num])) image_name = data['image_name'][image_num].strip('.jpg') score_bbox = data['word_bboxes'][image_num].split('),') generate_words(image_name, score_bbox, image)

運行腳本:

步驟6:識別(最后!) 

現(xiàn)在你可以在裁剪的單詞上盲目運行識別模塊了。但如果你想讓事情更有條理,修改如下所示。我們在每個圖像文件夾中創(chuàng)建一個.txt文件,并將識別的單詞與裁剪圖像的名稱一起保存。除此之外,預(yù)測的單詞也保存在我們維護的CSV中。

import stringimport argparse
import torchimport torch.backends.cudnn as cudnnimport torch.utils.dataimport torch.nn.functional as F
from utils import CTCLabelConverter, AttnLabelConverterfrom dataset import RawDataset, AlignCollatefrom model import Modeldevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
import pandas as pdimport os
def demo(opt):

"""Open csv file wherein you are going to write the Predicted Words""" data = pd.read_csv('/content/Pipeline/data.csv')
""" model configuration """ if 'CTC' in opt.Prediction: converter = CTCLabelConverter(opt.character) else: converter = AttnLabelConverter(opt.character) opt.num_class = len(converter.character)
if opt.rgb: opt.input_channel = 3 model = Model(opt) print('model input parameters', opt.imgH, opt.imgW, opt.num_fiducial, opt.input_channel, opt.output_channel, opt.hidden_size, opt.num_class, opt.batch_max_length, opt.Transformation, opt.FeatureExtraction, opt.SequenceModeling, opt.Prediction) model = torch.nn.DataParallel(model).to(device)
# load model print('loading pretrained model from %s' % opt.saved_model) model.load_state_dict(torch.load(opt.saved_model, map_location=device))
# prepare data. two demo images from https://github.com/bgshih/crnn#run-demo AlignCollate_demo = AlignCollate(imgH=opt.imgH, imgW=opt.imgW, keep_ratio_with_pad=opt.PAD) demo_data = RawDataset(root=opt.image_folder, opt=opt) # use RawDataset demo_loader = torch.utils.data.DataLoader( demo_data, batch_size=opt.batch_size, shuffle=False, num_workers=int(opt.workers), collate_fn=AlignCollate_demo, pin_memory=True)
# predict model.eval() with torch.no_grad(): for image_tensors, image_path_list in demo_loader: batch_size = image_tensors.size(0) image = image_tensors.to(device) # For max length prediction length_for_pred = torch.IntTensor([opt.batch_max_length] * batch_size).to(device) text_for_pred = torch.LongTensor(batch_size, opt.batch_max_length + 1).fill_(0).to(device)
if 'CTC' in opt.Prediction: preds = model(image, text_for_pred)
# Select max probabilty (greedy decoding) then decode index to character preds_size = torch.IntTensor([preds.size(1)] * batch_size) _, preds_index = preds.max(2) # preds_index = preds_index.view(-1) preds_str = converter.decode(preds_index.data, preds_size.data)
else: preds = model(image, text_for_pred, is_train=False)
# select max probabilty (greedy decoding) then decode index to character _, preds_index = preds.max(2) preds_str = converter.decode(preds_index, length_for_pred)
dashed_line = '-' * 80 head = f'{"image_path":25s}\t {"predicted_labels":25s}\t confidence score' print(f'{dashed_line}\n{head}\n{dashed_line}') # log.write(f'{dashed_line}\n{head}\n{dashed_line}\n')
preds_prob = F.softmax(preds, dim=2) preds_max_prob, _ = preds_prob.max(dim=2) for img_name, pred, pred_max_prob in zip(image_path_list, preds_str, preds_max_prob): start = PATH TO CROPPED WORDS path = os.path.relpath(img_name, start)
folder = os.path.dirname(path)
image_name=os.path.basename(path)
file_name='_'.join(image_name.split('_')[:-8])
txt_file=os.path.join(start, folder, file_name) log = open(f'{txt_file}_log_demo_result_vgg.txt', 'a') if 'Attn' in opt.Prediction: pred_EOS = pred.find('[s]') pred = pred[:pred_EOS] # prune after "end of sentence" token ([s]) pred_max_prob = pred_max_prob[:pred_EOS]
# calculate confidence score (= multiply of pred_max_prob) confidence_score = pred_max_prob.cumprod(dim=0)[-1] print(f'{image_name:25s}\t {pred:25s}\t {confidence_score:0.4f}') log.write(f'{image_name:25s}\t {pred:25s}\t {confidence_score:0.4f}\n')
log.close()
if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('--image_folder', required=True, help='path to image_folder which contains text images') parser.add_argument('--workers', type=int, help='number of data loading workers', default=4) parser.add_argument('--batch_size', type=int, default=192, help='input batch size') parser.add_argument('--saved_model', required=True, help="path to saved_model to evaluation") """ Data processing """ parser.add_argument('--batch_max_length', type=int, default=25, help='maximum-label-length') parser.add_argument('--imgH', type=int, default=32, help='the height of the input image') parser.add_argument('--imgW', type=int, default=100, help='the width of the input image') parser.add_argument('--rgb', action='store_true', help='use rgb input') parser.add_argument('--character', type=str, default='0123456789abcdefghijklmnopqrstuvwxyz', help='character label') parser.add_argument('--sensitive', action='store_true', help='for sensitive character mode') parser.add_argument('--PAD', action='store_true', help='whether to keep ratio then pad for image resize') """ Model Architecture """ parser.add_argument('--Transformation', type=str, required=True, help='Transformation stage. None|TPS') parser.add_argument('--FeatureExtraction', type=str, required=True, help='FeatureExtraction stage. VGG|RCNN|ResNet') parser.add_argument('--SequenceModeling', type=str, required=True, help='SequenceModeling stage. None|BiLSTM') parser.add_argument('--Prediction', type=str, required=True, help='Prediction stage. CTC|Attn') parser.add_argument('--num_fiducial', type=int, default=20, help='number of fiducial points of TPS-STN') parser.add_argument('--input_channel', type=int, default=1, help='the number of input channel of Feature extractor') parser.add_argument('--output_channel', type=int, default=512, help='the number of output channel of Feature extractor') parser.add_argument('--hidden_size', type=int, default=256, help='the size of the LSTM hidden state')
opt = parser.parse_args()
""" vocab / character number configuration """ if opt.sensitive: opt.character = string.printable[:-6] # same with ASTER setting (use 94 char).
cudnn.benchmark = True cudnn.deterministic = True opt.num_gpu = torch.cuda.device_count() # print (opt.image_folder)
# pred_words=demo(opt) demo(opt)

從Clova AI STR Github Repository下載權(quán)重后,你可以運行以下命令:

我們選擇了這種網(wǎng)絡(luò)組合,因為它們的準(zhǔn)確性很高。現(xiàn)在CSV看起來是這樣的。pred_words有檢測框坐標(biāo)和預(yù)測的單詞,用冒號分隔。


結(jié)論

我們已經(jīng)集成了兩個準(zhǔn)確的模型,創(chuàng)建了一個單一的檢測和識別模塊?,F(xiàn)在你有了預(yù)測的單詞和它們的邊界框在一個單獨的列中,你可以以任何你想要的方式對齊文本!

       
下載1:OpenCV-Contrib擴展模塊中文版教程
在「小白學(xué)視覺」公眾號后臺回復(fù):擴展模塊中文教程,即可下載全網(wǎng)第一份OpenCV擴展模塊教程中文版,涵蓋擴展模塊安裝、SFM算法、立體視覺、目標(biāo)跟蹤、生物視覺、超分辨率處理等二十多章內(nèi)容。

下載2:Python視覺實戰(zhàn)項目52講
小白學(xué)視覺公眾號后臺回復(fù):Python視覺實戰(zhàn)項目即可下載包括圖像分割、口罩檢測、車道線檢測、車輛計數(shù)、添加眼線、車牌識別、字符識別、情緒檢測、文本內(nèi)容提取、面部識別等31個視覺實戰(zhàn)項目,助力快速學(xué)校計算機視覺。

下載3:OpenCV實戰(zhàn)項目20講
小白學(xué)視覺公眾號后臺回復(fù):OpenCV實戰(zhàn)項目20講,即可下載含有20個基于OpenCV實現(xiàn)20個實戰(zhàn)項目,實現(xiàn)OpenCV學(xué)習(xí)進(jìn)階。

交流群


歡迎加入公眾號讀者群一起和同行交流,目前有SLAM、三維視覺、傳感器、自動駕駛、計算攝影、檢測、分割、識別、醫(yī)學(xué)影像、GAN、算法競賽等微信群(以后會逐漸細(xì)分),請掃描下面微信號加群,備注:”昵稱+學(xué)校/公司+研究方向“,例如:”張三 + 上海交大 + 視覺SLAM“。請按照格式備注,否則不予通過。添加成功后會根據(jù)研究方向邀請進(jìn)入相關(guān)微信群。請勿在群內(nèi)發(fā)送廣告,否則會請出群,謝謝理解~


瀏覽 60
點贊
評論
收藏
分享

手機掃一掃分享

分享
舉報
評論
圖片
表情
推薦
點贊
評論
收藏
分享

手機掃一掃分享

分享
舉報

感谢您访问我们的网站,您可能还对以下资源感兴趣:

国产秋霞理论久久久电影-婷婷色九月综合激情丁香-欧美在线观看乱妇视频-精品国avA久久久久久久-国产乱码精品一区二区三区亚洲人-欧美熟妇一区二区三区蜜桃视频 天天干夜夜爽| 成人AV在线资源| 久爱视频| 日韩成人激情| 中文字幕三级片在线观看| 人妻在线观看| 三级网站在线播放| 老司机免费福利视频| 四季AV一区二区夜夜嗨| 欧美日韩一级A片| 日韩不卡视频在线| 免费色色| 中文字幕在线观看有码| 经典三级在线视频| 丰满人妻一区二区三区46| 十八禁福利网站| 操逼大毛片| 四虎国产精品成人久久| 色aV牛牛在线观看| 国产高清AV| 麻豆成人91精品二区三区| 久久免费观看视频| 一区二区三区电影高清电影免费观看 | 亚洲AV无码永久精品| 激情午夜av| 樱桃性爱视频| 蜜臀久久99精品| 日韩在线99| 亚洲无码AV免费观看| 亚洲码AV波多野| 人操人人人操| 男人天堂无码成人| 久久精品操| 国产激情电影| 国产乱伦熟女| 色天堂视频在线观看| 久久人妻无码中文字幕系列| AAAA毛片视频| 翔田千里高潮90分钟| 欧美成人图片视频在线| 老司机永久免费91| 欧美性猛交一区二区三区| 蜜臀久久99精品久久久久久牛牛| 99精品在线| 天天操操操| 久久精品99| 亚洲精品区| 在线无码高清| 久久在线视频| 一区二区久久| 成人无码视频| 国产成人免费视频| 另类老妇性BBwBBw| 蕉久中文字慕| 婷婷情色五月| 久久久久国产一区二区三区四区 | 国产精品777777| 精品无人区无码乱码毛片国产| 激情婷婷六月| 亚洲热在线视频| 国产九九热| 亚洲高清视频在线播放| 激情三区| 综合精品7799| 东京热91| 亚洲AV无码一区毛片AV| 人妻无码HEYZO少妇精品| 二区AV| 乱伦三级| 亚洲A级毛片| 国产A片视频| 成人免费观看视频| 国产成人在线免费观看| 伊人在线观看视频| 青青在线视频| 韩国三级中文字幕HD久久精品 | 日韩一区二区三免费高清在线观看| 日本操鸡小视频| 亚洲国产成人精品综合99| 欧美一级特黄AAAAAA片在线视频| 黄片网址在线观看| 日韩黄色免费网站| 免费在线观看AV片| 大香蕉75在线| 午夜亚洲福利| 日韩三级片无码| 91人妻人人澡人人爽人人精品乱| 欧美一级婬片AAAA毛片| 久久国产劲爆∧v内射| 麻豆91在线| 在线小视频| 亚洲欧美色图| 亚洲有码人妻| 51午夜福利| 简单av网| 亚洲精品影视| jizz无码| 久久久久久久麻豆| 免费的毛片| 色婷婷视频在线| 91蜜桃视频| 安徽妇搡BBBB搡BBBB小说| 久久欧洲成人精品无码区| 国产AV日韩AⅤ亚洲AV中文 | 黄色片网站在线观看| 欧美不卡视频| 人人摸人人操人人摸| 91AV免费看| av资源在线| 国产操逼片| 外国成人视频| 久久精品视频久久| 777国产盗摄偷窥精品0000| 国产精品尤物| 日韩无码你懂的| 亚洲无码三级视频| 口工视频| 极品美鮑20p| 黄片在线免费播放| 超碰九九| 韩国精品无码一区二区三区18| 久久久WWW成人免费精品| 午夜99| 神马午夜久久| 成人免费黄片| 国产性爱电影网| 亚洲精品系列| 加勒比一区二区三区| 无码在线高清| 日本伊人大香蕉| 国产成人AV网站| av在线天堂| 国产av探花| 无码专区av| 天天舔天天操| 日日骚av一区二区三区| 亚洲AV成人精品一区二区三区 | 亚洲精品97| 色五月婷婷小说| 国产传媒一区| 91吴梦梦一区二区传媒| 婷婷五月天无码| 欧美久久久| 亚洲无码高清在线观看视频| 国产乱子伦一区二区三区视频 | 免费在线亚洲| 91丝袜一区二区三区| 亚洲天堂2025| 婷婷欧美| 亚洲精品成人片在线观看精品字幕| 三级乱伦视频| 日本理论片一道本| 国产色综合视频| 特级西西WWW888| 久色视频福利| 一区二区三区四区在线视频| 黄色操逼大片| AV中文字幕在线播放| 免费视频a| 亚洲免费在线婷婷| 激情婷婷六月| 美女扣穴| 国产二区三区| www.四虎成人网站| 91白丝在线观看| 日韩美在线| 亚洲日韩视频在线播放| 日韩性爱无码| 亚洲小说图片AV在线| 亚洲五月激情| 亚洲AV黄色| 91色在线| 亚洲第一伊人| 日韩无码不卡电影| 欧美中文字幕视频| 三级无码中文| 中文字幕乱妇无码Av在线| 久久久久久三级电影| 天天天做夜夜夜爽无码| 欧美精品系列| 香蕉伊人在线| aaa在线免费视频| 伊人大香焦网| 中文字幕精品人妻| 学生妹毛片| 色吧五月| 国产淫荡视频| 不卡的av在线| 婷婷五月丁香五月| 一本色道久久综合狠狠躁| 国产精品av在线播放| 精品一区二区久久久久久久网站| 毛片一区二区| 日韩无码不卡电影| 婷婷欧美日韩| 成人久久精品| 日本一级特黄电影| 先锋AV资源站| 国产欧美日韩一区二区三区| 悠悠色综合| 国产一区二区免费看| 天天撸天天日| 久久免费视频播放| 国产又黄又爽| 9l视频自拍蝌蚪9l视频成人| 久久婷婷成人综合色怡春院| 无码AV中文字幕| 九色91| 精品人妻系列| 久久91精品| 午夜无码精品一区二区三区99午| 懂色中文字幕| 亚洲无码一级视频| 一级黄色视频免费看| 538在线视频| 9l视频自拍蝌蚪9l视频成人| 91爱逼| 国产又爽又黄免费网站在线观看| 人妻无码HEYZO少妇精品| 无码免费在线观看视频| 一级a一级a爱片免费免免高潮| 在线观看免费黄色视频| 色视频网| 日韩免费看| 久久福利导航| 青娱乐亚洲视频在线| 粉嫩护士小泬18p| 亚洲免费在线观看视频| 天天日综合网| 精东影业AV无码精品| 成人免费大香蕉| 操b在线免费观看| 男人天堂新地址| av无码在线播放| 秋霞亚洲| 俺也日| 成人黄色电影在线观看| 久久三级片电影| 欧美色视频一区二区三区在线观看| www.插插插| 亚洲精品无码在线播放| 欧洲美一区二区三区亚洲| 狼友视频在线播放| 国产又黄又大又粗| 东方av在线免费观看| 少妇福利| 久操新在线| 国产豆花视频| 国产一区二区三区视频| 人妻丰满精品一区二区| 久久精品一区二区三区蜜芽的特点 | 欧美亚洲日韩一区| 国产精品主播| 加勒比DVD手机在线播放观看视频| 亚洲欧美在线视频观看| 俄罗斯熟妇搡BBBB搡BBBB| 色色色无码| 日韩性爱av| 成人在线精品| 国产精品无码一区二区三| 少妇bbb搡bbbb搡bbbb| 色五月激情五月| 操逼首页123| 国产色综合视频| 操女人逼AV| 羽月希奶水饱胀在线播放| www.五月婷婷| 国产一级黄色A片| 再深点好爽灬轻点久久国产| 91福利在线观看| 狼友视频免费在线观看| 男女视频网站| 久草在线资源| 激情小说五月天| 国产97热人人| 99久久久无码国产精品性波多| 国产一区二区AV| 日韩精品免费一区二区在线观看| 伊人无码在线| 91操美女视频| 蜜桃性爱视频| 西西4444WWW大胆无视频| 强伦人妻一区二区三区视频| 人妻少妇一区二区三区| 色色丁香五月天| 成人久久久久| 国产特級黃色大片| 亚洲午夜电影| 亚洲电影在线观看| 在线看v片| 久在线观看| 亚洲免费观看A∨中文| 中文字幕天天干| 四虎国产精品成人久久| 亚洲成人视频免费在线观看| 欧美伊人| 91看片看婬黄大片女跟女| 婷婷国产亚洲精品网站| 浮力影院av| 成人午夜无码视频| 亚洲超级高清无码第一在线视频观看 | 日韩高清无码三级片| 国产精品久久久| 天天艹天天干| 影音先锋成人在线| 天天操天天日天天射| 一级爱爱免费视频| 激情自拍偷拍| 国产欧美一区二区三区在线看蜜臀 | 中文字幕国产综合| 大鸡巴久久久| 亚洲操逼图片| 国产福利电影在线观看| 91视频黄| 操少妇视频| 国产成人精品片| AV一区二区三区四区| 久久久久人| 真实野外打野视频| 国产精品久久久91| 日逼逼| 国产剧情自拍| 乱伦网址| 在线视频三区| 日韩操逼网站| 欧美性爱免费在线视频| 亚洲第1页| 国产无遮挡又黄又爽又| 性满足BBWBBWBBW| 精品久久久999| 色五月婷婷综合| 欧美成人乱码一区二区三区| 欧美操逼视频网站| 亚洲中文字幕免费观看视频| 亚洲AV毛片| 国产女人水真多18毛片18精品 | 国产欧美日韩| 一本色道久久88亚洲精品综合| 中文字幕国产精品| 人人操人人妻人人| 日韩性爱无码| 无码AV电影在线观看| 五月天激情电影| 91久久无码一区人妻A片蜜桃| 青娱乐偷拍| 18害羞勿进网站国产| 影音先锋亚洲无码| 日日操日日摸| 秋霞久久日| 成人午夜av| 啪啪啪av| 俺去啦在线视频| 91AV免费| 波多野结衣AV在线播放| 99热国品| 黄色无码视频| 视色视频在线观看18| 韩国中文字幕HD久久| 天天爽天天搞| 蜜芽av在线观看| 97热热| 精品久久无码中文字幕| 国产乱伦电影| 操B视频免费看| 欧美怡春院| 国产AV小电影| 欧美日韩高清一区| 日韩中文字幕久久| 午夜丁香婷婷| 国产在线一区二区| 一级黄色免费看| 亚洲无码在线观看免费| 亚洲久久久久久| 久久久老熟女一区二区三区91 | 中文无码人妻少妇| 欧美A区| 日本乱轮视频| 日本五十路| 久久成人网豆花视频| 亚洲成人少妇老妇a视频在线 | 国产乱子伦| 日韩一区二区视频| 久久一道| 91日日| 激情小视频| 中文字幕免费毛片| 色妹子综合| 久草资源在线观看| 亚洲第一色在线| 欧美一道本| 操b视频在线免费观看| 久色网| 亚洲综合精品| 丁香花在线高清完整版视频| 欧美黑吊大战白妞| 男人V天堂| 最全av在线| 无码囯无精品毛片大码| 啊啊啊在线| 日日夜夜干| 午夜成人精品| www.伊人网| 熟女网址| 中文字幕在线一区二区a| 国产精品怡红院有限公司| 少妇bbw搡bbbb搡bbbb| 日韩免费片| 免费操逼网站| 偷拍亚洲欧美| 婷婷久久久久久| 超碰99在线| 亚洲激情片| 午夜视频无码| 一级操逼| 无码在线观看免费视频| 国产一级在线免费观看| 91视频免费网站| 午夜亚洲福利| zzjicom| 日韩黄色三级片| 色婷婷18禁| 欧美特黄AAA| 中文字幕日韩欧美| 国产精品第二页| 中文字幕H| 亚洲AV成人无码精在线| 成人高清无码在线观看| 婷婷丁香五月花| 高清无码三级片| 亚洲欧美网站| 色色色五月婷婷| 特级西西444www大胆免费看 | 安徽扫搡BBBB揉BBBB| 色婷婷精品视频| 国产伦精品一区二区三区色大师 | 男女一区二区三区| 人操人人| 日本一级片在线观看| 无码国产+白浆| 懂色av一区蜜桃| 91欧美视频| 国产精品av在线播放| 青操AV| 中文字幕成人网| 精品77777| 日韩av小说| 亚洲精品成人无码| 内射在线| 另类无码| 蜜臀AV成人| 欧美不卡一区| 91久久亚洲| 波多野吉衣av| 欧美成人视频。| 91亚洲国产成人精品一区| 色婷婷播放| 欧美在线看片| 91青青| 日韩中文一区| 91九色蝌蚪91POR成人| 超碰在线进入| 婷婷精品| 成人高清无码视频| 欧美一级黃色A片免费看蜜桃熟了| 天天操嫩逼无套视频| 久久久久91| 77久久| 91在线电影| 久久毛| 一级黄色电影在线观看| 中文字幕在线中文| jizz免费观看| 天天色天天色| 日韩午夜福利视频| 自拍偷拍影音先锋| 亚洲成人精品一区| 夜夜爱爱| 黄页网站免费在线观看| 日韩成人网站在线观看| 国产一级性爱| 久久精品水多多www| 亚洲成人精品在线观看| 美女大香蕉| 影音先锋91久久网| 青草视频精品| 欧美在线中文字幕| 午夜高清视频| 亚洲欧美日韩动漫| 爽爽午国产浪潮AV性色www| 狼人综合网| 大香蕉官网| 日韩在线视频中文字幕| 先锋影音AV资源站| 午夜福利电影无码| 91豆花视频18| 日韩精品一二三| 免费成人视频| 亚洲无码人妻在线| 日韩精品一区二区三区四在线播放 | 国产精品色在线| 中日韩中文字幕一区二区区别| 五月婷婷丁香| 欧美成人性爱视频| 日韩欧美精品18| 欧美综合婷婷| 日本精品在线观看视频| 国产成人性| 国内久久| Japanese在线观看| 东北嫖老熟女一区二区视频网站| 久久与婷婷| 骚婷婷| 亚欧洲精品在线视频| 成人做爱免费看| 色欲无码| 91人妻在线| 大香蕉久久伊人| 国产在线观看97| 国产天堂| 日本精品码喷水在线看| 亚洲黄色视频免费看| 日本免费精品| 三级乱伦视频| 欧美性BBwBBwBBwHD| 亚洲av电影在线观看| 三级片91| 桃色五月天| 成人免费网站在线| 天堂无码高清| 大鸡巴视频在线| 甘肃WBBBB搡wBBBB| 欧美综合激情| 91亚洲精品乱码久久久久久蜜桃 | 国产又爽又黄免费网站在线观看| 国产91精品在线观看| 少妇搡BBBB搡BBB搡造水多/| 国产最新福利| 一区二区中文字幕| 国产在线欧美在线| 欧美成人精品欧美一级乱黄| 五月天国产精品| 精品国产三级片| 波多野结衣大战黑人| 精品无码9| 色色色91| 香蕉av在线观看| 超碰在线观看97| 黄色成人视频在线免费观看| 丰满熟妇人妻中文字幕| 精品无码一区二区Av蜜桃| 艹逼无码| 中文字幕资源在线| 麻豆视频在线免费观看| 伊人免费视频| www.av在线| 日韩免费网站| 永久免费av| 麻豆成人精品国产免费| 狠狠成人| 草久在线| 久久久aaa| 青操AV| 中国熟女网站| 国产亚洲色婷婷久久99精品91| 亚洲精品免费观看| 一区二区国产精品| AV网站在线免费观看| 青青草原在线免费| 美女性爱视频网站| 色九九视频| 日韩毛片在线视频x| 韩国日本美国免费毛片| 人妻人人操| 国产精品一级片| 一级理论片| 日韩精品中文字幕无码| 麻豆传媒电影| 谁有毛片网站| 欧美日韩亚洲成人| 超清无码在线| 欧美在线A| 国产欧美综合在线观看| 国产一区免费观看| 欧美日韩不卡在线| 国产嫩草久久久一二三久久免费观看 | 自拍偷拍无码| 七十路の高齢熟妇无码| 一区二区三区电影| 亚洲国产熟妇无码日韩| 国产精品欧美一区二区| 中国婬乱a| 欧美三级无码| 丁香五月天激情网| 亚洲欧美日韩成人| 91成人三级| 96精品久久久久久久久久| 亚洲AV无码一区毛片AV| 亚洲欧美在线综合| 国产婷婷久久Av免费高清| 综合+++夜夜| 国产操屄视频| 亚洲高清无码在线| 欧美一级内射| 国产激情在线播放| av水果派| 国产h在线观看| 欧美日韩成人视频| 国产黄色免费乱伦片| 欧美少妇视频| 成人电影一区二区| 嫩草视频网站| 欧洲亚洲免费视频| 欧美a片在线观看| 国产亚洲中文| 肏屄视频在线播放| 无码区一区二区| 日本一级黄色A片| 精品码产区一区二亚洲国产| 久久不射网站| 人人操超碰在线观看| 俺来也俺去也www色| 在线看A片| 影音先锋亚洲无码| 九色自拍| 亚洲AV成人无码久久精品麻豆| 久操视频免费观看| 亚洲国产中文字幕| 免费黄色视频大全| 国产精品成人无码a无码| 人妻成人网| 2025国产成人精品一区| 亚洲日本黄色视频| 99xav| 69成人国产| 国产成人午夜视频| 亚洲三级视频在线播出| 人人色人人黄| 青青无码视频| 丰满人妻-区二区三区| 日韩黄色精品| 国产欧美日韩综合| 在线你懂的| 日韩欧美中文| 国产亚洲久一区二区写真| 成人黄色在线| 在线免费观看黄色小视频| 成年人免费视频网站| 五月婷亚洲精品AV天堂| 三级片无码在线观看| 国产精品一区二| 香蕉操逼视频| 乱伦视频网站| 双飞人妻13p| 777777视频| 无码精品ThePorn| 黄片免费大全| 中文字幕成人| 综合导航无码| 天天爽夜夜爽精品成人免费 | 国产又爽又黄免费视频免费| 国产黄在线观看| 精品无码秘人妻一区二区三区| 一级黄色视频网站| 欧美精品99久久久| 国精产品乱码一区一区三区四区 | 中文字幕在线视频观看| 亚洲日韩在线播放| 中文字幕三级片在线观看| 丝袜足交视频在线观看| 无码精品一区二区三区在线观看| 刘玥精品A片在线观看| 亚洲无码在线资源| 国产日韩一区二区三免费高清| 91无码精品国产AⅤ| www.五月天.con| 秋霞一区二区| 日韩一级片免费观看| 国产亚洲欧美精品综合在线| 影音先锋av中文字幕| 国产一级a一级a免费视频| 日韩福利在线| 欧美亚洲一区| 免费AV在线| 97无码免费| 免费看A级片| 五月天黄色电影网站| 夜夜撸一撸| 亚洲婷婷综合网| 久久综合久| 欧美成人怡红院| 日韩特级毛片| 成人A片免费看| 国产精品性爱| 99久久精品国产色欲| 中文字幕的色| 亚洲a级毛片| 熟女人妻人妻の视频| 天天撸天天日| 91看片看婬黄大片女跟女| 狠狠干伊人| 九九色| 人人操人人干人人摸| 91av在线看| 亚洲中文字幕在线播放| 大香蕉免费中文| 日本少妇高潮喷水XXXXXXX| 蝌蚪窝在线视频免费观看| 成人做爰黄A片免费看| 无码专区在线观看| 日韩午夜AV| 亚洲香蕉在线| 日本免费A片| 欧美日韩逼| 中文字幕www一区| 91啦丨熟女露脸| 夜夜撸日日| 中国免费一级无码成人片| 国产精品成人无码a无码| 91玖玖| 久热99| 亚洲avwww| 欧美日韩成人网站| 黑人巨大翔田千里AⅤ| 无码V| 麻豆mdapp03.tⅴ| 日韩电影一区| 逼逼AV网站-日韩电影| 国产精品51麻豆cm传媒| 欧美色影院| www免费视频在线观看播放| 91麻豆精品国产| 日韩欧美中文在线| 天天色色| 日韩精品影视| 91亚洲日韩| 精品动漫3D一区二区三区免费版| 天堂久草| 中文字幕乱视频| 久久久精品| 摸BBB槡BBBB搡BBB,,,,,| 超碰97成人| 一级电影视频去去去| 午夜福利久久| 中文字幕人妻无码| 亚洲黄色在线| 日韩成人在线看| 一级二级三级毛片| 精品无码一区二区三区的天堂| 一级av片| 欧美成人网站在线观看| 成人女人18女人毛片| 蜜臀久久99久久久久久宅男 | www.天天操| 奇米影视亚洲春色| 女人高潮天天躁夜夜躁| 成人毛片一区二区三区无码| 人人看人人摸人人草| 国产在线拍偷自揄拍无码一区二区 | 一级黄色免费片| 午夜褔利| 国产亚洲视频在线观看| 久久午夜无码鲁丝片午夜精品偷窥| 俺也来俺也去WWW色| AV在线导航| 亚洲人妻一区二区| 一级黄色电影网站| 色999在线播放视频| xxxx日韩| 欧美久久大香蕉| 人妻人人操人人爽| 影音先锋成人资源| 五月花在线视频| 1000部毛片A片免费视频| 午夜男人天堂| 欧美综合色| 色999在线播放视频| 成人一级黄色电影| 思思热思思操| 人人操碰| 丁香六月婷婷| 狠狠撸综合| 中国特级毛片| 欧美一道本| 日逼网址| 亚洲AV无码高清| 一级黄色电影免费| 2018最好看的中文字幕高清电影| 中文字幕在线观看免费视频| a√在线视频| 91精品婷婷国产综合久久蝌蚪 | 天堂v视频| 欧美中文字幕在线播放| 国产欧美日韩在线观看| 欧美综合亚洲图片综合区| 91亚洲日韩| 69国产在线| 亚洲无码高清视频在线观看| a片在线电影网| 亚洲天堂三级片| 五月丁香狠狠爱| 国产56页| 国产主播精品| 豆花视频在线免费观看| 无套免费视频欧美| 日韩视频在线观看免费| 美日韩综合| 日韩人妻在线播放| 99视频久久| 97国产| 日本色情在线| 色乱视频| 国产AV一区二区三区四区| 日都一级A片| 黑人在线视频| 伊人一区二区三区| 亚洲无码视频免费观看| 中文字幕精品久久久久人妻红杏Ⅰ | 国产黄色视频免费看| 老鸭窝在线观看视频| 麻豆免费福利视频| 欧美69成人| 婷婷五月六月丁香| 久草社区| 国产—级a毛—a毛免费视频| 在线激情网站| 先锋影音av资源网| 欧美东京热视频| 人人操人人摸人人爽| 五月丁香婷婷色| 免费黄色网址啊不卡| www.俺去啦| 最新色站| 成人视频网站在线观看| 亚洲色一| 欧美成人毛片一级A片| 51成人网站| 大鸡巴日小逼| 无码一级二级| 大鸡吧在线观看| 亚洲小电影在线观看| 亚洲中文字幕2019| 欧美日韩高清在线| 444444免费高清在线观看电视剧的注意| 成人免费黄色视频网站| 色色免费视频| www.在线播放| 国产91无码| 人人操在线观看| 久久精品水多多www| 亚洲天堂国产| 操小骚逼视频| 国产欧美一区二区三区国产幕精品| 日韩在线三级片| 亚洲无码av在线播放| 中国一级黄色A片| 91精彩视频在线观看| 日韩中文字幕有码| 88国产精品| 在线国产福利| 成人在线免费视频观看| 无套内射免费视频| 在线观看视频免费无码免费视频 | 国产A片免费看| 国产伦精品一区二区三区色大师 | 91内射| 成人无码网站在线观看| 中文字幕高清在线| 日韩天堂av| 青青草免费在线观看| 另类罕见稀奇videos| 做aAAAAA免费视频| 成人做爰黄A片免费视频网站野外 国产成人午夜精品无码区久久麻豆 | 亚洲一区无码在线观看| 丁香五月六月婷婷| 中文字幕三区| 激情五月天开心网| 羞羞视频com.入口| 国产成人av| 欧美日韩日逼视频| www男人的天堂| 看90后操B| 天天玩夜夜玩天天玩国产99| 性爱免费视频网站| 久久男人天堂| 国产性爱一级片| 在线天堂999| www.18av| 天天日天天色| 国产A片一区| 久一视频| 国产成人在线视频| 九九九视频在线观看| 无码免费视频在线观看| 肏逼网站在线观看| 久久婷婷五月综合伊人| 国产美女高潮| 毛片天天干| 婷婷五月AV| 国产精品后入| 无码人妻精品一区二区蜜桃漫画 |