高清视频在线观看免费播放器-伊人日本-色九月综合-18禁止看的免费污网站-免费观看性行为视频的网站-天天碰天天操-久久精品国产欧美日韩99热-中文字幕在线视频不卡-国产偷人妻精品一区二区在线-国内精品久-伊人影院在线看-密臀av一区-久久综合五月丁香久久激情-福利一区福利二区-gg国产精品国内免费观看-国产精品 高清 尿 小便 嘘嘘

當(dāng)前位置: 首頁 >縱橫 > 正文

JavaCV人臉識(shí)別三部曲之三:識(shí)別和預(yù)覽

2023-07-01 08:32:04 來源:博客園
歡迎訪問我的GitHub

這里分類和匯總了欣宸的全部原創(chuàng)(含配套源碼):https://github.com/zq2599/blog_demos

《JavaCV人臉識(shí)別三部曲》鏈接《視頻中的人臉保存為圖片》《訓(xùn)練》《識(shí)別和預(yù)覽》本篇概覽

作為《JavaCV人臉識(shí)別三部曲》的終篇,今天咱們要開發(fā)一個(gè)實(shí)用的功能:有人出現(xiàn)在攝像頭中時(shí),應(yīng)用程序在預(yù)覽窗口標(biāo)注出此人的身份,效果如下圖所示:

簡單來說,本篇要做的事情如下:


(資料圖片僅供參考)

理解重點(diǎn)概念:confidence理解重點(diǎn)概念:threshold編碼驗(yàn)證今天編寫的代碼,主要功能如下圖所示:理解重點(diǎn)概念:confidence

confidence和threshold是OpenCV的人臉識(shí)別中非常重要的兩個(gè)概念,咱們先把這兩個(gè)概念搞清楚,再去編碼就非常容易了

假設(shè),咱們用下面六張照片訓(xùn)練出包含兩個(gè)類別的模型:

用一張新的照片去訓(xùn)練好的模型中做識(shí)別,如下圖,識(shí)別結(jié)果有兩部分內(nèi)容:label和confidence

先說lable,這個(gè)好理解,與訓(xùn)練時(shí)的lable一致(回顧上一篇的代碼,lable如下圖紅框所示),前面圖中l(wèi)able等于2,表示被判定為郭富城:

按照上面的說法,lable等于2就能確定照片中的人像是郭富城嗎?

當(dāng)然不能!!!此時(shí)confidence字段就非常重要了,先看JavaCV源碼中對(duì)confidence的解釋,如下圖紅框所示,我的理解是:與lable值相關(guān)聯(lián)的置信度,或者說這張臉是郭富城的可能性

如果理解為可能性,那么問題來了,這是個(gè)double型的值,這個(gè)值越大,表示可能性越大還是越小?

上圖并沒有明說,但是那一句e.g. distance,讓我想起了機(jī)器學(xué)習(xí)中的K-means,此時(shí)我腦海中的畫面如下:-若真如上圖所示,那么顯然confidence越小,是郭富城的可能性就越大了,接下來再去找一些權(quán)威的說法:

OpenCV的官方論壇有個(gè)帖子的說法如下圖:代碼中的confidence變量屬于命名不當(dāng),其含義不是可信度,而是與模型中的類別的距離:

再看第二個(gè)解釋,如下圖紅框,說得很清楚了,值越小,與模型中類別的相似度越高,0表示完全匹配:

再看一個(gè)Stack Overflow的解釋:

至此,相信您對(duì)confidence已經(jīng)足夠理解了,lable等于2,confidence=30.01,意思是:被識(shí)別照片與郭富城最相似,距離為30.01,距離越小,是郭富城的可能性越大

