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

如何用 OpenCV、Python 和深度學(xué)習(xí)實現(xiàn)面部識別?

共 33952字,需瀏覽 68分鐘

 ·

2021-07-05 07:46

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

重磅干貨,第一時間送達

本文轉(zhuǎn)自|新機器視覺

Face ID 的興起帶動了一波面部識別技術(shù)熱潮。本文將介紹如何使用 OpenCV、Python 和深度學(xué)習(xí)在圖像和視頻中實現(xiàn)面部識別,以基于深度識別的面部嵌入,實時執(zhí)行且達到準確度。

以下為譯文:

想知道怎樣用OpenCV、Python和深度學(xué)習(xí)進行面部識別嗎?

這篇文章首先將簡單介紹下基于深度學(xué)習(xí)的面部識別的工作原理,以及“深度度量學(xué)習(xí)”(deep metric learning)的概念。接下來我會幫你安裝好面部識別需要的庫。最后我們會發(fā)現(xiàn),這個面部識別的實現(xiàn)能夠?qū)崟r運行。


理解深度學(xué)習(xí)面部識別嵌入


那么,基于深度學(xué)習(xí)的面部識別是怎樣工作的呢?秘密就是一種叫做“深度度量學(xué)習(xí)”的技術(shù)。

如果你有深度學(xué)習(xí)的經(jīng)驗,你應(yīng)該知道,通常情況下訓(xùn)練好的網(wǎng)絡(luò)會接受一個輸入圖像,并且給輸入的圖像生成一個分類或標簽。

而在這里,網(wǎng)絡(luò)輸出的并不是單一的標簽(也不是圖像中的坐標或邊界盒),而是輸出一個表示特征向量的實數(shù)。

對于dlib面部識別網(wǎng)絡(luò)來說,輸出的特征向量為128維(即一個由128個實數(shù)組成的列表),用來判斷面部。網(wǎng)絡(luò)的訓(xùn)練是通過三元組進行的:

