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>

        使用 OpenCV 的基于標記的增強現(xiàn)實

        共 19335字,需瀏覽 39分鐘

         ·

        2022-12-30 21:53

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

        重磅干貨,第一時間送達

        先決條件

        了解什么是增強現(xiàn)實 (AR)、虛擬現(xiàn)實 (VR) 和混合現(xiàn)實 (MR),Marker-based AR 和 Marker-less AR 之間的區(qū)別:https://arshren.medium.com/all-you-want-to-know-about-augmented-reality-1d5a8cd08977

        基于標記的增強現(xiàn)實

        基于標記的 AR,也稱為圖像識別 AR,使用對象或基準標記作為參考來確定相機的位置或方向。

        基于位置的 AR 通過掃描像 ArUco 標記這樣的標記來工作。ArUco 標記檢測觸發(fā)增強體驗以定位對象、文本、視頻或動畫以顯示在設備上。

        在這個例子中,我們將編寫一個簡單的代碼,借助 ArUco 標記來增強視頻流上的圖像。

        ArUco 標記

        ArUco(Augmented Reality University of Cordoba) 由 S.Garrido-Jurado 等人于 2014 年在他們的工作“自動生成和檢測遮擋下高度可靠的基準標記”(https://www.researchgate.net/publication/260251570_Automatic_generation_and_detection_of_highly_reliable_fiducial_markers_under_occlusion)中開發(fā)。

        ArUco 標記是用于相機姿態(tài)估計的基準方形標記。當在視頻中檢測到 ArUco 標記時,你可以在檢測到的標記上增加數(shù)字內(nèi)容,例如圖像。



        尺寸為 6X6 的 ArUco 標記

        ArUco 標記是一種合成方形標記,內(nèi)部的二進制矩陣包含在帶有唯一標識符的寬黑色邊框內(nèi)。在 ArUco 標記中, 黑色表示1,白色表示0。

        標記大小決定了內(nèi)部二進制矩陣的大小。ArUco 標記中的奇數(shù)塊代表奇偶校驗位,標記中的偶數(shù)方塊代表數(shù)據(jù)位。

        黑色邊框便于在圖像內(nèi)快速檢測,二進制矩陣允許對其進行識別。

        ArUco 標記幫助相機了解角度、高度和深度,并在計算機視覺、機器人和增強現(xiàn)實中得到應用。

        ArUco 標記由預定義的字典組成,涵蓋一系列不同的字典大小和標記大小。要生成 ArUco 標記,你需要指定:

        • 字典大小:是字典中標記的數(shù)量

        • 指示位數(shù)的標記大小

        上面的 ArUco 標記來自 100 個標記的字典,標記大小為 6X6 二進制矩陣。

        此示例將使用計算機的默認攝像頭捕捉視頻,然后從 6x6x100 字典中引入 4 個 ArUco 標記。一旦檢測到 ArUco 標記,就在檢測到的 ArUco 標記上增加圖像。



        在此處閱讀如何使用 OpenCV 讀取、寫入和顯示視頻:https://arshren.medium.com/read-and-write-videos-using-opencv-7f92548afcba

        導入所需的庫

        import numpy as np
        import cv2
        import imutils

        檢測圖像中的 ArUco 標記

        要檢測圖像中的 ArUco 標記,

        1. 分析圖像以找到作為標記候選的正方形形狀。

        2. 檢測到候選后,驗證其內(nèi)部編碼以確保它們是 ArUco 標記。

        在 OpenCV 中,ArUco 標記字典遵循命名約定cv2.aruco.DICT_NxN_M,其中 N 是二進制矩陣的大小,代表標記的大小,M 是字典中 ArUco 標記的數(shù)量。

        要檢測 ArUco 標記,請將 BGR 圖像轉(zhuǎn)換為灰度圖像,以便于檢測。getattr()用于訪問 ArUco 標記中鍵屬性的值以加載 ArUco 字典。

        檢測在detectMarkers()函數(shù)中執(zhí)行,其中輸入?yún)?shù)是包含 ArUco 標記的圖像,ArUco 字典對象,在我們的例子中是 6x6x100 和 DetectorParameters(). detectMarkers()函數(shù)返回四個角的向量、它們的 id 以及檢測到但不符合 ArUco 編碼的任何矩形。

        def findArucoMarkers(img, markerSize = 6, totalMarkers=250, draw=True):
            gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
            key = getattr(cv2.aruco, f'DICT_{markerSize}X{markerSize}_{totalMarkers}')
            
            #Load the dictionary that was used to generate the markers.
            arucoDict = cv2.aruco.Dictionary_get(key)
            
            # Initialize the detector parameters using default values
            arucoParam = cv2.aruco.DetectorParameters_create()
            
            # Detect the markers
            bboxs, ids, rejected = cv2.aruco.detectMarkers(gray, arucoDict, parameters = arucoParam)
            return bboxs, ids

        通過將源圖像疊加在視頻頂部來應用增強現(xiàn)實。

        開始使用計算機的默認攝像頭捕捉視頻,并讀取要疊加在 ArUco 標記上的圖像。

        檢測視頻幀中的 ArUco 標記并找到每個 ArUco 標記的所有四個角的位置。計算視頻幀和將要疊加的圖像之間的單應性。

        單應性是一個圖像中的點到另一圖像中的對應點的變換映射。

        OpenCV 的findHomography()計算圖像和視頻幀點之間的單應性函數(shù) h 以扭曲圖像以適應視頻幀。然后對扭曲的圖像進行屏蔽并復制到視頻幀上。


        import numpy as np
        import cv2
        import imutils

        # function to detect ArUco Markers
        def findArucoMarkers(img, markerSize = 6, totalMarkers=250, draw=True):
            gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
            key = getattr(cv2.aruco, f'DICT_{markerSize}X{markerSize}_{totalMarkers}')
            
            
            #Load the dictionary that was used to generate the markers.
            arucoDict = cv2.aruco.Dictionary_get(key)
            
            # Initialize the detector parameters using default values
            arucoParam = cv2.aruco.DetectorParameters_create()
            
            # Detect the markers
            bboxs, ids, rejected = cv2.aruco.detectMarkers(gray, arucoDict, parameters = arucoParam)
            return bboxs, ids
            
        # Superimposing the image on the aruco markers detected in the video 
        imgH=480
        imgW=640

        video = cv2. VideoCapture(0)

        ret, video_frame=video.read()
        image = cv2.imread(r'nature.png')
        image = cv2.resize(image, (imgH, imgW))

        while(video.isOpened()):
            if ret==True:
                refPts=[]  
                #Detect the Aruco markers on the video frame
                arucofound =findArucoMarkers(video_frame, totalMarkers=100)
                h, w = video_frame.shape[:2]
                
                # if the aruco markers are detected
                if  len(arucofound[0])!=0:
                        
                        for Corner, id in zip(arucofound[0], arucofound[1]):
                            
                            corners = Corner.reshape((42))
                            (topLeft, topRight, bottomRight, bottomLeft) = corners
                            topRight = (int(topRight[0]), int(topRight[1]))
                            bottomRight = (int(bottomRight[0]), int(bottomRight[1]))
                            bottomLeft = (int(bottomLeft[0]), int(bottomLeft[1]))
                            topLeft = (int(topLeft[0]), int(topLeft[1]))
                            # draw lines around the marker and display the marker id
                            cv2.line(video_frame, topLeft, topRight, (02550), 2)
                            cv2.line(video_frame, topRight, bottomRight, (02550), 2)
                            cv2.line(video_frame, bottomRight, bottomLeft, (02550), 2)
                            cv2.line(video_frame, bottomLeft, topLeft, (02550), 2)                    
                            cv2.putText(video_frame, str(id),(topLeft[0], topLeft[1] - 15), cv2.FONT_HERSHEY_SIMPLEX,0.5, (02550), 2)
                            corner = np.squeeze(Corner)
                            refPts.append(corner)
                            
                            # only when all the 4 markes are detected in the image
                            if len(refPts)==4:
                                ( refPtBR, refPtTR,refPtBL, refPtTL) = refPts
                                video_pt = np.array([  refPtTL[3], refPtBL[3],refPtBR[2], refPtTR[3]])
                               
                                # grab the spatial dimensions of the  image and define the
                                # transform matrix for the image in 
                                #top-left, top-right,bottom-right, and bottom-left order
                                image_pt = np.float32([[0,0], [h,0], [h,w], [0,w]])
                                
                                # compute the homography matrix between the image and the video frame
                                matrix, _ = cv2.findHomography( image_pt, video_pt)
                                
                                #warp the  image to video frame based on the homography
                                warped  = cv2.warpPerspective(image, matrix, (video_frame.shape[1], video_frame.shape[0]))
                                
                                #Create a mask representing region to 
                                #copy from the warped image into the video frame.
                                mask = np.zeros((imgH, imgW), dtype="uint8")
                                cv2.fillConvexPoly(mask, video_pt.astype("int32"), (255255255),cv2.LINE_AA)
                                                                            
                                # give the source image a black border
                                # surrounding it when applied to the source image,
                                #you can apply a dilation operation
                                rect = cv2.getStructuringElement(cv2.MORPH_RECT, (33))
                                mask = cv2.dilate(mask, rect, iterations=2)
                                
                                # Copy the mask with the three channel version by stacking it depth-wise,
                                # This will allow copying the warped source image into the input image
                                maskScaled = mask.copy() / 255.0
                                maskScaled = np.dstack([maskScaled] * 3)
                                
                                # Copy the masked warped image into the video frame by
                                # (1) multiplying the warped image and masked together, 
                                # (2) multiplying the Video frame with the mask 
                                # (3) adding the resulting images
                                warpedMultiplied = cv2.multiply(warped.astype("float"), maskScaled)
                                imageMultiplied = cv2.multiply(video_frame.astype(float), 1.0 - maskScaled)
                                #imgout = video frame multipled with mask 
                                #        + warped image multipled with mask
                                output = cv2.add(warpedMultiplied, imageMultiplied)
                                output = output.astype("uint8")
                                cv2.imshow("output", output)
            
            ret, video_frame=video.read()
            key = cv2.waitKey(20)
            # if key q is pressed then break 
            if key == 113:
                break 
            
        #finally destroy/close all open windows
        video.release()
        cv2.destroyAllWindows()

        最終輸出會將圖像映射到視頻中檢測到的 ArUco 標記的頂部。



        使用 ArUco 標記的增強現(xiàn)實

        此處提供代碼:https://github.com/arshren/AR_Aruco

        參考:

        https://docs.opencv.org/4.x/d5/dae/tutorial_aruco_detection.html

        https://machinelearningknowledge.ai/augmented-reality-using-aruco-marker-detection-with-python-opencv/

        https://learnopencv.com/augmented-reality-using-aruco-markers-in-opencv-c-python/



        ☆ END ☆

        好消息!

        小白學視覺知識星球

        開始面向外開放啦??????




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

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

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

        交流群


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


        瀏覽 66
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

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

        手機掃一掃分享

        分享
        舉報
        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>
            国产高清一区二区 | 国产亚洲视频一区 | 男女无遮挡毛片免费视频色大師 | 国产麻豆成人免费视频 | 最新超碰97人人看人人 | 日韩性爱视频网站 | 熟妇日逼| 学生妹毛片| 自拍偷拍2| 久久精品女人天堂avapp下载 |