理解重點(diǎn)概念:threshold在聊threshold之前,咱們先看一個(gè)場景,還是劉德華郭富城的模型,這次咱們拿喜洋洋的照片給模型識(shí)別,識(shí)別結(jié)果如下:顯然,模型不會(huì)告訴你照片里是誰,只會(huì)告訴你:和郭富城的距離是3000.01看到這里,聰明的您可能會(huì)這么想:那我就寫一段代碼吧,識(shí)別結(jié)果的confidence如果太大(例如超過100),就判定用于識(shí)別的人不屬于訓(xùn)練模型的任何一個(gè)類別上述功能,OpenCV已經(jīng)幫咱們想到了,那就是:threshold,翻譯過來即門限,如果咱們?cè)O(shè)置了threshold等于100,那么,一旦距離超過100,OpenCV的lable返回值就是-1理解了confidence和threshold,接下來可以寫人臉識(shí)別的代碼了,感謝咱們的充分準(zhǔn)備,接下來是絲般順滑的編碼過程...源碼下載《JavaCV人臉識(shí)別三部曲》的完整源碼可在GitHub下載到,地址和鏈接信息如下表所示(https://github.com/zq2599/blog_demos):
名稱鏈接備注
項(xiàng)目主頁https://github.com/zq2599/blog_demos該項(xiàng)目在GitHub上的主頁
git倉庫地址(https)https://github.com/zq2599/blog_demos.git該項(xiàng)目源碼的倉庫地址,https協(xié)議
git倉庫地址(ssh)git@github.com:zq2599/blog_demos.git該項(xiàng)目源碼的倉庫地址,ssh協(xié)議
這個(gè)git項(xiàng)目中有多個(gè)文件夾,本篇的源碼在javacv-tutorials文件夾下,如下圖紅框所示:javacv-tutorials里面有多個(gè)子工程,《JavaCV人臉識(shí)別三部曲》系列的代碼在simple-grab-push工程下:編碼:人臉識(shí)別服務(wù)開始正式編碼,今天咱們不會(huì)新建工程,而是繼續(xù)使用《JavaCV的攝像頭實(shí)戰(zhàn)之一:基礎(chǔ)》中創(chuàng)建的simple-grab-push工程先定義一個(gè)Bean類PredictRlt.java,用來保存識(shí)別結(jié)果(lable和confidence字段):
package com.bolingcavalry.grabpush.extend;import lombok.Data;@Datapublic class PredictRlt {    private int lable;    private double confidence;}
然后把人臉識(shí)別有關(guān)的服務(wù)集中在RecognizeService.java中,方便主程序使用,代碼如下,有幾處要注意的地方稍后提到:
package com.bolingcavalry.grabpush.extend;import com.bolingcavalry.grabpush.Constants;import org.bytedeco.opencv.global.opencv_imgcodecs;import org.bytedeco.opencv.opencv_core.Mat;import org.bytedeco.opencv.opencv_core.Size;import org.bytedeco.opencv.opencv_face.FaceRecognizer;import org.bytedeco.opencv.opencv_face.FisherFaceRecognizer;import static org.bytedeco.opencv.global.opencv_imgcodecs.IMREAD_GRAYSCALE;import static org.bytedeco.opencv.global.opencv_imgproc.resize;/** * @author willzhao * @version 1.0 * @description 把人臉識(shí)別的服務(wù)集中在這里 * @date 2021/12/12 21:32 */public class RecognizeService {    private FaceRecognizer faceRecognizer;    // 推理結(jié)果的標(biāo)簽    private int[] plabel;    // 推理結(jié)果的置信度    private double[] pconfidence;    // 推理結(jié)果    private PredictRlt predictRlt;    // 用于推理的圖片尺寸,要和訓(xùn)練時(shí)的尺寸保持一致    private Size size= new Size(Constants.RESIZE_WIDTH, Constants.RESIZE_HEIGHT);    public RecognizeService(String modelPath) {        plabel = new int[1];        pconfidence = new double[1];        predictRlt = new PredictRlt();                // 識(shí)別類的實(shí)例化,與訓(xùn)練時(shí)相同        faceRecognizer = FisherFaceRecognizer.create();        // 加載的是訓(xùn)練時(shí)生成的模型        faceRecognizer.read(modelPath);        // 設(shè)置門限,這個(gè)可以根據(jù)您自身的情況不斷調(diào)整        faceRecognizer.setThreshold(Constants.MAX_CONFIDENCE);    }    /**     * 將Mat實(shí)例給模型去推理     * @param mat     * @return     */    public PredictRlt predict(Mat mat) {        // 調(diào)整到和訓(xùn)練一致的尺寸        resize(mat, mat, size);        boolean isFinish = false;        try {            // 推理(這一行可能拋出RuntimeException異常,因此要補(bǔ)貨,否則會(huì)導(dǎo)致程序退出)            faceRecognizer.predict(mat, plabel, pconfidence);            isFinish = true;        } catch (RuntimeException runtimeException) {            runtimeException.printStackTrace();        }        // 如果發(fā)生過異常,就提前返回        if (!isFinish) {            return null;        }        // 將推理結(jié)果寫入返回對(duì)象中        predictRlt.setLable(plabel[0]);        predictRlt.setConfidence(pconfidence[0]);        return predictRlt;    }}
上述代碼有以下幾處需要注意:構(gòu)造方法中,通過faceRecognizer.setThreshold設(shè)置門限,我在實(shí)際使用中發(fā)現(xiàn)50比較合適,您可以根據(jù)自己的情況不斷調(diào)整predict方法中,用于識(shí)別的圖片要用resize方法調(diào)整大小,尺寸要和訓(xùn)練時(shí)的尺寸一致實(shí)測發(fā)現(xiàn),在一張照片中出現(xiàn)多個(gè)人臉時(shí),faceRecognizer.predict可能拋出RuntimeException異常,因此這里要捕獲異常,避免程序崩潰退出編碼:檢測和識(shí)別檢測有關(guān)的接口DetectService.java,如下,和《JavaCV人臉識(shí)別三部曲之一:視頻中的人臉保存為圖片》中的完全一致:
package com.bolingcavalry.grabpush.extend;import com.bolingcavalry.grabpush.Constants;import org.bytedeco.javacv.Frame;import org.bytedeco.javacv.OpenCVFrameConverter;import org.bytedeco.opencv.opencv_core.*;import org.bytedeco.opencv.opencv_objdetect.CascadeClassifier;import static org.bytedeco.opencv.global.opencv_core.CV_8UC1;import static org.bytedeco.opencv.global.opencv_imgcodecs.imwrite;import static org.bytedeco.opencv.global.opencv_imgproc.*;/** * @author willzhao * @version 1.0 * @description 檢測工具的通用接口 * @date 2021/12/5 10:57 */public interface DetectService {    /**     * 根據(jù)傳入的MAT構(gòu)造相同尺寸的MAT,存放灰度圖片用于以后的檢測     * @param src 原始圖片的MAT對(duì)象     * @return 相同尺寸的灰度圖片的MAT對(duì)象     */    static Mat buildGrayImage(Mat src) {        return new Mat(src.rows(), src.cols(), CV_8UC1);    }        /**     * 初始化操作,例如模型下載     * @throws Exception     */    void init() throws Exception;    /**     * 得到原始幀,做識(shí)別,添加框選     * @param frame     * @return     */    Frame convert(Frame frame);    /**     * 釋放資源     */    void releaseOutputResource();}
然后就是DetectService的實(shí)現(xiàn)類DetectAndRecognizeService .java,功能是用攝像頭的一幀圖片檢測人臉,再拿檢測到的人臉給RecognizeService做識(shí)別,完整代碼如下,有幾處要注意的地方稍后提到:
package com.bolingcavalry.grabpush.extend;import lombok.extern.slf4j.Slf4j;import org.bytedeco.javacpp.Loader;import org.bytedeco.javacv.Frame;import org.bytedeco.javacv.OpenCVFrameConverter;import org.bytedeco.opencv.opencv_core.*;import org.bytedeco.opencv.opencv_objdetect.CascadeClassifier;import java.io.File;import java.net.URL;import java.util.Map;import static org.bytedeco.opencv.global.opencv_imgproc.*;/** * @author willzhao * @version 1.0 * @description 音頻相關(guān)的服務(wù) * @date 2021/12/3 8:09 */@Slf4jpublic class DetectAndRecognizeService implements DetectService {    /**     * 每一幀原始圖片的對(duì)象     */    private Mat grabbedImage = null;    /**     * 原始圖片對(duì)應(yīng)的灰度圖片對(duì)象     */    private Mat grayImage = null;    /**     * 分類器     */    private CascadeClassifier classifier;    /**     * 轉(zhuǎn)換器     */    private OpenCVFrameConverter.ToMat converter = new OpenCVFrameConverter.ToMat();    /**     * 檢測模型文件的下載地址     */    private String detectModelFileUrl;    /**     * 處理每一幀的服務(wù)     */    private RecognizeService recognizeService;    /**     * 為了顯示的時(shí)候更加友好,給每個(gè)分類對(duì)應(yīng)一個(gè)名稱     */    private Map kindNameMap;    /**     * 構(gòu)造方法     * @param detectModelFileUrl     * @param recognizeModelFilePath     * @param kindNameMap     */    public DetectAndRecognizeService(String detectModelFileUrl, String recognizeModelFilePath, Map kindNameMap) {        this.detectModelFileUrl = detectModelFileUrl;        this.recognizeService = new RecognizeService(recognizeModelFilePath);        this.kindNameMap = kindNameMap;    }    /**     * 音頻采樣對(duì)象的初始化     * @throws Exception     */    @Override    public void init() throws Exception {        // 下載模型文件        URL url = new URL(detectModelFileUrl);        File file = Loader.cacheResource(url);        // 模型文件下載后的完整地址        String classifierName = file.getAbsolutePath();        // 根據(jù)模型文件實(shí)例化分類器        classifier = new CascadeClassifier(classifierName);        if (classifier == null) {            log.error("Error loading classifier file [{}]", classifierName);            System.exit(1);        }    }    @Override    public Frame convert(Frame frame) {        // 由幀轉(zhuǎn)為Mat        grabbedImage = converter.convert(frame);        // 灰度Mat,用于檢測        if (null==grayImage) {            grayImage = DetectService.buildGrayImage(grabbedImage);        }        // 進(jìn)行人臉識(shí)別,根據(jù)結(jié)果做處理得到預(yù)覽窗口顯示的幀        return detectAndRecoginze(classifier, converter, frame, grabbedImage, grayImage, recognizeService, kindNameMap);    }    /**     * 程序結(jié)束前,釋放人臉識(shí)別的資源     */    @Override    public void releaseOutputResource() {        if (null!=grabbedImage) {            grabbedImage.release();        }        if (null!=grayImage) {            grayImage.release();        }        if (null==classifier) {            classifier.close();        }    }    /**     * 檢測圖片,將檢測結(jié)果用矩形標(biāo)注在原始圖片上     * @param classifier 分類器     * @param converter Frame和mat的轉(zhuǎn)換器     * @param rawFrame 原始視頻幀     * @param grabbedImage 原始視頻幀對(duì)應(yīng)的mat     * @param grayImage 存放灰度圖片的mat     * @param kindNameMap 每個(gè)分類編號(hào)對(duì)應(yīng)的名稱     * @return 標(biāo)注了識(shí)別結(jié)果的視頻幀     */    static Frame detectAndRecoginze(CascadeClassifier classifier,                                    OpenCVFrameConverter.ToMat converter,                                    Frame rawFrame,                                    Mat grabbedImage,                                    Mat grayImage,                                    RecognizeService recognizeService,                                    Map kindNameMap) {        // 當(dāng)前圖片轉(zhuǎn)為灰度圖片        cvtColor(grabbedImage, grayImage, CV_BGR2GRAY);        // 存放檢測結(jié)果的容器        RectVector objects = new RectVector();        // 開始檢測        classifier.detectMultiScale(grayImage, objects);        // 檢測結(jié)果總數(shù)        long total = objects.size();        // 如果沒有檢測到結(jié)果,就用原始幀返回        if (total<1) {            return rawFrame;        }        PredictRlt predictRlt;        int pos_x;        int pos_y;        int lable;        double confidence;        String content;        // 如果有檢測結(jié)果,就根據(jù)結(jié)果的數(shù)據(jù)構(gòu)造矩形框,畫在原圖上        for (long i = 0; i < total; i++) {            Rect r = objects.get(i);// 核心代碼,把檢測到的人臉拿去識(shí)別            predictRlt = recognizeService.predict(new Mat(grayImage, r));            // 如果返回為空,表示出現(xiàn)過異常,就執(zhí)行下一個(gè)            if (null==predictRlt) {                System.out.println("return null");                continue;            }            // 分類的編號(hào)(訓(xùn)練時(shí)只有1和2,這里只有有三個(gè)值,1和2與訓(xùn)練的分類一致,還有個(gè)-1表示沒有匹配上)            lable = predictRlt.getLable();            // 與模型中的分類的距離,值越小表示相似度越高            confidence = predictRlt.getConfidence();            // 得到分類編號(hào)后,從map中取得名字,用來顯示            if (kindNameMap.containsKey(predictRlt.getLable())) {                content = String.format("%s, confidence : %.4f", kindNameMap.get(lable), confidence);            } else {                // 取不到名字的時(shí)候,就顯示unknown                content = "unknown(" + predictRlt.getLable() + ")";                System.out.println(content);            }            int x = r.x(), y = r.y(), w = r.width(), h = r.height();            rectangle(grabbedImage, new Point(x, y), new Point(x + w, y + h), Scalar.RED, 1, CV_AA, 0);            pos_x = Math.max(r.tl().x()-10, 0);            pos_y = Math.max(r.tl().y()-10, 0);            putText(grabbedImage, content, new Point(pos_x, pos_y), FONT_HERSHEY_PLAIN, 1.5, new Scalar(0,255,0,2.0));        }        // 釋放檢測結(jié)果資源        objects.close();        // 將標(biāo)注過的圖片轉(zhuǎn)為幀,返回        return converter.convert(grabbedImage);    }}
上述代碼有幾處要注意:重點(diǎn)關(guān)注detectAndRecoginze方法,這里面先調(diào)用classifier.detectMultiScale檢測出當(dāng)前照片所有的人臉,然后把每一張人臉交個(gè)recognizeService進(jìn)行識(shí)別,識(shí)別結(jié)果的lable是個(gè)int型的,看起來不夠友好,因此從kindNameMap中根據(jù)lable找出對(duì)應(yīng)的名稱來最終給每個(gè)頭像添加矩形框,還在左上角添加識(shí)別結(jié)果,以及confidence的值處理完畢后轉(zhuǎn)為Frame對(duì)象返回,這樣的幀顯示在預(yù)覽頁面,效果就是視頻中每個(gè)人被框選出來,并帶有身份現(xiàn)在核心代碼已經(jīng)寫完,需要再寫一些代碼來使用DetectAndRecognizeService編碼:運(yùn)行框架《JavaCV的攝像頭實(shí)戰(zhàn)之一:基礎(chǔ)》創(chuàng)建的simple-grab-push工程中已經(jīng)準(zhǔn)備好了父類AbstractCameraApplication,所以本篇繼續(xù)使用該工程,創(chuàng)建子類實(shí)現(xiàn)那些抽象方法即可編碼前先回顧父類的基礎(chǔ)結(jié)構(gòu),如下圖,粗體是父類定義的各個(gè)方法,紅色塊都是需要子類來實(shí)現(xiàn)抽象方法,所以接下來,咱們以本地窗口預(yù)覽為目標(biāo)實(shí)現(xiàn)這三個(gè)紅色方法即可:新建文件PreviewCameraWithIdentify.java,這是AbstractCameraApplication的子類,其代碼很簡單,接下來按上圖順序依次說明先定義CanvasFrame類型的成員變量previewCanvas,這是展示視頻幀的本地窗口:
protected CanvasFrame previewCanvas
把前面創(chuàng)建的DetectService作為成員變量,后面檢測的時(shí)候會(huì)用到:
/**     * 檢測工具接口     */    private DetectService detectService;
PreviewCameraWithIdentify的構(gòu)造方法,接受DetectService的實(shí)例:
/**     * 不同的檢測工具,可以通過構(gòu)造方法傳入     * @param detectService     */    public PreviewCameraWithIdentify(DetectService detectService) {        this.detectService = detectService;    }
然后是初始化操作,可見是previewCanvas的實(shí)例化和參數(shù)設(shè)置,還有檢測、識(shí)別的初始化操作:
@Override    protected void initOutput() throws Exception {        previewCanvas = new CanvasFrame("攝像頭預(yù)覽和身份識(shí)別", CanvasFrame.getDefaultGamma() / grabber.getGamma());        previewCanvas.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        previewCanvas.setAlwaysOnTop(true);        // 檢測服務(wù)的初始化操作        detectService.init();    }
接下來是output方法,定義了拿到每一幀視頻數(shù)據(jù)后做什么事情,這里調(diào)用了detectService.convert檢測人臉并保存圖片,然后在本地窗口顯示:
@Override    protected void output(Frame frame) {        // 原始幀先交給檢測服務(wù)處理,這個(gè)處理包括物體檢測,再將檢測結(jié)果標(biāo)注在原始圖片上,        // 然后轉(zhuǎn)換為幀返回        Frame detectedFrame = detectService.convert(frame);        // 預(yù)覽窗口上顯示的幀是標(biāo)注了檢測結(jié)果的幀        previewCanvas.showImage(detectedFrame);    }
最后是處理視頻的循環(huán)結(jié)束后,程序退出前要做的事情,先關(guān)閉本地窗口,再釋放檢測服務(wù)的資源:
@Override    protected void releaseOutputResource() {        if (null!= previewCanvas) {            previewCanvas.dispose();        }        // 檢測工具也要釋放資源        detectService.releaseOutputResource();    }
由于檢測有些耗時(shí),所以兩幀之間的間隔時(shí)間要低于普通預(yù)覽:
@Override    protected int getInterval() {        return super.getInterval()/8;    }
至此,功能已開發(fā)完成,再寫上main方法,代碼如下,有幾處要注意的地方稍后說明:
public static void main(String[] args) {        String modelFileUrl = "https://raw.github.com/opencv/opencv/master/data/haarcascades/haarcascade_frontalface_alt.xml";        String recognizeModelFilePath = "E:\\temp\\202112\\18\\001\\faceRecognizer.xml";        // 這里分類編號(hào)的身份的對(duì)應(yīng)關(guān)系,和之前訓(xùn)練時(shí)候的設(shè)定要保持一致        Map kindNameMap = new HashMap();        kindNameMap.put(1, "Man");        kindNameMap.put(2, "Woman");        // 檢測服務(wù)        DetectService detectService = new DetectAndRecognizeService(modelFileUrl,recognizeModelFilePath, kindNameMap);        // 開始檢測        new PreviewCameraWithIdentify(detectService).action(1000);    }
上述main方法中,有以下幾處需要注意:kindNameMap是個(gè)HashMap,里面放這每個(gè)分類編號(hào)對(duì)應(yīng)的名稱,我訓(xùn)練的模型中包含了兩位群眾演員的頭像,給他們分別起名ManWomanmodelFileUrl是人臉檢測時(shí)用到的模型地址recognizeModelFilePath是人臉識(shí)別時(shí)用到的模型地址,這個(gè)模型是《JavaCV人臉識(shí)別三部曲之二:訓(xùn)練》一文中訓(xùn)練的模型至此,人臉識(shí)別的代碼已經(jīng)寫完,運(yùn)行main方法,請(qǐng)幾位群眾演員來到攝像頭前面,驗(yàn)證效果吧驗(yàn)證

程序運(yùn)行起來后,請(qǐng)名為Man的群眾演員A站在攝像頭前面,如下圖,識(shí)別成功:

接下來,請(qǐng)名為Woman的群眾演員B過來,和群眾演員A同框,如下圖,同時(shí)識(shí)別成功,不過偶爾會(huì)識(shí)別錯(cuò)誤,提示成unknown(-1)

再請(qǐng)一個(gè)沒有參與訓(xùn)練的小群眾演員過來,與A同框,此刻的識(shí)別也是準(zhǔn)確的,小演員被標(biāo)注為unknown(-1)

去看程序的控制臺(tái),發(fā)現(xiàn)FaceRecognizer.predict方法會(huì)拋出異常,幸好程序捕獲了異常,不會(huì)把整個(gè)進(jìn)程中斷退出:

至此,整個(gè)《JavaCV人臉識(shí)別三部曲》全部完成,如果您是位java程序員,正在尋找人臉識(shí)別相關(guān)的方案,希望本系列能給您一些參考

另外《JavaCV人臉識(shí)別三部曲》是《JavaCV的攝像頭實(shí)戰(zhàn)》系列的分支,作為主干的《JavaCV的攝像頭實(shí)戰(zhàn)》依然在持續(xù)更新中,欣宸原創(chuàng)會(huì)繼續(xù)與您一路相伴,學(xué)習(xí)、實(shí)戰(zhàn)、提升

歡迎關(guān)注博客園:程序員欣宸

學(xué)習(xí)路上,你不孤單,欣宸原創(chuàng)一路相伴...

標(biāo)簽:

返回頂部
高清视频在线观看免费播放器-伊人日本-色九月综合-18禁止看的免费污网站-免费观看性行为视频的网站-天天碰天天操-久久精品国产欧美日韩99热-中文字幕在线视频不卡-国产偷人妻精品一区二区在线-国内精品久-伊人影院在线看-密臀av一区-久久综合五月丁香久久激情-福利一区福利二区-gg国产精品国内免费观看-国产精品 高清 尿 小便 嘘嘘
  • <cite id="ecweg"><pre id="ecweg"></pre></cite>
    <rt id="ecweg"><acronym id="ecweg"></acronym></rt>
  • <rt id="ecweg"></rt>
    91看片就是不一样| 天堂8在线天堂资源bt| 91 在线视频观看| 日本黄色的视频| 老汉色影院首页| 69sex久久精品国产麻豆| 国产h视频在线播放| 毛片毛片毛片毛片毛片毛片毛片毛片毛片| 91淫黄看大片| 波多野结衣激情| 99中文字幕在线观看| 缅甸午夜性猛交xxxx| 香蕉视频禁止18| 欧美在线观看黄| 久草综合在线观看| 成年人三级视频| 欧美一级片中文字幕| 手机在线免费毛片| 国产91美女视频| 懂色av一区二区三区四区五区| 波多野结衣综合网| 91aaa精品| 国产最新免费视频| 超碰中文字幕在线观看| 欧美亚洲国产成人| 自拍偷拍视频在线| 国产欧美高清在线| 五月天在线免费视频| 免费一级特黄录像| 国产欧美日韩小视频| 99re6在线观看| 国产99久久九九精品无码| 国产精品中文久久久久久| 日韩av在线综合| 国产精品无码一区二区在线| 99中文字幕在线| 欧美精品性生活| 日本成年人网址| 国产日韩视频在线播放| 久久精品香蕉视频| 大桥未久一区二区三区| 最新av免费在线观看| 免费视频爱爱太爽了| 在线观看av免费观看| 波多野结衣天堂| 国产成人亚洲精品无码h在线| 丁香六月激情网| 香港三级日本三级a视频| 亚洲天堂一区二区在线观看| 欧美特级aaa| 天天操天天摸天天爽| 狠狠爱免费视频| 日韩xxxx视频| 色爽爽爽爽爽爽爽爽| 日韩欧美色视频| 国产免费人做人爱午夜视频| 国产欧美日韩小视频| 人妻无码久久一区二区三区免费| 日本a级片在线观看| 日本一本草久p| av一区二区三区免费观看| 日韩精品福利片午夜免费观看| 无码人妻aⅴ一区二区三区日本| 911av视频| 久久99国产精品一区| a级片一区二区| 欧美aaa在线观看| 中文字幕线观看| 国产成人免费高清视频| 97久久国产亚洲精品超碰热| 日韩极品视频在线观看| 亚洲 高清 成人 动漫| 欧美亚洲一二三区| 又色又爽又高潮免费视频国产| 高清av免费看| 99精品视频免费版的特色功能| www国产无套内射com| 激情深爱综合网| 国产又猛又黄的视频| 欧美性视频在线播放| 欧美精品久久96人妻无码| 日韩视频在线观看视频| 无码av天堂一区二区三区| 无遮挡又爽又刺激的视频| 国产福利影院在线观看| 视色,视色影院,视色影库,视色网 日韩精品福利片午夜免费观看 | 老汉色影院首页| 欧美综合在线播放| 日本三级黄色网址| 青青在线免费观看| 亚洲xxxx2d动漫1| 超薄肉色丝袜足j调教99| 波多野结衣家庭教师在线| 激情五月婷婷基地| 精品视频在线观看一区| 密臀av一区二区三区| 在线观看国产一级片| 国产系列第一页| 国产又黄又猛视频| 影音先锋成人资源网站| 色哟哟精品视频| 精品国产一区二区三区无码| 亚洲18在线看污www麻豆| 波多野结衣之无限发射| 一区二区三区一级片| 成人黄色一区二区| 丁香六月激情婷婷| 欧美精品 - 色网| 免费看a级黄色片| 黄页网站在线观看视频| 99精品视频国产| 国产福利一区视频| 黄色一级在线视频| 国产高清不卡无码视频| 无码人妻丰满熟妇区五十路百度| 久久久九九九热| 天天综合网日韩| 美女福利视频在线| 国产av人人夜夜澡人人爽麻豆| 看看黄色一级片| 欧美在线aaa| www.com黄色片| 日本熟妇人妻中出| 免费欧美一级视频| 欧美一级视频免费看| 激情五月六月婷婷| 日本福利视频导航| 欧美激情第一区| 国产成人美女视频| 奇米视频7777| 182午夜视频| 一二三级黄色片| 欧洲在线免费视频| 中文 日韩 欧美| 黄色一级片网址| 强伦女教师2:伦理在线观看| 九九九久久久久久久| 亚洲制服在线观看| 老司机午夜网站| 日韩久久久久久久久久久久| 免费的av在线| 九一免费在线观看| 玖玖精品在线视频| 日韩成人三级视频| 精品国偷自产一区二区三区| www.av毛片| 亚洲不卡中文字幕无码| 凹凸国产熟女精品视频| 日本精品免费在线观看| 三级在线视频观看| 强伦女教师2:伦理在线观看| 日韩精品一区二区三区四| www.亚洲视频.com| 成人羞羞国产免费网站| 网站一区二区三区| 欧美成年人视频在线观看| 91小视频网站| 免费看日本黄色| 免费在线观看的毛片| 九九久久久久久| 9l视频自拍9l视频自拍| 中文字幕日韩精品无码内射| 韩国日本在线视频| 99日在线视频| 97在线国产视频| 欧美成年人视频在线观看| 国产人妻人伦精品| 欧美日韩亚洲自拍| 777久久精品一区二区三区无码| 91九色在线观看视频| 992kp免费看片| 草草久久久无码国产专区| 高清一区在线观看| 婷婷五月综合缴情在线视频| 亚洲视频一二三四| 欧美日韩精品在线一区二区| 免费网站在线观看黄| 日韩欧美国产综合在线| 亚洲男人天堂av在线| www.爱色av.com| 少妇久久久久久被弄到高潮| 久久久久久蜜桃一区二区| 国产精品一区二区免费在线观看| 青青草原播放器| 激情网站五月天| 中文字幕av导航| 国产在线观看福利| 国产精品久久久久久久久电影网| youjizzxxxx18| 日韩小视频在线播放| 国产系列第一页| 手机av在线网| 欧美国产激情视频| 日本欧美视频在线观看| 中国老女人av| 蜜臀一区二区三区精品免费视频| 男人天堂网视频| 国产女大学生av| 欧美深夜福利视频| 人人妻人人澡人人爽欧美一区双|