1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        使用 Python 和 OpenCV 制作反應(yīng)游戲

        共 19902字,需瀏覽 40分鐘

         ·

        2024-04-19 10:20

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

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

        在本文中,將向你展示如何使用 OpenCV 在 Python 中制作一個(gè)反應(yīng)游戲,你可以動(dòng)手來玩。

        你可能已經(jīng)熟悉 OpenCV,OpenCV 基本上允許進(jìn)行各種圖像處理。

        你可以在下面的視頻中看到最終結(jié)果,并且可以在此處獲取文件:https://github.com/Goncalo-Chambel/ReactionGame

        盡管這可能看起來很復(fù)雜(取決于你的專業(yè)知識),但在我們看來,這是一個(gè)相當(dāng)簡單但很有趣的項(xiàng)目。你基本上可以用 200 行代碼創(chuàng)建一個(gè)游戲(這代碼量很少了?。?。

        我們將把任務(wù)分成幾個(gè)部分:設(shè)置+手部檢測、主要游戲機(jī)制、創(chuàng)建實(shí)際游戲最后潤色。

        第 1 步:設(shè)置 + 手部檢測

        這個(gè)項(xiàng)目的主要目標(biāo)是創(chuàng)建一個(gè)反應(yīng)游戲,其中圓圈會隨機(jī)出現(xiàn)在屏幕上,你必須用你的手盡可能快地“觸摸”它們。

        因此,第一個(gè)步驟是讓程序訪問你的網(wǎng)絡(luò)攝像頭。

        為此,我們將使用 OpenCV 庫,為此我們只需添加一行import cv2。就這么簡單,但如果你還沒有安裝,你必須先安裝它。

        在此處添加了此項(xiàng)目的要求:https://github.com/Goncalo-Chambel/ReactionGame/blob/main/requirements.txt

        因此你可以通過在命令行中鍵入pip install -r requirements.txt來安裝所有這些要求。

        cv2 庫有很多功能,但讓我們一步一步來。第一個(gè)目標(biāo)是告訴 Python 從網(wǎng)絡(luò)攝像頭讀取數(shù)據(jù)并將其顯示在屏幕上。這可以通過使用函數(shù)cv2.VideoCapture()來完成

        import cv2
        cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)

        現(xiàn)在cap變量包含對你的網(wǎng)絡(luò)攝像頭的引用。然后在我們的主文件中,我們可以創(chuàng)建一個(gè)無限循環(huán),每次迭代都會顯示網(wǎng)絡(luò)攝像頭捕獲的當(dāng)前圖像。

        import cv2
        cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)
        cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)  # set width of window
        cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)  # set height of window

        while True:
            ret, frame = cap.read()
            cv2.imshow("Reaction Game", frame)
            k = cv2.waitKey(1) & 0xFF
            if k == ord('q'):
                break

        有了這幾行代碼,我們應(yīng)該有一個(gè)程序,這個(gè)程序可以簡單地打開一個(gè)新窗口(名為“反應(yīng)游戲”),大小為 1280 x 720 像素,帶有網(wǎng)絡(luò)攝像頭的視頻源。我還添加了最后幾行代碼,以便你可以關(guān)閉窗口并按“q”退出程序。

        現(xiàn)在我們可以繼續(xù)檢測手了。創(chuàng)建一個(gè)算法來檢測視頻中的手是一項(xiàng)復(fù)雜的任務(wù),但幸運(yùn)的是我們不必重新發(fā)明輪子。有一個(gè)非常好的庫可以為我們做這件事,叫做 CV Zone。

        CV Zone 允許各種與對象檢測相關(guān)的項(xiàng)目,但我們主要對 HandDetector 模型感興趣。該模型使我們能夠獲得有關(guān)視頻中被跟蹤手的重要信息,例如它們的中心位置或邊界框。我們初始化模型的方式如下:

        from cvzone.HandTrackingModule import HandDetector
        detector = HandDetector(detectionCon=0.8, maxHands=2)

        其中detectionCon是置信區(qū)間(從0到1),表明你希望模型跟蹤手的精度。更高的值意味著模型更確信被跟蹤的手就是手,但也可能使模型“錯(cuò)過手”,因?yàn)樗鼪]有信心相信它們是手。maxHands參數(shù)僅限制模型一次可以跟蹤的手的數(shù)量。

        然后在我們的主循環(huán)中,我們只調(diào)用函數(shù)detector.findHands()來獲取有關(guān)被跟蹤手的信息。

        while True:
            ret, frame = cap.read()
            hands, frame = detector.findHands(frame, flipType=False)
            cv2.imshow("Reaction Game", frame)

        輸出:

        如你所見,該算法非常擅長跟蹤手部(包括手指位置)。請注意,根據(jù)你的規(guī)格,該程序可能看起來有點(diǎn)“不穩(wěn)定”。此外,根據(jù)你使用的相機(jī),你可能不需要翻轉(zhuǎn)圖像,只需檢查標(biāo)簽“左手”是否真的對應(yīng)于你的左手。

        最后,在屏幕上顯示所有這些信息可能會太混亂,因此我們可以告訴檢測器不要通過書寫來繪制這些信息

        hands = detector.findHands(frame, flipType=False, draw=False)

        請注意,當(dāng)我們包含參數(shù)draw=False時(shí),detector僅返回手信息(與返回幀相反)。

        第 2 步:主要游戲機(jī)制

        我們現(xiàn)在可以研究我們游戲的基本機(jī)制。基本想法是在屏幕上隨機(jī)生成圓圈并檢測手是否在觸摸它。

        這里有兩個(gè)主要部分,畫圈檢查碰撞。

        畫圈

        這是一個(gè)相對簡單的步驟,因?yàn)?em>cv2有一個(gè)內(nèi)置函數(shù)cv2.circle(),可以在屏幕上繪制一個(gè)圓形,該函數(shù)將我們正在繪制的圖像、屏幕上的位置(以像素為單位)、圓的半徑(以像素為單位)、顏色(以BGR) 和線條粗細(xì)作為輸入。所以假設(shè)我們想在屏幕中間放置一個(gè)紅色圓圈,厚度為2,半徑為 50 像素,我們會這樣做:

        while True:
            ret, frame = cap.read()
            cv2.circle(frame,(int(width/2),int(heigh/2)), 50, (0,0,255), 2)
            cv2.imshow("Reaction Game", frame)

        請注意,此函數(shù)不返回任何內(nèi)容,它會自動(dòng)更新frame變量。此外,如果你想要一個(gè)實(shí)心圓而不僅僅是輪廓,你可以將粗細(xì)設(shè)置為 -1。

        在繼續(xù)在屏幕上創(chuàng)建隨機(jī)圓圈之前,讓我們先創(chuàng)建自己的Circle類。如果我們想在只處理一個(gè)變量的同時(shí)訪問圓的多個(gè)屬性,這將很方便。這是一個(gè)非常簡單的類,現(xiàn)在讓我們添加一個(gè)構(gòu)造函數(shù)和一個(gè)draw()方法

        class Circle:

            def __init__(self, coordinates, radius, color, thickness):
                self.coordinates = coordinates
                self.radius = radius
                self.color = color
                self.thickness = thickness

            def draw(self, _frame):
                cv2.circle(_frame, self.coordinates, self.radius, self.color, self.thickness)

        現(xiàn)在如果我們想像之前那樣畫一個(gè)圓圈,我們會這樣做:

        target = Circle((int(width/2),int(heigh/2)), 50, (00,255), 2)
        while True:
            ret, frame = cap.read()
            target.draw(frame)
            cv2.imshow("Reaction Game", frame)

        現(xiàn)在可能看起來不是很有用,但以后會有所幫助。

        在繼續(xù)討論交集方法本身之前,我們首先需要一些東西來檢查交集。我們已經(jīng)有了一種在屏幕上創(chuàng)建目標(biāo)的方法,但我們需要將其與某些東西進(jìn)行比較。很明顯,有些東西會是我們的手,但具體是手的哪一部分?

        我們可以使用邊界框,但我覺得這可能太容易了。我們還可以使用手指的位置,例如食指,但這似乎不太直觀。我發(fā)現(xiàn)我認(rèn)為效果最好的方法是使用手的中心位置。

        我們可以在手的中心位置創(chuàng)建另一個(gè)圓圈,這樣我們只需要檢查一個(gè)圓圈是否與另一個(gè)圓圈相交。

        首先我們需要一種方法在手的中心位置創(chuàng)建一個(gè)圓圈。變量handsdetector.findHands()函數(shù)的輸出)是一個(gè)列表,其中每個(gè)項(xiàng)目都是一個(gè)字典,其中包含有關(guān)被跟蹤的手的信息。這個(gè)字典有 4 個(gè)鍵:

        • lmList:21 個(gè)地標(biāo)的位置列表(以像素為單位)
        • bbox : 邊界框的坐標(biāo)和大小(以像素為單位)
        • center : 中心位置的坐標(biāo),以像素為單位
        • type:左手或右手

        從這 4 個(gè)鍵中,我們感興趣的是中心,所以為了得到中心位置,我們這么做:

        while True:
            ret, frame = cap.read()
            hands = detector.findHands(frame, flipType=False, draw=False)
            if hands:
                for i in range(len(hands)):
                    hand_position = hands[i]["center"]

        我們首先檢查是否檢測到任何手,如果是,我們可以訪問中心位置,但只需指定鍵“center”。

        現(xiàn)在我們有了創(chuàng)建一個(gè)圓圈的方法,我們可以在每只手的中心創(chuàng)建一個(gè)圓圈并通過添加這兩條線來繪制它

        hand_circle = Circle(hand_position, hand_radius, (00255), 1)
        hand_circle.draw(frame)

        這會在每個(gè)被跟蹤手的中心位置繪制一個(gè)紅色圓圈(未填充)。注意,手的中心位置不是手掌中心,而是所有地標(biāo)位置的平均位置。你可以通過合上手來測試一下,你可以看到中心位置向你手的下部移動(dòng)。

        檢查碰撞

        我們需要一種方法來檢查玩家是否擊中了目標(biāo)。這將是我們游戲的主要機(jī)制。

        Cv2 沒有任何檢查兩個(gè)對象是否相交的函數(shù),但由于我們處理的是圓,所以這個(gè)任務(wù)變得非常簡單。我們只需要檢查圓心之間的距離是否小于或等于半徑之和。讓我們看一下下面的例子

        相交算法

        希望這說明了相交算法。由于我們已經(jīng)知道目標(biāo)半徑和手圓半徑,我們只需要計(jì)算距離d。并且有一個(gè)非常簡單的數(shù)學(xué)公式,給定兩個(gè)點(diǎn),計(jì)算它們之間的距離。

        該距離公式是:

        我們所要做的就是在代碼中創(chuàng)建該函數(shù)。為了方便起見,我在Circle類中創(chuàng)建了這個(gè)函數(shù),如下所示

        def check_intersection(self, other_coordinates, other_radius):
            distance = math.sqrt(math.pow(other_coordinates[0] - self.coordinates[0], 2) + math.pow(
                other_coordinates[1] - self.coordinates[1], 2))

            if distance <= self.radius + other_radius:
                return True
            else:
                return False

        該函數(shù)考慮了我們上面討論的所有內(nèi)容并返回一個(gè)布爾值,指示一個(gè)圓是否與另一個(gè)圓相交。

        我們可以通過在主循環(huán)中添加幾行來測試它

        if hands:
            for i in range(len(hands)):
                hand_position = hands[i]["center"]
                hand_circle = Circle(hand_position,hand_radius,(0,0,255),1)
                if target.check_intersection(hand_circle.coordinates, hand_circle.radius):
                   
                    # is intersecting
                    hand_circle.color = (02550)
                else:
                    # not intersection
                    hand_circle.color = (00255)
                hand_circle.draw(frame)

        你現(xiàn)在可以看到,如果我“觸摸”目標(biāo),我的手圈會變成綠色,否則就是紅色

        第 3 步:創(chuàng)建實(shí)際游戲

        因此,創(chuàng)建我們實(shí)際游戲的第一步是,一旦我們擊中當(dāng)前目標(biāo),就能夠在隨機(jī)位置選擇一個(gè)新目標(biāo)。為此,我們可以創(chuàng)建一個(gè)這樣的函數(shù)

        def create_random_target(current_target_pos=[]):
            if current_target_pos:
                possible_x = []

                x_limit = [target_radius + border_size + 15, width - target_radius - border_size - 15]
                y_limit = [target_radius + border_size + 15, height - target_radius - border_size - 15]

                for i in range(x_limit[0], x_limit[1]):
                    if i + 200 < current_target_pos[0or i - 200 > current_target_pos[0]:
                        possible_x.append(i)

                possible_y = []
                for i in range(y_limit[0], y_limit[1]):
                    if i + 200 < current_target_pos[1or i - 200 > current_target_pos[1]:
                        possible_y.append(i)

                if not possible_x:
                    possible_x = range(x_limit[0], x_limit[1])

                if not possible_y:
                    possible_y = range(y_limit[0], y_limit[1])

            else:
                possible_x = range(target_radius + border_size, width - target_radius - border_size)
                possible_y = range(target_radius + border_size, height - target_radius - border_size)
            # pick a random coordinate
            random_x = random.choice(possible_x)
            random_y = random.choice(possible_y)
            # pick a random color
            random_color = [random.randint(0255), random.randint(0255), random.randint(0256)]
            _target = Circle([random_x, random_y], target_radius, random_color, -1)

            return _target

        這個(gè)函數(shù)有很多事情要做,所以讓我們分解一下。

        第一部分是我們設(shè)置新目標(biāo)可以采用的寬度和高度的可能值。我們通過首先設(shè)置變量x_limity_limit來做到這一點(diǎn),顧名思義,這些變量限制了可以放置目標(biāo)的位置。這是為了避免我們最終得到一個(gè)部分在屏幕外的目標(biāo)。

        你可能已經(jīng)注意到有一個(gè)新變量,border_size我們還沒有討論過,但我稍后會討論它。

        然后,對于每個(gè)維度(寬度和高度),我們運(yùn)行一個(gè) for 循環(huán),用可能的位置填充數(shù)組possible_xpossible_y。請注意,我加入了一個(gè)限制,為了讓游戲更具挑戰(zhàn)性,新目標(biāo)必須與當(dāng)前目標(biāo)相距至少 282 像素(寬度為 200 像素,高度為 200 像素))

        之后,只需從possible_xpossible_y中選擇一個(gè)隨機(jī)值,分配一個(gè)隨機(jī)顏色,然后返回新的圓圈。

        現(xiàn)在我們可以在主循環(huán)中使用這個(gè)函數(shù)

        if hands:
            for i in range(len(hands)):
                hand_position = hands[i]["center"]
                hand_circle = Circle(hand_position,hand_radius,(0,0,255),1)
                hand_circle.draw(frame)
                if target.check_intersection(hand_circle.coordinates, hand_circle.radius):
                   
                    # is intersecting
                    hit_target = True
                    break;
        if hit_target:
            target_count += 1
            target = create_random_target(target.coordinates)
            hit_target = False

        如你所見,此代碼可能非常耗時(shí),因?yàn)槊看挝覀円獎(jiǎng)?chuàng)建新目標(biāo)時(shí),我們都會遍歷屏幕的幾乎每個(gè)像素。如果這個(gè)函數(shù)會減慢你的游戲速度,只需注釋掉你有 for 循環(huán)的行并使用以下代碼來代替

        possible_x = range(target_radius + border_size, width -        
        target_radius - border_size)

        possible_y = range(target_radius + border_size, height - target_radius - border_size)

        這將產(chǎn)生相同的影響,除了我們不再有創(chuàng)建遠(yuǎn)離當(dāng)前目標(biāo)的新目標(biāo)的限制。

        有了這段代碼,游戲就完成了!你現(xiàn)在可以不停地玩游戲。但當(dāng)然,我們會改進(jìn)它。

        可以改進(jìn)這款游戲的眾多方法之一是賦予它一種感覺或緊迫感?;旧?,我們需要一種方法來激勵(lì)玩家盡快達(dá)到目標(biāo)。一個(gè)很好的方法是添加一個(gè)計(jì)時(shí)器。

        為了使用計(jì)時(shí)器,我們首先必須有一種方法來跟蹤經(jīng)過的時(shí)間。我們可以通過time庫做到這一點(diǎn)

        import time

        t_start = time.time()
        while True:
            elapsed_time = time.time() - t_start
            print(elapsed_time)

        這應(yīng)該輸出我們自循環(huán)開始以來經(jīng)過的時(shí)間。有了這個(gè),我們現(xiàn)在可以限制玩家玩游戲的時(shí)間,迫使玩家盡可能快地獲得更好的分?jǐn)?shù)。我們還需要一種方法讓玩家知道他打得有多好,所以我們將在圖像中添加一條消息,使用函數(shù)cv2.putText()顯示得分

        if elapsed_time >= max_time:
            is_playing = False
            final_message = "Time's up! You hit " + str(target_count) + " targets in " + str(max_time) + " seconds"
            frame = cv2.putText(frame, final_message, object_title_pos, cv2.FONT_HERSHEY_DUPLEX, 1, (00255), 2)

        我還添加了標(biāo)志is_playing以在計(jì)時(shí)器結(jié)束后阻止目標(biāo)出現(xiàn)。現(xiàn)在我們可以玩游戲并嘗試每次提高我們的分?jǐn)?shù),我們甚至可以與其他人競爭!

        我們還可以用兩種不同的方式玩我們的游戲。事實(shí)上,現(xiàn)在我們已經(jīng)設(shè)置了運(yùn)行時(shí)間的游戲,但我們也可以讓游戲運(yùn)行目標(biāo)。我的意思是,與其嘗試在給定時(shí)間內(nèi)擊中盡可能多的目標(biāo),我們可以看到我們可以多快擊中給定數(shù)量的目標(biāo)。

        我們只需要添加一些東西,即控制我們正在玩的游戲類型的變量,我們還需要一種方法來檢查目標(biāo)計(jì)數(shù)何時(shí)達(dá)到最大值

        play_for_time = True
        play_for_targets = not play_for_time
        ...
        while True:
            if hit_target:
                target_count += 1
                target = create_random_target(target.coordinates)
                if play_for_time and target_count == max_targets:
                    is_playing = False
                    final_message = "Congrats! You hit " + str(target_count) + " targets in " + "{:.2f}".format(elapsed_time) + " seconds"

        現(xiàn)在我們可以用兩種不同的方式玩我們的游戲了!

        第 4 步:最后潤色

        我們現(xiàn)在擁有的游戲非?;A(chǔ),有無數(shù)種方法可以改進(jìn)它,但是在本節(jié)中,我將與你分享一些我也實(shí)現(xiàn)的其他功能。

        保存/加載高分

        不必記住上次獲得的分?jǐn)?shù),你可以創(chuàng)建一個(gè)讀取(和寫入)當(dāng)前高分的方法。

        為此,我們需要兩個(gè)函數(shù)來加載和保存我們的高分

        import pickle
        def load_highscore(is_time):
            try:
                if is_time:
                    with open('high_score_time.dat''rb'as file:
                        score = pickle.load(file)
                else:
                    with open('high_score_targets.dat''rb'as file:
                        score = pickle.load(file)
            except:
                score = 0
            return score


        def save_highscore(score, is_time):
            if is_time:
                with open('high_score_time.dat''wb'as file:
                    pickle.dump(score, file)
            else:
                with open('high_score_targets.dat''wb'as file:
                    pickle.dump(score, file)

        我們正在使用pickle將當(dāng)前的高分保存并加載到文件中。要將其合并到我們當(dāng)前的代碼中,我們只需要檢查我們得到的當(dāng)前分?jǐn)?shù)是否比我們的高分更好,如果是,則更新高分

        highscore_targets = load_highscore(False)
        while True:
            if hit_target:
                target_count += 1
                target = create_random_target(target.coordinates)
                if play_for_time and target_count == max_targets:
                    is_playing = False
                    final_message = "Congrats! You hit " + str(target_count) + " targets in " + "{:.2f}".format(elapsed_time) + " seconds"
                if target_count > highscore_targets or highscore_targets==0:
                    save_highscore(target_count, False)
                    highscore_message = "New highscore!!"
                else:
                     highscore_message = "Best score: " + str(highscore_targets)

        添加當(dāng)前時(shí)間和分?jǐn)?shù)

        現(xiàn)在我們無法知道我們擊中了多少個(gè)目標(biāo),或者我們玩了多長時(shí)間,所以為了解決這個(gè)問題,我們可以在頂部角落添加兩個(gè)文本框來顯示當(dāng)前目標(biāo)計(jì)數(shù)和當(dāng)前時(shí)間

        score_text_pos = (width - 150, border_size + 30)
        time_text_pos = (border_size + 15, border_size + 30)
        while True:
            ...
            frame = cv2.putText(frame, "Total: " + str(target_count), score_text_pos, cv2.FONT_HERSHEY_DUPLEX, 1, (00255), 2)
            frame = cv2.putText(frame, "Time left: " + "{:.2f}".format(elapsed_time), time_text_pos,               cv2.FONT_HERSHEY_DUPLEX, 1, (00255), 2)

        添加邊框

        最后,我之前提到過border_size這個(gè)變量,這個(gè)變量表示我們希望邊框的像素?cái)?shù)。我們可以使用函數(shù)cv2.copyMakeBorder()創(chuàng)建邊框

        while True:
            frame = cv2.copyMakeBorder(frame, border_size, border_size, border_size, border_size, cv2.BORDER_CONSTANT,                       value=[000])

        GitHub 存儲庫上提供的文件還有更多功能:https://github.com/Goncalo-Chambel/ReactionGame

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

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

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

        交流群


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


        瀏覽 198
        10點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評論
        圖片
        表情
        推薦
        10點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            操屌视频| 91人妻人人澡人人爽精品 | 小泬BBBBBB免费看 | 黄色一级A片老女人 | 激情大尺度戏份 | 欧美精品第五页 | 天天综合网天天综合 | 曰逼视频 | 亚洲精品777 | 一区二区三区四区无码 |