圖1:利用深度度量學(xué)習(xí)進行面部識別需要“三元組訓(xùn)練”。三元組包括三張不同的面部圖像,其中兩張屬于同一個人。神經(jīng)網(wǎng)絡(luò)為每張面部圖像生成一個128維向量。對于同一個人的兩張面部圖像,我們調(diào)整神經(jīng)網(wǎng)絡(luò)使得輸出向量的距離度量盡可能接近。圖片來源:Adam Geitgey的“Machine Learning is Fun”博客(https://medium.com/@ageitgey/machine-learning-is-fun-part-4-modern-face-recognition-with-deep-learning-c3cffc121d78

這里我們需要給網(wǎng)絡(luò)提供三張圖片:

其中兩張圖片是同一個人的面部;第三張圖片是從數(shù)據(jù)集中取得的隨機面部圖片,并且保證與另外兩張圖片不是同一個人。以圖1為例,這里我們用了三張圖片,一張是Chad Smith,兩張是Will Ferrell。

網(wǎng)絡(luò)會測試這些面部圖片,并為每張圖片生成128維嵌入(embedding,即qualification)。

接下來,基本思路就是調(diào)整神經(jīng)網(wǎng)絡(luò)的權(quán)重,使得兩張Will Ferrell的測量結(jié)果盡量接近,而Chad Smith的測量結(jié)果遠離。

我們的面部識別網(wǎng)絡(luò)的架構(gòu)基于He等人在《Deep Residual Learning for Image Recognition》(https://arxiv.org/abs/1512.03385)中提出的ResNet-34,但層數(shù)較少,而且過濾器的數(shù)量減少了一半。

網(wǎng)絡(luò)本身由Davis King(https://www.pyimagesearch.com/2017/03/13/an-interview-with-davis-king-creator-of-the-dlib-toolkit/)在大約300萬張圖片上訓(xùn)練。在Labeled Faces in the Wild(LFW)(http://vis-www.cs.umass.edu/lfw/)數(shù)據(jù)集上與其他方法相比,該網(wǎng)絡(luò)的準確度達到了99.38%。

Davis King(dlib的作者)和Adam Geitgey(https://adamgeitgey.com/, 我們即將用到的face_recognition模塊的作者)都有文章介紹了基于深度學(xué)習(xí)的面部識別的工作原理:

  • High Quality Face Recognition with Deep Metric Learning(Davis,http://blog.dlib.net/2017/02/high-quality-face-recognition-with-deep.html

  • Modern Face Recognition with Deep Learning( Adam,https://medium.com/@ageitgey/machine-learning-is-fun-part-4-modern-face-recognition-with-deep-learning-c3cffc121d78

強烈建議閱讀以上文章,以深入了解深度學(xué)習(xí)面部嵌入的工作原理。


安裝面部識別庫


為了用Python和OpenCV吸納面部識別,我們需要安裝一些庫:

  • dlib(http://dlib.net/);

  • face_recognition(https://github.com/ageitgey/face_recognition)。

由Davis King維護的dlib庫包含了“深度度量學(xué)習(xí)”的實現(xiàn),用來在實際的識別過程中構(gòu)建面部嵌入。

Adam Geitgey創(chuàng)建的face_recognition庫則封裝了dlib的面部識別功能,使之更易用。

我假設(shè)你的系統(tǒng)上已經(jīng)裝好了OpenCV。如果沒有也不用擔心,可以看看我的OpenCV安裝指南一文(https://www.pyimagesearch.com/opencv-tutorials-resources-guides/),選擇適合你的系統(tǒng)的指南即可。

這里我們來安裝dlib和face_recognition庫。

注意:下面的安裝過程需要在Python虛擬環(huán)境中進行。我強烈推薦使用虛擬環(huán)境來隔離項目,這是使用Python的好習(xí)慣。如果你看了我的OpenCV安裝指南,并且安裝了virtualenv和virtualenvwrapper,那么只要在安裝dlib和face_recognition之前執(zhí)行workon命令即可。

安裝沒有GPU支持的dlib

如果你沒有GPU,可以用pip安裝dlib(參考這篇指南:https://www.pyimagesearch.com/2018/01/22/install-dlib-easy-complete-guide/)。

$ workon # optional
$ pip install dlib

或者從源代碼進行編譯:

$ workon <your env name here> # optional
$ git clone https://github.com/davisking/dlib.git
$ cd dlib
$ mkdir build
$ cd build
$ cmake .. -DUSE_AVX_INSTRUCTIONS=1
$ cmake --build .
$ cd ..
$ python setup.py install --yes USE_AVX_INSTRUCTIONS

安裝有GPU支持的dlib(可選)

如果你有兼容CUDA的GPU,那么可以安裝有GPU支持的dlib,這樣面部識別能更快、更精確。

我建議從源代碼安裝dlib,這樣可以更精細地控制安裝過程:

$ workon <your env name here> # optional
$ git clone https://github.com/davisking/dlib.git
$ cd dlib
$ mkdir build
$ cd build
$ cmake .. -DDLIB_USE_CUDA=1 -DUSE_AVX_INSTRUCTIONS=1
$ cmake --build .
$ cd ..
$ python setup.py install --yes USE_AVX_INSTRUCTIONS --yes DLIB_USE_CUDA

安裝face_recognition包

face_recognition模塊只需簡單地使用pip命令即可安裝:

$ workon <your env name here> # optional
$ pip install face_recognition

安裝imutlis

我們還需要imutils包提供一些遍歷的函數(shù)。在Python虛擬環(huán)境中使用pip即可:

$ workon <your env name here> # optional
$ pip install imutils


面部識別數(shù)據(jù)集


圖2:利用Python和Bing圖像搜索API自動創(chuàng)建的面部識別數(shù)據(jù)集,圖中顯示的是電影侏羅紀公園的六個角色。

1993年的《侏羅紀公園》是我最喜歡的電影,為了紀念最新上映的《侏羅紀世界:失落王國》,我們將使用電影中的一些角色進行面部識別:

Alan Grant,古生物學(xué)家(22張圖像)

Clair Dearing,公園管理人(53張圖像)

Ellie Sattler,古生物學(xué)家(31張圖像)

Ian Malcolm,數(shù)學(xué)家(41張圖像)

John Hammond,商人,侏羅紀公園所有者(36張圖像)

Owen Grady,恐龍研究學(xué)者(35張圖像)

這個數(shù)據(jù)集只需要30分鐘就可以建好,參見我的文章《怎樣(快速)建立深度學(xué)習(xí)圖像數(shù)據(jù)集》(https://www.pyimagesearch.com/2018/04/09/how-to-quickly-build-a-deep-learning-image-dataset/)。

有了這個數(shù)據(jù)集,我們可以:

  • 為數(shù)據(jù)集中的每張圖像建立128維嵌入;

  • 利用這些嵌入,從圖像和視頻中識別每個角色的面部。


面部識別項目結(jié)構(gòu)


項目結(jié)構(gòu)可以參考下面的tree命令的輸出結(jié)果:

$ tree --filelimit 10 --dirsfirst
.
├── dataset
│   ├── alan_grant [22 entries]
│   ├── claire_dearing [53 entries]
│   ├── ellie_sattler [31 entries]
│   ├── ian_malcolm [41 entries]
│   ├── john_hammond [36 entries]
│   └── owen_grady [35 entries]
├── examples
│   ├── example_01.png
│   ├── example_02.png
│   └── example_03.png
├── output
│   └── lunch_scene_output.avi
├── videos
│   └── lunch_scene.mp4
├── search_bing_api.py
├── encode_faces.py
├── recognize_faces_image.py
├── recognize_faces_video.py
├── recognize_faces_video_file.py
└── encodings.pickle

10 directories, 11 files

該項目有4個頂層目錄:

  • dataset/:包含六個角色的面部圖像,用角色名組織到各個子目錄中;

  • examples/:包含三個不屬于該數(shù)據(jù)集的測試圖像;

  • output/:存儲經(jīng)過面部識別處理后的視頻,上面有我生成的一個視頻,來自于原版《侏羅紀公園》電影的午飯場景;

  • videos/:輸入視頻存放于該文件夾中,該文件夾也包含了尚未經(jīng)過面部識別的“午飯場景”的視頻。

根目錄下還有6個文件:

  • search_bing_api.py:第一步就是建立數(shù)據(jù)集(我已經(jīng)幫你做好了)。關(guān)于利用Bing API建立數(shù)據(jù)集的具體方法請參考我這篇文章:https://www.pyimagesearch.com/2018/04/09/how-to-quickly-build-a-deep-learning-image-dataset/;

  • encode_faces.py:該腳本用來進行面部編碼(128維向量);

  • recognize_faces_image.py:基于數(shù)據(jù)集生成的編碼,對單張圖片進行面部識別;

  • recognize_faces_video.py:對來自攝像頭的實時視頻流進行面部識別并輸出視頻文件;

  • recognize_faces_video_file.py:對硬盤上保存的視頻文件進行面部識別,并輸出處理后的視頻文件。本文不再討論該腳本,因為它的基本結(jié)構(gòu)與上面識別視頻流的腳本相同;

  • encodings.pickle:該腳本將encode_faces.py生成的面部識別編碼序列化并保存到硬盤上。

用search_bing_api.py創(chuàng)建好圖像數(shù)據(jù)集之后,就可以運行encode_faces.py來創(chuàng)建嵌入了。

接下來我們將運行識別腳本來進行面部識別。


用OpenCV和深度學(xué)習(xí)對面部進行編碼


圖3:利用深度學(xué)習(xí)和Python進行面部識別。對每一個面部圖像,用face_recognition模塊的方法生成一個128維實數(shù)特征向量。

在識別圖像和視頻中的面部之前,我們首先需要在訓(xùn)練集中識別面部。要注意的是,我們并不是在訓(xùn)練網(wǎng)絡(luò)——該網(wǎng)絡(luò)已經(jīng)在300萬圖像的訓(xùn)練集上訓(xùn)練過了。

當然我們可以從頭開始訓(xùn)練網(wǎng)絡(luò),或者微調(diào)已有模型的權(quán)重,但那就超出了這個項目的范圍。再說,你需要巨量的圖像才能從頭開始訓(xùn)練網(wǎng)絡(luò)。

相反,使用預(yù)先訓(xùn)練好的網(wǎng)絡(luò)來給訓(xùn)練集中的218張面部圖像建立128維嵌入更容易些。

然后,在分類過程中,只需利用簡單的k-NN模型,加上投票,即可確定最終的面部分類,也可以使用其他經(jīng)典機器學(xué)習(xí)模型。

現(xiàn)在打開本文“下載”鏈接中的encode_faces.py文件,看看是如何構(gòu)建面部嵌入的:

1# import the necessary packages
2from imutils import paths
3import face_recognition
4import argparse
5import pickle
6import cv2
7import os

首先需要導(dǎo)入必需的包。這個腳本需要事先安裝imutils、face_recognition和OpenCV。請翻到前面“安裝面部識別庫”一節(jié)確保你已經(jīng)安裝了必須的庫。

首先用argparse處理運行時傳遞的命令行參數(shù):

1# construct the argument parser and parse the arguments
2ap = argparse.ArgumentParser()
3ap.add_argument("-i", "--dataset", required=True,
4    help="path to input directory of faces + images")
5ap.add_argument("-e""--encodings"required=True,
6    help="path to serialized db of facial encodings")
7ap.add_argument("-d""--detection-method"type=strdefault="cnn",
8    help="face detection model to use: either `hog` or `cnn`")
9args = vars(ap.parse_args())

如果你之前沒有用過PyImageSearch,你可以多讀讀我的博客文章,就明白上面這段代碼了。首先利用argparse分析命令行參數(shù),在命令行上執(zhí)行Python程序時,可以在終端中給腳本提供格外的信息。第2-9行不需要做任何改動,它們只是為了分析終端上的輸入。如果不熟悉這些代碼,可以讀讀我這篇文章:https://www.pyimagesearch.com/2018/03/12/python-argparse-command-line-arguments/ 。

下面逐一列出參數(shù):

  • --dataset:數(shù)據(jù)集的路徑(利用search_bing_api.py創(chuàng)建的數(shù)據(jù)集);

  • --encodings:面部編碼將被寫到該參數(shù)所指的文件中;

  • --detection-method:首先需要檢測到圖像中的面部,才能對其進行編碼。兩種面部檢測方法為hog或cnn,因此該參數(shù)只接受這兩個值。

現(xiàn)在參數(shù)已經(jīng)定義好了,我們可以獲得數(shù)據(jù)集文件的路徑了(同時進行兩個初始化):

1# grab the paths to the input images in our dataset
2print("[INFO] quantifying faces...")
3imagePaths = list(paths.list_images(args["dataset"]))
4
5# initialize the list of known encodings and known names
6knownEncodings = []
7knownNames = []

行3用輸入數(shù)據(jù)集的路徑,建立了一個列表imagePaths。

我們還需要在循環(huán)開始之前初始化兩個列表,分別是knownEncodings和knownNames。這兩個列表分別包含面部編碼數(shù)據(jù)和數(shù)據(jù)集中相應(yīng)人物的名字(行6和行7)。

現(xiàn)在可以依次循環(huán)侏羅紀公園中的每個角色了!

 1# loop over the image paths
2for (i, imagePath) in enumerate(imagePaths):
3    # extract the person name from the image path
4    print("[INFO] processing image {}/{}".format(i + 1,
5        len(imagePaths)))
6    name = imagePath.split(os.path.sep)[-2]
7
8    # load the input image and convert it from BGR (OpenCV ordering)
9    # to dlib ordering (RGB)
10    image = cv2.imread(imagePath)
11    rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

這段代碼會循環(huán)218次,處理數(shù)據(jù)集中的218張面部圖像。行2在所有圖像路徑中進行循環(huán)。

接下來,行6要從imagePath中提取人物的名字(因為子目錄名就是人物名)。

然后將imagePath傳遞給cv2.imread(行10),讀取圖像保存到image中。

OpenCV中的顏色通道排列順序為BGR,但dlib要求的順序為RGB。由于face_recognition模塊使用了dlib,因此在繼續(xù)下一步之前,行11轉(zhuǎn)換了顏色空間,并將轉(zhuǎn)換后的新圖像保存在rgb中。

接下來定位面部位置并計算編碼:

 1    # detect the (x, y)-coordinates of the bounding boxes
2    # corresponding to each face in the input image
3    boxes = face_recognition.face_locations(rgb,
4        model=args["detection_method"])
5
6    # compute the facial embedding for the face
7    encodings = face_recognition.face_encodings(rgb, boxes)
8
9    # loop over the encodings
10    for encoding in encodings:
11        # add each encoding + name to our set of known names and
12        # encodings
13        knownEncodings.append(encoding)
14        knownNames.append(name)

這段代碼是最有意思的部分!

每次循環(huán)都會檢測一個面部圖像(或者一張圖像中有多個面部,我們假設(shè)這些面部都屬于同一個人,但如果你使用自己的圖像的話,這個假設(shè)有可能不成立,所以一定要注意)。

比如,假設(shè)rgb里的圖像是Ellie Sattler的臉。

行3和4查找面部位置,返回一個包含了許多方框的列表。我們給face_recognition.face_locations方法傳遞了兩個參數(shù):

  • rgb:RGB圖像;

  • model:cnn或hog(該值包含在命令行參數(shù)字典中,賦給了detection_method鍵)。CNN方法比較準確,但速度較慢;HOG比較快,但不太準確。

然后,在行7,我們要將Ellie Sattler的面部的邊界盒boxes轉(zhuǎn)換成128個數(shù)字。這個步驟就是將面部編碼成向量,可以通過face_recognition.face_encodings方法實現(xiàn)。

接下來秩序?qū)llie Sattler的encoding和name添加到恰當?shù)牧斜碇校╧nownEncodings或knownNames)。

然后對數(shù)據(jù)集中所有218張圖像進行這一步驟。

提取這些編碼encodings的目的就是要在另一個腳本中利用它們進行面部識別?,F(xiàn)在來看看怎么做:

1# dump the facial encodings + names to disk
2print("[INFO] serializing encodings...")
3data = {"encodings": knownEncodings, "names": knownNames}
4f = open(args["encodings"], "wb")
5f.write(pickle.dumps(data))
6f.close()

行3構(gòu)建了一個字典,它包含encodings和names兩個鍵。

行4-6將名字和編碼保存到硬盤中,供以后使用。

怎樣才能在終端上運行encode_faces.py腳本?

要創(chuàng)建面部嵌入,可以從終端執(zhí)行以下命令:

 1$ python encode_faces.py --dataset dataset --encodings encodings.pickle
2[INFO] quantifying faces...
3[INFO] processing image 1/218
4[INFO] processing image 2/218
5[INFO] processing image 3/218
6...
7[INFO] processing image 216/218
8[INFO] processing image 217/218
9[INFO] processing image 218/218
10[INFO] serializing encodings...
11$ ls -lh encodings*
12-rw-r--r--@ 1 adrian  staff   234K May 29 13:03 encodings.pickle

從輸出中課件,它生成了個名為encodings.pickle的文件,該文件包含了數(shù)據(jù)集中每個面部圖像的128維面部嵌入。

在我的Titan X GPU上,處理整個數(shù)據(jù)集花費了一分鐘多一點,但如果只使用CPU,就要做好等待很久的心理準備。

在我的Macbook Pro上(沒有GPU),編碼218張圖像需要21分20秒。

如果你有GPU并且編譯dlib時選擇了支持GPU,那么速度應(yīng)該會快得多。


識別圖像中的面部


圖4:John Hammond的面部識別,使用了Adam Geitgey的深度學(xué)習(xí)Python模塊face_recognition。

現(xiàn)在已經(jīng)給數(shù)據(jù)集中的每張圖像建好了128維面部嵌入,我們可以用OpenCV、Python和深度學(xué)習(xí)進行面部識別了。

打開recognize_faces_image.py,插入以下代碼(或者從本文的”下載“部分下載代碼和相關(guān)的圖像):

 1# import the necessary packages
2import face_recognition
3import argparse
4import pickle
5import cv2
6
7# construct the argument parser and parse the arguments
8ap = argparse.ArgumentParser()
9ap.add_argument("-e", "--encodings", required=True,
10    help="path to serialized db of facial encodings")
11ap.add_argument("-i""--image"required=True,
12    help="path to input image")
13ap.add_argument("-d""--detection-method"type=strdefault="cnn",
14    help="face detection model to use: either `hog` or `cnn`")
15args = vars(ap.parse_args())

這段代碼首先導(dǎo)入了必需的包(行2-5)。face_recognition模塊完成主要工作,OpenCV負責(zé)加載圖像、轉(zhuǎn)換圖像,并顯示處理之后的圖像。

行8-15負責(zé)分析三個命令行參數(shù):

  • --encodings:包含面部編碼的pickle文件的路徑;

  • --image:需要進行面部識別的圖像;

  • --detection-method:這個選項應(yīng)該很熟悉了??梢愿鶕?jù)系統(tǒng)的能力,選擇hog或cnn之一。追求速度的話就選擇hog,追求準確度就選擇cnn。

注意:在樹莓派上必須選擇hog,因為內(nèi)存容量不足以運行CNN方法。

接下來要加載計算好的編碼和面部名稱,然后為輸入圖像構(gòu)建128維面部編碼:

 1# load the known faces and embeddings
2print("[INFO] loading encodings...")
3data = pickle.loads(open(args["encodings"], "rb").read())
4
5# load the input image and convert it from BGR to RGB
6image = cv2.imread(args["image"])
7rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
8
9# detect the (x, y)-coordinates of the bounding boxes corresponding
10# to each face in the input image, then compute the facial embeddings
11# for each face
12print("[INFO] recognizing faces...")
13boxes = face_recognition.face_locations(rgb,
14    model=args["detection_method"])
15encodings = face_recognition.face_encodings(rgb, boxes)
16
17# initialize the list of names for each face detected
18names = []

行3從硬盤加載pickle過的編碼和名字數(shù)據(jù)。稍后在實際的面部識別步驟中會用到這些數(shù)據(jù)。

然后,行6和行7加載輸入圖像image,并轉(zhuǎn)換其顏色通道順序(同encode_faces.py腳本一樣),保存到rgb中。

接下來,行13-15繼續(xù)檢測輸入圖像中的所有面部,并計算它們的128維encodings(這些代碼也應(yīng)該很熟悉了)。

現(xiàn)在應(yīng)該初始化一個列表names,用來保存每個檢測的面部。該列表將在下一步填充。

現(xiàn)在遍歷面部編碼encodings列表:

1# loop over the facial embeddings
2for encoding in encodings:
3    # attempt to match each face in the input image to our known
4    # encodings
5    matches = face_recognition.compare_faces(data["encodings"],
6        encoding)
7    name = "Unknown"

行2開始遍歷根據(jù)輸入圖像計算出的面部編碼。

接下來見證面部識別的奇跡吧!

在行5和行6,我們嘗試利用face_recognition.compare_faces將輸入圖像中的每個面部(encoding)對應(yīng)到已知的編碼數(shù)據(jù)集(保存在data["encodings"]中)上。

該函數(shù)會返回一個True/False值的列表,每個值對應(yīng)于數(shù)據(jù)集中的一張圖像。對于我們的侏羅紀公園的例子,數(shù)據(jù)集中有218張圖像,因此返回的列表將包含218個布爾值。

compare_faces函數(shù)內(nèi)部會計算待判別圖像的嵌入和數(shù)據(jù)集中所有面部的嵌入之間的歐幾里得距離。

如果距離位于容許范圍內(nèi)(容許范圍越小,面部識別系統(tǒng)就越嚴格),則返回True,表明面部吻合。否則,如果距離大于容許范圍,則返回False表示面部不吻合。

本質(zhì)上我們用了個更”炫酷“的k-NN模型進行分類。具體的實現(xiàn)細節(jié)可以參考compare_faces的實現(xiàn)(https://github.com/ageitgey/face_recognition/blob/master/face_recognition/api.py#L213)。

最終,name變量會的值就是人的名字。如果沒有任何”投票“,則保持"Unknown"不變(行7)。

根據(jù)matches列表,可以計算每個名字的”投票“數(shù)目(與每個名字關(guān)聯(lián)的True值的數(shù)目),計票之后選擇最適合的人的名字:

 1    # check to see if we have found a match
2    if True in matches:
3        # find the indexes of all matched faces then initialize a
4        # dictionary to count the total number of times each face
5        # was matched
6        matchedIdxs = [i for (i, b) in enumerate(matches) if b]
7        counts = {}
8
9        # loop over the matched indexes and maintain a count for
10        # each recognized face face
11        for i in matchedIdxs:
12            name = data["names"][i]
13            counts[name] = counts.get(name, 0) + 1
14
15        # determine the recognized face with the largest number of
16        # votes (note: in the event of an unlikely tie Python will
17        # select first entry in the dictionary)
18        name = max(counts, key=counts.get)
19
20    # update the list of names
21    names.append(name)

如果matches中包含任何True的投票(行2),則需要確定True值在matches中的索引位置。這一步在行6中通過建立一個簡單的matchedIdxs列表實現(xiàn)。對于example_01.png來說,它大概是這個樣子:

1(Pdb) matchedIdxs
2[35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 71, 72, 73, 74, 75]

然后初始化一個名為counts的字典,其鍵為角色的名字,值是投票的數(shù)量。

接下來遍歷matchedIdxs,統(tǒng)計每個相關(guān)的名字,并在counts增加相應(yīng)的計數(shù)值。counts字典可能是這個樣子(Ian Malcolm高票的情況):

1(Pdb) counts
2{'ian_malcolm': 40}

回憶一下我們的數(shù)據(jù)集中只有41張圖片,因此40分并且沒有任何其他投票可以認為非常高了。

取出counts中投票最高的名字,本例中為'ian_malcolm'。

循環(huán)的第二次迭代(由于圖像中有兩個人臉)會取出下面的counts:

1(Pdb) counts
2{'alan_grant': 5}

盡管這個投票分值較低,但由于這是字典中唯一的人名,所以很可能我們找到了Alan Grant。

注意:這里使用了Python調(diào)試器PDB來檢查counts字典的值。PDB的用法超出了本文的范圍,你可以在Python的文檔頁面(https://docs.python.org/3/library/pdb.html)找到其用法。

如下面的圖5所示,我們正確識別了Ian Malcolm和Alan Grant,所以這一段代碼工作得還不錯。

我們來繼續(xù)循環(huán)每個人的邊界盒和名字,然后將名字畫在輸出圖像上以供展示之用:

 1# loop over the recognized faces
2for ((top, right, bottom, left), name) in zip(boxes, names):
3    # draw the predicted face name on the image
4    cv2.rectangle(image, (left, top), (right, bottom), (0, 255, 0), 2)
5    y = top - 15 if top - 15 > 15 else top + 15
6    cv2.putText(image, name, (left, y), cv2.FONT_HERSHEY_SIMPLEX,
7        0.75, (0, 255, 0), 2)
8
9# show the output image
10cv2.imshow("Image", image)
11cv2.waitKey(0)

行2開始循環(huán)檢測到的面部邊界盒boxes和預(yù)測的names。我們調(diào)用了zip(boxes, names)以創(chuàng)建一個容易進行循環(huán)的對象,每次迭代將得到一個二元組,從中可以提取邊界盒坐標和名字。

行4利用邊界盒坐標畫一個綠色方框。

我們還利用坐標計算了人名文本的顯示位置(行5),并將人名的文本畫在圖像上(行6和行7)。如果邊界盒位于圖像頂端,則將文本移到邊界盒下方(行5),否則文本就被截掉了。

然后顯示圖像,直到按下任意鍵為止(行10和11)。

怎樣運行面部識別的Python腳本?

在終端中,首先用workon命令保證位于正確的Python虛擬環(huán)境中(如果你用了虛擬環(huán)境的話)。

然后運行該腳本,同時至少提供兩個命令行參數(shù)。如果選擇HoG方式,別忘了傳遞--detection-method hog(否則默認會使用深度學(xué)習(xí)檢測方式)。

趕快試試吧!

打開終端并執(zhí)行腳本,用OpenCV和Python進行面部識別:

1$ python recognize_faces_image.py --encodings encodings.pickle \
2    --image examples/example_01.png
3[INFO] loading encodings...
4[INFO] recognizing faces...

圖5:Python + OpenCV + 深度學(xué)習(xí)方法識別出了Alan Grant和Ian Malcom的面部。

另一個面部識別的例子:

1$ python recognize_faces_image.py --encodings encodings.pickle \
2    --image examples/example_02.png
3[INFO] loading encodings...
4[INFO] recognizing faces...

圖6:用OpenCV和Python進行面部識別。


在視頻中進行面部識別

圖7:用Python、OpenCV和深度學(xué)習(xí)在視頻中進行面部識別。

我們已經(jīng)完成了圖像中的面部識別,現(xiàn)在來試試在視頻中進行(實時)面部識別。

關(guān)于性能的重要提示:CNN面部識別器只能在有GPU的情況下實時運行(CPU也可以運行,但視頻會非??ǎ瑢嶋H的幀速率不到0.5FPS)。如果你只有CPU,應(yīng)當考慮使用HoG方式(或者甚至采用OpenCV的Haar層疊方式,以后會撰文說明),以獲得較好的速度。

下面的腳本從前面的recognize_faces_image.py腳本中借用了許多代碼。因此我將略過之前介紹過的部分,只說明下視頻部分,以便于理解。

下載好代碼之后,打開recognize_faces_video.py:

 1# import the necessary packages
2from imutils.video import VideoStream
3import face_recognition
4import argparse
5import imutils
6import pickle
7import time
8import cv2
9
10# construct the argument parser and parse the arguments
11ap = argparse.ArgumentParser()
12ap.add_argument("-e", "--encodings", required=True,
13    help="path to serialized db of facial encodings")
14ap.add_argument("-o""--output"type=str,
15    help="path to output video")
16ap.add_argument("-y""--display"type=intdefault=1,
17    help="whether or not to display output frame to screen")
18ap.add_argument("-d""--detection-method"type=strdefault="cnn",
19    help="face detection model to use: either `hog` or `cnn`")
20args = vars(ap.parse_args())

行2-8導(dǎo)入包,然后行11-20解析命令行參數(shù)。

這里有四個命令行參數(shù),其中兩個是介紹過的(--encodings和--detection-method)。另外兩個參數(shù)是:

  • --output:視頻輸出路徑;

  • --display:指示是否將視頻幀輸出到屏幕的標志。1表示顯示到屏幕,0表示不顯示。

然后加載編碼并啟動VideoStream:

 1# load the known faces and embeddings
2print("[INFO] loading encodings...")
3data = pickle.loads(open(args["encodings"], "rb").read())
4
5# initialize the video stream and pointer to output video file, then
6# allow the camera sensor to warm up
7print("[INFO] starting video stream...")
8vs = VideoStream(src=0).start()
9writer = None
10time.sleep(2.0)

我們利用imutils中的VideoStream類來訪問攝像頭。行8啟動視頻流。如果系統(tǒng)中有多個攝像頭(如內(nèi)置攝像頭和外置USB攝像頭),可以將src=0改成src=1等。

稍后會將處理過的視頻寫到硬盤中,所以這里將writer初始化成None(行9)。sleep兩秒讓攝像頭預(yù)熱。

接下來啟動一個while循環(huán),開始抓取并處理視頻幀:

 1# loop over frames from the video file stream
2while True:
3    # grab the frame from the threaded video stream
4    frame = vs.read()
5
6    # convert the input frame from BGR to RGB then resize it to have
7    # a width of 750px (to speedup processing)
8    rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
9    rgb = imutils.resize(frame, width=750)
10    r = frame.shape[1] / float(rgb.shape[1])
11
12    # detect the (x, y)-coordinates of the bounding boxes
13    # corresponding to each face in the input frame, then compute
14    # the facial embeddings for each face
15    boxes = face_recognition.face_locations(rgb,
16        model=args["detection_method"])
17    encodings = face_recognition.face_encodings(rgb, boxes)
18    names = []

循環(huán)從行2開始,第一步就是從視頻流中抓取一個frame(行4)。

上述代碼中剩下的行8-18基本上與前一個腳本相同,只不過這里處理的是視頻幀,而不是靜態(tài)圖像?;旧暇褪亲x取frame,預(yù)處理,檢測到面部邊界盒boxes,然后給每個邊界盒計算encodings。

接下來遍歷每個找到的面部的encodings:

 1    # loop over the facial embeddings
2    for encoding in encodings:
3        # attempt to match each face in the input image to our known
4        # encodings
5        matches = face_recognition.compare_faces(data["encodings"],
6            encoding)
7        name = "Unknown"
8
9        # check to see if we have found a match
10        if True in matches:
11            # find the indexes of all matched faces then initialize a
12            # dictionary to count the total number of times each face
13            # was matched
14            matchedIdxs = [i for (i, b) in enumerate(matches) if b]
15            counts = {}
16
17            # loop over the matched indexes and maintain a count for
18            # each recognized face face
19            for i in matchedIdxs:
20                name = data["names"][i]
21                counts[name] = counts.get(name, 0) + 1
22
23            # determine the recognized face with the largest number
24            # of votes (note: in the event of an unlikely tie Python
25            # will select first entry in the dictionary)
26            name = max(counts, key=counts.get)
27
28        # update the list of names
29        names.append(name)

在這段代碼中依次循環(huán)每個encodings,并嘗試匹配到已知的面部數(shù)據(jù)上。如果找到匹配,則計算數(shù)據(jù)集中每個名字獲得的票數(shù)。然后取出得票最高的名字,就是該面部對應(yīng)的名字。這些代碼與前面的代碼完全相同。

下一段代碼循環(huán)找到的面部并在周圍畫出邊界盒,并顯示人的名字:

 1    # loop over the recognized faces
2    for ((top, right, bottom, left), name) in zip(boxes, names):
3        # rescale the face coordinates
4        top = int(top * r)
5        right = int(right * r)
6        bottom = int(bottom * r)
7        left = int(left * r)
8
9        # draw the predicted face name on the image
10        cv2.rectangle(frame, (left, top), (right, bottom),
11            (02550), 2)
12        y = top - 15 if top - 15 > 15 else top + 15
13        cv2.putText(frame, name, (left, y), cv2.FONT_HERSHEY_SIMPLEX,
14            0.75, (02550), 2)

這些代碼也完全相同,所以我們只關(guān)注與食品有關(guān)的代碼。

我們還可以將視頻幀寫到硬盤中,因此來看看是怎樣使用OpenCV將視頻寫到硬盤中的(https://www.pyimagesearch.com/2016/02/22/writing-to-video-with-opencv/):

 1    # if the video writer is None *AND* we are supposed to write
2    # the output video to disk initialize the writer
3    if writer is None and args["output"is not None:
4        fourcc = cv2.VideoWriter_fourcc(*"MJPG")
5        writer = cv2.VideoWriter(args["output"], fourcc, 20,
6            (frame.shape[1], frame.shape[0]), True)
7
8    # if the writer is not None, write the frame with recognized
9    # faces t odisk
10    if writer is not None:
11        writer.write(frame)

如果命令行參數(shù)提供了輸出文件路徑(可選),而我們還沒有初始化視頻的writer(行3),就要先初始化之。

行4初始化了VideoWriter_fourcc。FourCC是一種四字符編碼,在這里就是MJPG 四字符編碼。

接下來將對象、輸出路徑、每秒幀數(shù)的目標值和幀尺寸傳遞給VideoWriter(行5和6)。

最后,如果writer存在,就繼續(xù)將幀寫到磁盤中。

下面是是否將面部識別視頻幀輸出到屏幕的處理:

1    # check to see if we are supposed to display the output frame to
2    # the screen
3    if args["display"] > 0:
4        cv2.imshow("Frame", frame)
5        key = cv2.waitKey(1) & 0xFF
6
7        # if the `q` key was pressed, break from the loop
8        if key == ord("q"):
9            break

如果設(shè)置了display命令行參數(shù),就顯示視頻幀(行4)并檢查退出鍵("q")是否被按下(行5-8),如果被按下,則break掉循環(huán)(行9)。

最后是一些清理工作:

1# do a bit of cleanup
2cv2.destroyAllWindows()
3vs.stop()
4
5# check to see if the video writer point needs to be released
6if writer is not None:
7    writer.release()

行2-7清理并釋放屏幕、視頻流和視頻writer。

準備好運行真正的腳本了嗎?

為了演示OpenCV和Python的實時面部識別,打開終端然后執(zhí)行下面的命令:

1$ python recognize_faces_video.py --encodings encodings.pickle \
2    --output output/webcam_face_recognition_output.avi --display 1
3[INFO] loading encodings...
4[INFO] starting video stream...

下面是我錄制的演示視頻,用來演示面部識別系統(tǒng):


視頻文件中的面部識別

之前在“面部識別項目結(jié)構(gòu)”一節(jié)中說過,下載的代碼中還有個名為recognize_faces_video_file.py的腳本。

這個腳本實際上和剛才識別攝像頭的腳本相同,只不過它接收視頻文件作為輸入,然后生成輸出視頻文件。

我對原版侏羅紀公園電影中經(jīng)典的“午飯場景”做了面部識別,在該場景中,演員們圍在桌子旁邊討論他們對于公園的想法:

1$ python recognize_faces_video_file.py --encodings encodings.pickle \
2    --input videos/lunch_scene.mp4 --output output/lunch_scene_output.avi \
3    --display 0

下面是結(jié)果:


注意:別忘了我們的模型是根據(jù)原版電影中的四個角色進行訓(xùn)練的:Alan Grant、Ellie Sattler、Ian Malcolm和John Hammond。模型并沒有針對Donald Gennaro(律師)進行訓(xùn)練,所以他的面部被標記為“Unknown”。這個行為是特意的(不是意外),以演示我們的視頻識別系統(tǒng)在識別訓(xùn)練過的面部的同時,會把不認識的面部標記為“Unknown”。

下面的視頻中我從《侏羅紀公園》和《侏羅紀世界》的預(yù)告片中截取的剪輯:


可見,面部識別和OpenCV代碼的效果很不錯!


面部識別代碼能運行在樹莓派上嗎?


從某種意義上,可以。不過有一些限制:

  • 樹莓派內(nèi)存太小,沒辦法運行更準確的基于CNN的面部檢測器;

  • 因此只能用HOG方式;

  • 即使如此,HOG方式在樹莓派上也太慢,沒辦法用于實時面部檢測;

  • 所以只能用OpenCV的Haar層疊方式。

即使這樣能運行起來,實際的速率也只有1~2FPS,而且就算是這種速率也需要許多技巧。


總結(jié)


在這篇指南中,我們學(xué)習(xí)了如何利用OpenCV、Python和深度學(xué)習(xí)來進行面部識別。此外,我們還利用了Davis King的dlib庫和Adam Geitgey的face_recognition模塊,后者對dlib的深度度量學(xué)習(xí)進行了封裝,使得面部識別更容易完成。

我們發(fā)現(xiàn),我們的面部識別實現(xiàn)同時具有以下兩個特點:準確,并且能在GPU上實時運行。

最后,希望你喜歡今天的面部識別的文章!


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

交流群


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


瀏覽 66
點贊
評論
收藏
分享

手機掃一掃分享

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

手機掃一掃分享

分享
舉報

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

国产秋霞理论久久久电影-婷婷色九月综合激情丁香-欧美在线观看乱妇视频-精品国avA久久久久久久-国产乱码精品一区二区三区亚洲人-欧美熟妇一区二区三区蜜桃视频 偷窥丶亚洲丶熟女| 五月婷婷综合在线| 黄色视频a| 熟女熟妇人妻一区二区三区| 一区二区免费在线观看| 人人人人摸| 亚洲精品乱码久久久久久蜜桃欧美| 白虎高清无码大尺度免费在线观看| 婷婷色色五月天| a片网| 伊人视频在线观看| 四季AV一区二区夜夜嗨| 亚洲成人Av| 青在线视频| 骚逼逼影院| 91亚洲国产成人久久精品网站 | 九色蝌蚪9l视频蝌蚪9l视频成人熟妇| 中文字幕AV免费观看| 日韩在线视频不卡| 91成人篇| AA黄色电影| 久草黄色电影在线观看| 另类老妇奶性生BBwBB| 亚洲v| 操逼免费| 婷婷天堂| 国产无遮挡又黄又爽又色学生软件 | 亚洲综合中文字幕在线| 无码二区三区| 亚洲欧美日韩动漫| 可以免费看的黄色视频| 色黄视频在线观看| 蜜桃视频日韩| 在线观看免费一区| 操操操无码| 色黄视频在线观看| 五月停亭六月,六月停亭的英语 | 亚洲国产高清视频| 特级444WWW大胆高清| 熟女人妻人妻の视频| 激情AV在线| 奇米av| 亚洲无码在线播放| 午夜在线视频| 特级毛片| 日韩视频一区二区| 中文亚洲字幕| 日韩操逼网| 亚洲精品99| 日韩高清在线| 国产无码一区| 一本一道久久综合狠狠躁牛牛影视 | A免费观看| 中文字幕特黄A片| 日本少妇性爱视频| 操逼地址| 日韩欧美大片在线观看| 日本A在线播放| 男女91视频| 69综合| 青青三级片| 免费无码视频| 操你啦无码日韩| 久久丁香五月婷婷五月天激情视频| 99精品视频在线观看| 欧美三级在线播放| 国产熟妇码AV| 人妻少妇av中文字幕乱码牛牛 | 最近中文字幕免费mv第一季歌词強上 | 在线草| 深爱激情综合| 久久黄色毛片| 人人爽亚洲AV人人爽AV人人片| 蝌蚪九色啦403| 瘦精品无码一区二区三区四区五区六区七区八区 | 亚洲男女啪啪视频| 成人污污视频| 超碰2023| 精品国产A片| 日本黄色电影网址| 97超碰在线免费观看| 麻豆精品一区| 久久久人妻熟妇精品无码蜜桃| 秋霞福利网| 波多野结衣av在线播放| jizz在线免费观看| 日韩免费av| 高清无码在线免费观看| 中文字幕你懂的在线三级| A级片黄色片| 黄色激情av| 中文字幕一二三四| 操B久久| 黄色视频毛片| 成人亚洲A片V一区二区三区蜜月| HEZ-502搭讪绝品人妻系列 | 狠狠插狠狠操| 69网站| 欧美性爱91| 老熟女痒到不行-ThePorn| 亚洲成人一区二区三区| 午夜无码鲁丝片午夜精品| 蜜桃导航-精品导航| 俺也去色色| av影音先锋在线| 成人伊人综合网| 六月丁香婷| 午夜激情四射| 黄色小视频在线观看| A在线观看| 中文字幕在线观看辣文| 国产精品国产三级片| 97精品人妻一区二区三区香蕉农| 欧洲性爱视频在线观看| 国产免费无码视频| 欧美日韩一区二区在线观看| 成人一级视频| 国产福利在线视频| 婷婷色情网| 综合自拍偷拍| 一道AV| 黄色电影a片| 欧美亚洲在线| 日日干天天干| 日韩视频播放在线综合| 日韩AV免费网站| AAA精品| 欧美黄色性爱| 99xxxxx| 国产理论片| 日本在线免费观看| 日韩三级片AV| 最新亚洲中文字幕| 日本在线一区二区| 天天操夜| 51妺妺嘿嘿午夜成人A片| 精品无码一区二区| 国产一级A片免费看| 黄色免费视频| 日本人妻在线视频| 日韩高清毛片| 欧美日韩在线免费观看| 亚洲视频综合网| 在线观看三级| 一道本无码在线观看| 国产精彩视频| 亚洲成人性爱| 夫妻无码| 俄罗斯老熟妇与子伦| 欧美三级网站在线观看| 国产一级a毛一级a做免费高清视频| www.婷婷五月天| 吴梦梦《女教师时间暂停》| 国产噜噜噜噜噜久久久久久久久 | AV小说在线观看| 九九成人电影| 中文字幕乱码亚洲中文在线| 国产一区二区免费在线观看| 天天色粽合合合合合合合| 欧美婷婷综合| 亚州无码视频| 黑吊操| 午夜成人无码视频| 上海熟妇搡BBBB搡BBBB| 一本道在线无码| 亚洲色图偷拍| 国产午夜影视| 色逼逼网| 狠狠操狠狠操狠狠操| 日韩成人影片| 欧美美女日逼视频| 亚洲无码三级视频| 黄片免费播放| 久久精品一区二区三区四区| 香蕉网站操逼片| 手机av网站| 亚洲成色A片77777在线小说| 白浆av| 偷拍视频网站北条麻妃| 欧美日韩美女| 伦理被部长侵犯HD中字| 尻屄视频在线观看| 国产精品怡红院有限公司| 日韩一区二区三区四区久久久精品有吗| 俄罗斯白嫩BBwBBwBBw91| 99久久国| 亚洲中文字幕在线播放| 国产一级操逼片| 欧美三级网站在线观看| 人人干人人摸人人操| 国产色天使| 欧美日韩综合网| 超碰免费人妻| 欧美一卡二卡三卡| 四季AV一区二区凹凸懂色桃花 | 国产婷婷久久| 影音先锋av色| 日韩免费精品视频| 黄色小视频在线免费观看| 欧美激情网站| 亚洲午夜激情| 国产办公室丝袜人妖| 九九热精品在线视频| 成人免看一级a一片| 欧美成在线| 免费在线成人网| 久久亚洲热| 日本成人高清视频| 国产理论| 日本亚洲欧洲免费| 免费Av在线| 亚洲日韩在线观看视频| 女孩自慰在线观看| 新BBWBBWBBWBBW| 中文字幕不卡在线| 亚洲视频日韩在线观看| 久久视频在线| 靠逼免费视频| 青草伊人av| 91理论片| 亚洲无码影片| 成人播放视频| 亚洲AV成人片色在线观看高潮| 乖我硬了让老子cao你小视频| 大雞巴疯狂浓精合集| www.大香蕉伊人| A片黄色电影网站| 一道本在线视频| 日本午夜影院| 天天肏天天肏| 97色综合| 欧美午夜电影| 国产精品93333333| 搡BBBB推BBBB推BBBB| 欧美三级在线| 亚洲一| 99久久精| 国产操女人| 成人精品免费无码毛片| 久久午夜视频| 国产精品无码久久久久成人app | 欧美一级成人片| 露脸老熟女91集合| 亚洲欧美性爱| 在线免费观看黄色网址| 欧美图片小说| 欧美午夜精品一区二区蜜桃| aaa三级片| 日韩精品五区| 做爱视频91| 日韩精品在线观看免费| 99爱视频| 欧美成人精品激情在线观看| 欧美特黄AAAAAAAAA片| 色香蕉视频在线观看| 国产精品91久久久| 猛男大粗猛爽H男人味| 日本丰满老熟妇乱子伦| 91日综合欧美| 欧美色图另类图片| 亚洲成人性爱网| 欧美成人性爱网址| 91伊人在线| 国产青青| 爱逼爱操| 91男女| 波多野结衣网址| 高潮91PORN蝌蚪九色| 搡女人视频国产一级午夜片| 亚洲无码视频一区二区| 欧美A片视频| 西西4444www大胆无吗| 久久精品国产亚洲AV成人婷婷| 激情成人五月天| 亚洲一级黄| 中文字幕精品综合| 91人妻人人澡人人爽精品| 久草综合在线| 大地资源第三页在线观看免费播放最新 | 国产偷拍网站| 日韩精品一区二区三区四在线播放| 久热国产在线| 97久久久| 午夜视频免费在线观看| 国产毛片在线视频| 欧美三级视频| 成人免费A片在线观看直播96| 欧美一级免费| 精品无码一区二区三区四区五区| 丰满岳乱妇一区二区三区全文阅读| 欧美操逼图| 五月天婷婷无码| 亚洲精品成人无码毛片| 久久黄色视频免费看| 亚洲中文字幕免费在线观看| 91成人在线观看学生和老师| 亚洲无码中文视频| 日本A片视频| 超碰97观看| 久久精品内射| 综合导航无码| 欧美成人高清无码| 亚洲午夜剧场| 色婷在线| 精品自拍视频| AV777777| 免费操逼网| 国产欧美一区二区三区四区 | 年轻女教师高潮2| 色婷婷色五月| 久久久久久亚洲精品| a片免费在线| 123操逼| 国产欧美综合三级伦| 黄片免费在线播放| 国产老熟女高潮毛片A片仙踪林 | 日本久久综合网| 久久99免费视频| 国产波霸爆乳一区二区| 亚洲专区在线| 国产免费无码一区二区| 日韩欧美高清无码| 成人AAA片| 在线观看黄片网站| 特级艺体西西444WWw| 俺去操| 日韩欧美黄色电影| 日本一区二区三区免费视频| 豆花成人网站在线看| 日韩久久电影| 欧美在线黄色| 国产精品毛片VA一区二区三区| 激情五月天色| 1024手机在线视频| 91视频网站免费观看| 超碰人人射| 日韩无码影院| 久久久成人电影| 亚洲群交视频| 欧洲精品视频在线观看| 波多野结衣无码视频| 国产97在线视频| 国产福利小视频| 69欧美视频| 操逼电影网| 这里视频很精彩免费观看电视剧最新 | 在线免费观看黄色网址| 3D动漫啪啪精品一区二| 免费视频99| 91久久婷婷国产麻豆精品电影.co| 91AV电影网| H版视频| 国产三级三级三级| 中文字幕高清无码在线播放| 亚洲无码专区在线观看| 四川性BBB搡BBB爽爽爽小说| www.插插插| 国产精品久久久大香蕉| 精品人妻一区二区三区鲁大师| 成年人免费视频在线观看| 底流量AV电影在线| 最近中文字幕免费mv第一季歌词大全 | 在线日韩| 日本激情网| 国产成人在线视频免费| 五月天黄色电影| 波多野结衣一级婬片A片免费下载 囯产精品久久久久久久久免费无码 | 91视频人妻| www.亚洲视频| 有码在线播放| 国产精品免费观看视频| 久操久操久操| 国产一区免费| 亚洲成人777| 无套影院| 人人爱,人人操| 日韩精品一二| 99在线免费观看| 99re超碰| 色欧美亚洲| 夜夜嗨AV一区二区三区| 欧美日韩北条麻妃视频在线观看| 东京热一区二区| 日韩成人黄片| 成人性视频Aⅴ| 人人妻人人操人人| 日韩三级片在线播放| 最新中文字幕在线观看| 亚洲AV网址| 第四色色综合| 一区二区三区四区五区在线| 国产精品久久久久久精| 在线免费小黄片| 爱爱黄色视频| 亚洲精品在线视频观看| 中文字幕片av| 国产日韩在线观看视频| a免费视频在线观看| 欧美在线中文字幕| 91AV在线电影| 亚洲国产成人精品激情在线| 黄色av免费在线观看| 中文字幕五码| 中文字幕首页| 色婷婷色99国产综合精品| 丁香婷婷五月基地| 欧美成人A片在线观看| 浮力影院欧美| 色老久久| 日韩视频一区| 亚洲三级黄色| 欧美影院亚洲| 女人操逼视频| 成人免看一级a一片A片| 人人妻日日摸狠狠躁视频| 亚洲无码二区| 精品久久成人| 人人爱人人操人人干| 三级视频网站| 男人的天堂视频网站| 国产精品秘国产精品88| 免费黄色小视频| www.777av| 国产小视频在线免费观看| 欧美视频操逼| 久草青青草| 永久在线| 日本少妇黄色视频| 99视频热| 黄色片a片| 人人妻人人做| 91成人亚洲| 黄色电影a片| 中文字幕无码Av在线| 国产xxxxx| 粉嫩小泬BBBBBB免费| A片黄色视频| 操极品美女| 欧美精品一二三| 久久偷看各类wc女厕嘘嘘偷窃| 五月亚洲六月婷婷| 九九热精品视频在线播放| 东方av在| 午夜精品在线观看| 97综合| 依人大香蕉| 欧美午夜性爱视频| 久久成人三级| 操B视频在线观看| 少妇无码在线观看| 亚洲美女视频网| 欧美中文字幕在线| 超碰最新在线| 日韩欧美国产综合| 国产高清在线免费观看AV片| 久久久婷| 韩国精品在线| 性爱免费视频网站| 国产91综合一区在线观看| 蜜桃久久99精品久久久酒店| 国产做受91一片二片老头| 先锋成人电影| 欧美三级长视频| 黄频在线观看| 亚洲无码精品一区| AAA久久久| 日本处女性高潮喷水视频| 伊人久久电影| 欧美日韩人妻| 俺去也av| 国产欧美精品成人在线观看| 人人操人人操人人操| 2019人人操| 亚洲激情国产| 97国产免费| 99久久99久久兔费精桃| 亚洲国产A片| 国产十八岁在线观看免费| 可以免费看AV的网站| 国产视频精品一区二区三区 | 欧美一级特黄A片免费观看| 黑人操逼| 国产精品热| 亚洲插菊花综合网| 人人av在线| 成人视频网站在线观看| 91精品大屁股白浆自慰久久久| 麻豆传媒在线| 特猛特黄AAAAAA片| 免费观看无码| 91人妻人人澡人人爽人人精品乱| 亚洲欧洲天堂| 日产久久久久久| 91成人影片| 国产无码中文字幕| 操逼毛片视频| 夜夜夜操操操| 久久久精品| 3D动漫啪啪精品一区二区中文字幕 | 欧美性爱精品一区| 免费毛片网址| 自拍偷拍15p| 国产美女在线观看| 一级黄色视频日逼片| www.911国产| 日韩欧美精品18| 操逼123首页| 亚洲AV无码一区二区三区少妇| 日韩欧美高清视频| 亚欧洲精品在线视频免费观看| 亚洲天堂网在线观看视频| 99久久精彩视频| 亚洲无码二区| 日本A∨| 波多野结衣一区二区三区在线观看| 99精品视频在线免费观看| 国产丝袜AV| 无码免费播放| 91视频久久久| 精品无码视频在线观看| 91豆花在线| 99精品视频北条麻妃国产版| 肏屄网站| 成人av免费在线观看| 日韩爱爱网站| 2018中文字幕第一页| 五月花在线视频| 在线播放中文字幕| 日韩在线综合| 亚洲国产成人91PORN| 久久肏逼| 国产女人水真多18毛片18精品 | 中文字幕日本无码| 全国男人的天堂网站| 蜜桃网一区二区| 国产午夜激情| 国产传媒视频| 无码影音| 18禁污网站| 亚洲三级黄片| 亚洲无吗在线播放| 国产视频一区二区三区四区| 婷婷中文字幕| 少妇bbw搡bbbb搡bbbb| 操逼激情网| 我要操逼网| 欧洲精品在线视频| 国产清纯可爱美女自卫裸贷偷情| 五月天堂网| A毛片| 99Re66精品免费视频| 韩国成人精品三级| 欧美精品久| 在线A∨视频| 波多野结衣一区二区| 国产欧美一区二区三区在线看蜜臀| 亚洲日韩欧美视频| 精品成人久久| 国产三级精品三级在线观看| 亚洲无码免费在线视频| 成人二区三区| av在线资源| 91无码在线观看| 日本精品在线| 亚洲无码人妻| 日韩高清无码片| 大香蕉综合网站| 操老骚逼视频| 色臀av| 最新AV在线播放| 黄色成人在线观看| 不卡二区| 中文字幕在线观| 精品国产欧美一区二区三区成人| 男人的天堂免费视频| 国产成人无码精品一区秘二区 | 500部大龄熟乱4K视频| 人善交精品一区二区三区| 站街大龄熟女x| 99久久99久久精品免费看小说。| 国产在线色| 国产又爽又黄网站免费观看| 2018天天操天天干| 性欧美V| 久久肏屄视频| 黄色视频在线观看18| 黄片一区二区| 第一福利视频导航| 翔田千里一区二区三区| 午夜天堂网| 免费成人视频在线观看| 天天干精品| 亚洲久久色| 久久伊人中文字幕| 91福利网| 水蜜桃视频网站| 91豆花视频| 嫩BBB搡BBB槡BBB小号| 台湾成人综合网| 激情精品| 又黄又爽的网站| 曰曰摸日日碰| 婷婷婷色| 97成人在线视频| 做a视频| 欧美一级片网站| 午夜爽爽视频| 激情五月色五月| 中文无码人妻少妇| 无码三级在线免费观看| 成年人在线视频| 影音先锋久久| 三级片在线观看视频| 男女www| 亚洲三级片在线视频| 日本A片免费看| 一本色道久久综合狠狠躁的推荐 | 91拍真实国产伦偷精品| 亚洲视频免费看| 中文字幕有码在线视频| 成人三级视频在线观看| 欧美一区不卡| 无码三| 波多野结衣av中文字幕| 九九福利| 五月天高清无码| 国产精品高潮呻吟久久| 日韩成人高清| 久久公开视频| 日韩成人三级片| 操逼爽| 精品久久免费视频| 国产丰满| 一区二区三区无码区| 丰滿人妻-区二区三区| 免费日韩黄色电影| 色婷在线| 黑人亚洲娇小videos∞| 国产在线一区二区三区四区| 豆花视频在线免费观看| 人人妻人人躁人人DVD| 欧美日韩肏屄视频| 丁香婷婷社区| 国产一区二区在线播放| 高清无码视频免费看| 青青草视频91| 色中色AV| 免费无码婬片aaaa| 亚洲有码在线视频| 亚洲AⅤ无码一区二区波多野按摩| 啪啪免费网| 高清无码免费观看视频| 国产亚洲精品成人a| 欧美操逼在线观看| 日韩理论在线| 中文字幕在线一区二区a| 成人无码观看| 蝌蚪窝久久| 免费无码又爽又黄又刺激网站| 69式荫蒂被添全过程| AV青青草| 无码AV免费观看| 粉嫩av懂色av蜜臀av熟妇| 国产丝袜无码| 91导航| 婷婷六月综合| 亚洲无码制服| 一级特黄大片录像i| 天干天干天夜夜爽| 神马午夜51| 日韩av在线免费观看| 日逼视频网站| 淫荡五月天视频导航| 一级A片视频免费看| 丁香五香天堂| 亚洲三级精品| 91人人妻人人做人人爽| 日韩黄色激情| 免费观看亚洲视频| BBw日本熟妇BBwHD| 天堂网在线播放| 日韩无码人妻久久一区二区三区 | www.yw尤物| AV一区二区三区四区| 久草视频在线资源| 久草国产在线视频| 成人黄网免费观看视频| 国产黄色片在线观看| 青青精品| 欧美丰满美乳XXⅩ高潮www| 高清一区二区| 国产成人主播| 无码一区二区区| 超碰免费99| 久久久久久黄色| 91av久久| 操逼网首页| 青青草原在线| 天天干天天操天天干| 亚洲高清免费视频| 最新中文字幕| 精品黄色毛片| 精品视频中文字幕| 操久在线| 国产精品码ls字幕影视| 婷婷五月色综合| 四虎在线视频| 日本少妇网站| 亚洲天堂免费观看| 亚洲国产成人精品女人| 欧美成人精品无码网站| a在线观看免费| 青青草国产在线视频| 日本免费在线黄色视频| 日韩AV中文字幕在线播放| 中文字幕在线中文| 丁香色五月婷婷| 波多野在线视频| 成人欧美在线| 一区二区三区精品| 成人国产片女人爽到高潮| 亚洲欧洲久久| 少妇搡BBBB搡BBB搡小说| 东北操逼视频| 日韩欧美精品18| 欧美成人黄色| 黃色一级A片一級片| 嫩草在线观看| 日韩精品你懂的| 九月婷婷综合| 黄色av免费网站| www.五月丁香| 四lll少妇BBBB槡BBBB| 亚洲高清无码一区| 日本精品人妻无码77777| 长泽梓黑人初解禁BDD07| 高清无码中文字| 国产色婷婷精品综合在线播放| 伊香蕉大综综综合| 神马午夜秋霞不卡| 亚洲一区二区三区在线| 亚洲中文字幕AV| 性爱免费专区| 成人精品二区| 丰满熟妇人妻无码视频| 天天免费视频| 人人天天夜夜| 口爆在线| 欧美性爱一级视频| 久福利| 182在线视频| 激情丁香六月| 91资源在线| 操逼片| 电家庭影院午夜| 中文字幕在线永久| 婷婷综合素质二区| 刘玥91精一区二区三区| 青青草手机在线视频| 婷婷色色五月天图片| 欧美三区四区| 99久久久无码国产精品性波多| 欧美五月激情| 2021无码| 欧美三级视频| 天堂综合网久久| 四川少BBB搡BBB爽爽爽| 懂色av懂色av粉嫩av无码| 亚洲无码专区在线| 久久三级视频| 久草中文在线视频| 亚洲综合视频网| 北条麻妃人妻中文字幕91影视| 国产AV一区二区三区精品| 日本黄色电影网站| 夜夜操操| 欧美亚洲国产视频| 国内自拍av| 全国最大成人网站| 精品一区二区三区毛片| 久久久国产AV| 高清无码免费看| 嫩草AV| 五月天综合网| 成人网站视频| 日韩人妻无码电影| 成人a片在线观看| 亚洲在线免费视频| 国产一级性爱视频| 日韩无码AV中文字幕| 神马午夜秋霞不卡| 国产电影一区二区三区| 大屌探花| 国产女人与禽zOz0性| 免费做a爰片77777| 人妻av在线| 成人视频三级| 少妇性受XXXX黑人XYX性爽| 河南熟妇搡BBBB搡BBBB| 中文字幕熟女人妻| 久操视频在线| 高潮91PORN蝌蚪九色| 不卡视频一区二区三区| 国产精品色色| 国产欧美一区二区三区视频| 2024av在线| 欧美午夜伦理| 日韩欧美中文在线| av玖玖| 蜜桃人妻无码AV天堂二区| 亚州高清无码视频| 东方av在线观看| 青草午夜| 人妻啪啪| 午夜色婷婷| 久久国产乱子伦精品免费女,网站| 成人性生交大片免费看小芳| 粉嫩小泬BBBBBB免费看| 99热香蕉| 国产激情欧洲在线观看一区二区三区 | 麻豆视频一区二区| 99成人| 五月天狠狠| 日韩在线视频中文字幕码无| 日本一级黃色大片看免费| 欧美日韩A片欧美日| www.99热视频| 国产情侣在线视频| 免费黄网站| 美女十八禁| 欧美精品在线观看视频| 日韩欧美性爱| 麻豆成人无码| 台湾久久| 九九99精品| 日本久久人体视频| 欧美做受高潮白| 欧美日韩在线视频播放| 91亚洲视频| 亚洲午夜久久久| 性生活黄色视频| 四川少妇搡bbbbb搡多人| 欧美成人五月天| 亚洲秘av无码一区二区| 国产怡红院| 成人性在线| 亚洲一级性爱| 欧美日韩精品久久久免费观看| 青草午夜| 久久精品久| 无码高清一区| 欧美专区一区| 大香蕉五月丁香| 天天操夜夜操狠狠操| AAA片网站| 91人妻人人澡人人爽人人玩| 视色网| 夜夜AV| 亚洲天堂影音先锋| 亚洲欧洲中文字幕| 欧美肏逼网| 久久熟女| 久久99综合| 操比免费视频| 88AV在线视频| 91玖玖| 西西444WWW无码视频软件功能介绍| 亚洲成a| 成人免费无遮挡无码黄漫视频| 午夜免费福利视频| 麻豆精品一区| www.久草| A级视频免费观看| www.91国产| 久草蜜臀| 操B电影| 超碰91在线观看| 国产99999| 色色A| 69av在线观看| 日韩国产传媒| 在线免费观看黄色小视频| 欧美国产成人在线| 中文字幕日韩亚洲| 亚洲成人三级片| 国产又粗又猛又黄又爽无遮挡| 欧美精品日韩| 无码激情| 日韩欧美亚洲一区二区三区| 亚洲三级片视频| 四季AV一区二区凹凸懂色桃花| 婷婷五月开心五月| 先锋影音在线资源| 亚洲综合网在线观看| 91网站免费在线观看| 操逼逼一区二区三区| 日韩欧美中文字幕公布| 日本亚洲欧美| 国产精品九九视频| 国产黄色免费视频|