<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          使用Python+OpenCV+dlib為人臉生成口罩

          共 16461字,需瀏覽 33分鐘

           ·

          2021-01-06 05:08

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

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

          推薦閱讀

          42個(gè)pycharm使用技巧,瞬間從黑鐵變王者

          Google C++項(xiàng)目編程風(fēng)格指南 (中文版) 分享

          轉(zhuǎn)自|深度學(xué)習(xí)與計(jì)算機(jī)視覺
          本文使用OpenCV dlib庫生成口罩
          口罩已經(jīng)被證明是防止COVID-19傳播的最好的防御措施之一,然而,這也導(dǎo)致了基于面部特征(包括鼻子、嘴和下巴線)的面部識別算法的失效。
          在全球有傳染病之前,面部識別系統(tǒng)通過對檢測到的不同面部特征進(jìn)行比較測量來驗(yàn)證兩幅圖像中的人臉。當(dāng)一個(gè)人的鼻子、嘴和臉頰上戴上口罩,大大減少了通常用來識別他/她的身份的信息。
          將需要重新訓(xùn)練或重新設(shè)計(jì)有效的識別系統(tǒng),以識別受管制地區(qū)的口罩臉。為了做到這一點(diǎn),需要一個(gè)大的口罩?jǐn)?shù)據(jù)集來訓(xùn)練深度學(xué)習(xí)模型,以檢測戴口罩的人和不戴口罩的人。
          目前,可用于訓(xùn)練和評估人臉識別系統(tǒng)的圖像數(shù)據(jù)集是有限的。據(jù)報(bào)道,美國國家標(biāo)準(zhǔn)與技術(shù)研究所(NIST)的研究通過將口罩(各種顏色、大小和位置)疊加在沒有帶口罩人臉的圖像上來解決這個(gè)問題。[https://www.cnet.com/news/face-masks-are-thwarting-even-the-best-facial-recognition-algorithms-study-finds/?ftag=COS-05-10aaa0b&TheTime=2020-07-27T22%3A23%3A21&PostType=link&UniqueID=C7330AC8-D057-11EA-8580-DE063A982C1E&ServiceType=twitter]
          這篇文章試圖用OpenCV和dlib庫來實(shí)現(xiàn)這個(gè)過程,在這里我們綜合生成5種類型的口罩來繪制人臉圖像。圖1顯示了生成的5種口罩類型。

          安裝所需的軟件包

          使用Python3.7創(chuàng)建一個(gè)新的虛擬環(huán)境并安裝依賴項(xiàng)。所需的庫如下:
             
          #requirements_facemask.txt
          numpy == 1.18.5
          pip == 20.2.2
          imutils == 0.5.3
          python >=3.7
          dlib == 19.21.0
          cmake == 3.18.0
          opencv-python == 4.4.0
          由于此腳本需要dlib庫,因此在開始運(yùn)行該腳本之前需要安裝dlib,你可以通過以下鏈接了解如何使用Python綁定安裝dlib:https://www.pyimagesearch.com/2017/03/27/how-to-install-dlib/
          Dlib是一個(gè)高級的機(jī)器學(xué)習(xí)庫,它是為解決復(fù)雜的現(xiàn)實(shí)世界問題而創(chuàng)建的。這個(gè)庫是用C++編程語言創(chuàng)建的,它可以使用C/C++、Python和java等語言。

          導(dǎo)入庫

          我們從導(dǎo)入所需的庫開始:OpenCV、dlib、numpy、os和imutils。
             
          # 必要的導(dǎo)入
          import cv2
          import dlib
          import numpy as np
          import os
          import imutils
          下一步是設(shè)置口罩的顏色,并設(shè)置要從中導(dǎo)入圖像的目錄和路徑,OpenCV的顏色空間按BGR順序而不是RGB。
             
          # 設(shè)置目錄
          os.chdir('PATH_TO_DIR')
          path = 'IMAGE_PATH'

          # 初始化顏色 [color_type] = (Blue, Green, Red)
          color_blue = (239,207,137)
          color_cyan = (255,200,0)
          color_black = (000)
          下面的鏈接讓你可以立即從視覺上探索顏色,它可以用于將顏色從十六進(jìn)制轉(zhuǎn)換為RGB,反之亦然:https://www.rgbtohex.net/rgb/

          圖像預(yù)處理

          接下來,我們通過OpenCV加載我們的輸入圖像,然后通過調(diào)整大小使其具有500像素的寬度并將其轉(zhuǎn)換為灰度來預(yù)處理圖像。
             
          # 加載圖像并調(diào)整大小,將其轉(zhuǎn)換為灰度
          img= cv2.imread('image_path')
          img = imutils.resize(img, width = 500)
          gray=cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

          使用dlib、OpenCV和Python檢測和提取人臉關(guān)鍵點(diǎn)

          為了覆蓋口罩,我們需要進(jìn)行人臉檢測,有許多方法可用于執(zhí)行此任務(wù)我們可以使用OpenCV內(nèi)置的Haar Cascade XML文件,甚至TensorFlow或使用Keras。在這篇文章中,我們使用的是dlib的人臉檢測器。
          dlib中的正面人臉檢測器是基于方向梯度直方圖(HOG)和線性SVM的。
          我們使用dlib的正面人臉檢測來首先檢測人臉,然后使用面部標(biāo)志點(diǎn)預(yù)測器dlib.shape_predictor檢測人臉關(guān)鍵點(diǎn)。
          人臉關(guān)鍵點(diǎn)檢測被定義為檢測臉上的關(guān)鍵標(biāo)志點(diǎn)并跟蹤它們(對由于頭部運(yùn)動和面部表情而導(dǎo)致的剛性和非剛性面部變形具有魯棒性)[來源]

          什么是人臉關(guān)鍵點(diǎn)?

          人臉關(guān)鍵點(diǎn)是用于定位和表示面部的顯著區(qū)域,如眼睛、眉毛、鼻子、下顎線、嘴巴等,應(yīng)用于人臉對齊、頭部姿態(tài)估計(jì)、換臉、眨眼檢測、困倦檢測等領(lǐng)域。
          在人臉關(guān)鍵點(diǎn)下,利用形狀預(yù)測方法對人臉上重要的面部結(jié)構(gòu)進(jìn)行檢測是非常必要的。面部標(biāo)志點(diǎn)檢測包括兩個(gè)步驟:
          1. 定位圖像中檢測到的人臉。
          2. 面部關(guān)鍵點(diǎn)的檢測
          如前所述,我們可以通過多種方式執(zhí)行人臉檢測,但每種方法都試圖定位和標(biāo)記以下面部區(qū)域:
          • 鼻子
          • 下顎線
          • 左眼和右眼
          • 左右眉
          在這篇文章中,我們使用了基于深度學(xué)習(xí)的人臉定位算法,該算法還用于圖像中人臉的檢測。我們將通過某種方法獲得面邊界框,其中我們分別使用圖像中人臉的(x,y)坐標(biāo)。一旦人臉區(qū)域被檢測到并被限定,我們進(jìn)入下一步檢測臉部區(qū)域中的關(guān)鍵點(diǎn)。
          我們正在使用的dlib庫中包含的預(yù)訓(xùn)練人臉關(guān)鍵點(diǎn)探測器,這是Kazemi和Sullivan(2014)用回歸樹集合論文實(shí)現(xiàn)的1毫秒人臉對齊算法,其中估計(jì)了映射到人臉結(jié)構(gòu)的68個(gè)(x,y)坐標(biāo)的位置。我們可以使用下圖顯示68個(gè)坐標(biāo)或點(diǎn)的索引:
          從圖3可以通過不同的點(diǎn)集[起點(diǎn),終點(diǎn)]來評估面部特征的位置:
          • 左眼:點(diǎn)[42,47]
          • 嘴:點(diǎn)[48,67]
          • 左眉:點(diǎn)[22,26]
          • 鼻子:點(diǎn)[27,34]
          • 右眉:點(diǎn)[17,21]
          • 右眼:點(diǎn)[36,41]
          • 下顎線:點(diǎn)[0,16]
          請注意,標(biāo)志點(diǎn)從0開始
          dlib人臉關(guān)鍵點(diǎn)檢測器就是在這個(gè)數(shù)據(jù)集上訓(xùn)練的:https://ibug.doc.ic.ac.uk/resources/facial-point-annotations/

          人臉檢測與人臉關(guān)鍵點(diǎn)檢測

          下一步是對dlib的預(yù)訓(xùn)練人臉檢測器進(jìn)行初始化,該檢測器是基于Histogram of Oriented Gradients + Linear SVM method](https://pyimagesearch.com/2014/11/10/histogram-oriented-gradients-object-detection/) 。此檢測器會進(jìn)行圖像中人臉邊界框的檢測。
          檢測器的第一個(gè)參數(shù)是我們的灰度圖像。(此方法也適用于彩色圖像)。
          第二個(gè)參數(shù)是在應(yīng)用檢測器之前對圖像進(jìn)行放大時(shí)要應(yīng)用的圖像金字塔層的數(shù)量。在人臉檢測之前增加輸入圖像的分辨率的好處是可以讓我們在圖像中檢測到更多的人臉,但其缺點(diǎn)是,輸入圖像越大,計(jì)算開銷越大,檢測速度越慢。
          我們還打印出邊界框的坐標(biāo)以及檢測到的人臉數(shù)。我們也可以使用cv2在檢測到的面部周圍使用for循環(huán)繪制邊界框。
             
          # 初始化dlib的人臉檢測器
          detector = dlib.get_frontal_face_detector()

          """
          在灰度圖像中檢測人臉并創(chuàng)建一個(gè)對象-存儲邊界矩形的坐標(biāo)列表
          第二個(gè)參數(shù)中的“1”表示應(yīng)該向上采樣圖像1次。 
          這會使圖像變得更大,并允許我們檢測更多的面孔
          """


          faces = detector(gray, 1)

          # 打印邊界矩形的坐標(biāo)
          print(faces)
          print("Number of faces detected: ", len(faces))

          """
          # 使用for循環(huán)來提取特定坐標(biāo)(x1,x2,y1,y2)
          for face in faces:
            x1 = face.left()
            y1 = face.top()
            x2 = face.right()
            y2 = face.bottom()
            # 在檢測到的臉部周圍畫一個(gè)矩形
            cv2.rectangle(img, (x1,y1), (x2,y2),(0,255,0),3)
          cv2.imshow("image", img)
          cv2.waitKey(0)
          cv2.destroyAllWindows()
          """

          為了檢測人臉關(guān)鍵點(diǎn),我們需要從dlib庫下載人臉關(guān)鍵點(diǎn)預(yù)測器dlib.shape_predictor。
          我們的預(yù)測方法需要一個(gè)名為“shape_predictor_68_face_landmarks.dat”的文件,可從以下鏈接下載文件:http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2
          需要強(qiáng)調(diào)的是,這個(gè)模型文件是專為dlib的HOG人臉檢測器設(shè)計(jì)的,不應(yīng)該用于dlib的基于CNN的人臉檢測器,原因是它期望人臉檢測器的邊界框按照dlib的HOG人臉檢測器的方式對齊。
          當(dāng)與另一個(gè)產(chǎn)生不同對齊框的人臉檢測器(如基于CNN的mmod_human_face_detector.dat )一起使用時(shí),結(jié)果不會很好。
             
          # 文件路徑
          p = "shape_predictor_68_face_landmarks.dat"
          # 初始化dlib的預(yù)測器
          predictor = dlib.shape_predictor(p)

          # 使用預(yù)測器獲取外形

          for face in faces:
              landmarks = predictor(gray, face)

              # for n in range(0,68):
              #     x = landmarks.part(n).x
              #     y = landmarks.part(n).y
              #     img_landmark = cv2.circle(img, (x, y), 4, (0, 0, 255), -1)
          下載檢測器后,我們可以初始化檢測器,以便在輸入圖像中檢測到的每個(gè)人臉上檢測到人臉關(guān)鍵點(diǎn)。
          一旦檢測到人臉關(guān)鍵點(diǎn),我們就可以開始“繪圖”了,通過使用OpenCV中的繪圖功能連接所需的點(diǎn),將口罩覆蓋在臉上:https://docs.opencv.org/master/dc/da5/tutorial_py_drawing_functions.html

          Dlib口罩方法

          下面的步驟包括識別繪制不同類型口罩所需的點(diǎn)。我們復(fù)制的口罩類型由NIST研究報(bào)告附錄A中提到的不同點(diǎn)集定義:https://doi.org/10.6028/NIST.IR.8311。視覺效果見圖。
          我們將通過連接附錄A中定義的標(biāo)志點(diǎn)來定義口罩的形狀。例如,為了形成寬覆蓋和中覆蓋口罩,我們將用29點(diǎn)的標(biāo)志點(diǎn)坐標(biāo)連接(繪制)下顎線[0,16]的標(biāo)志點(diǎn)。
          可以使用OpenCV中橢圓和其他三種規(guī)則形狀函數(shù)繪制口罩輪廓。然后我們可以使用cv2.fillpoly函數(shù)將繪制的口罩填充顏色。
             
          points = []
              for i in range(116):
                  point = [landmarks.part(i).x, landmarks.part(i).y]
                  points.append(point)
              # print(points)

              # 寬,高覆蓋口罩
              mask_a = [((landmarks.part(42).x), (landmarks.part(15).y)),
                        ((landmarks.part(27).x), (landmarks.part(27).y)),
                        ((landmarks.part(39).x), (landmarks.part(1).y))]

              # 寬,中覆蓋口罩
              mask_c = [((landmarks.part(29).x), (landmarks.part(29).y))]

              # 寬、低覆蓋口罩
              mask_e = [((landmarks.part(35).x), (landmarks.part(35).y)),
                        ((landmarks.part(34).x), (landmarks.part(34).y)),
                        ((landmarks.part(33).x), (landmarks.part(33).y)),
                        ((landmarks.part(32).x), (landmarks.part(32).y)),
                        ((landmarks.part(31).x), (landmarks.part(31).y))]

              fmask_a = points + mask_a
              fmask_c = points + mask_c
              fmask_e = points + mask_e

              # mask_type = {1: fmask_a, 2: fmask_c, 3: fmask_e}
              # mask_type[choice2]


              # 使用Python OpenCV - cv2.polylines()方法為[mask_type]繪制口罩輪廓:
              # fmask_a = wide, high coverage mask,
              # fmask_c = wide, medium coverage mask,
              # fmask_e  = wide, low coverage mask

              fmask_a = np.array(fmask_a, dtype=np.int32)
              fmask_c = np.array(fmask_c, dtype=np.int32)
              fmask_e = np.array(fmask_e, dtype=np.int32)

              mask_type = {1: fmask_a, 2: fmask_c, 3: fmask_e}
              mask_type[choice2]


              # 更改參數(shù)[mask_type]和color_type用于各種組合
              img2 = cv2.polylines(img, [mask_type[choice2]], True, choice1, thickness=2, lineType=cv2.LINE_8)

              # 使用Python OpenCV - cv2.fillPoly()方法填充口罩
              # 更改參數(shù)[mask_type]和color_type用于各種組合
              img3 = cv2.fillPoly(img2, [mask_type[choice2]], choice1, lineType=cv2.LINE_AA)

          # cv2.imshow("image with mask outline", img2)
          cv2.imshow("image with mask", img3)

          # 為測試保存輸出文件
          outputNameofImage = "output/imagetest.jpg"
          print("Saving output image to", outputNameofImage)
          cv2.imwrite(outputNameofImage, img3)
             
              points = []
              for i in range(116):
                  point = [landmarks.part(i).x, landmarks.part(i).y]
                  points.append(point)
              # print(points)

              # 橢圓參數(shù)為高,圓形是覆蓋口罩
              top_ellipse = landmarks.part(27).y + (landmarks.part(28).y - landmarks.part(27).y) / 2
              centre_x = landmarks.part(28).x
              centre_y = landmarks.part(8).y - ((landmarks.part(8).y - (top_ellipse)) / 2)
              # 橢圓高度
              axis_major = (landmarks.part(8).y - top_ellipse) / 2
              # 橢圓寬度
              axis_minor = ((landmarks.part(13).x - landmarks.part(3).x) * 0.8) / 2

              centre_x = int(round(centre_x))
              centre_y = int(round(centre_y))
              axis_major = int(round(axis_major))
              axis_minor = int(round(axis_minor))

              centre = (centre_x, centre_y)
              axes = (axis_major, axis_minor)

              # 使用Python OpenCV - cv2.ellipse()方法繪制口罩輪廓
              # 更改最后一個(gè)參數(shù)- line thickness和color_type為各種組合
              img_2 = cv2.ellipse(img, centre, axes, 00360, color_type, thickness=2)



              # 使用Python OpenCV - cv2.ellipse()方法繪制口罩輪廓
              # 更改最后一個(gè)參數(shù)-line thickness為負(fù)數(shù)用于填充,color_type用于各種組合
              img_3 = cv2.ellipse(img, centre, axes, 00360, color_type, thickness=-1)

          # cv2.imshow("image with mask outline", img_2)
          cv2.imshow("image with mask", img_3)
          在圖像檢測開始之前,用戶可以選擇預(yù)先確定口罩的顏色和類型。我們預(yù)先選擇了兩種顏色的口罩-藍(lán)色和黑色
             
          # 使用input()函數(shù)根據(jù)用戶需求獲取口罩類型和口罩顏色
          choice1 = input("Please select the choice of mask color\nEnter 1 for blue\nEnter 2 for black:\n")
          choice1 = int(choice1)

          if choice1 == 1:
              choice1 = color_blue
              print('You selected mask color = blue')
          elif choice1 == 2:
              choice1 = color_black
              print('You selected mask color = black')
          else:
              print("invalid selection, please select again.")
              input("Please select the choice of mask color\nEnter 1 for blue\nEnter 2 for black :\n")


          choice2 = input("Please enter choice of mask type coverage \nEnter 1 for high \nEnter 2 for medium \nEnter 3 for low :\n")
          choice2 = int(choice2)

          if choice2 == 1:
              # choice2 = fmask_a
              print(f'You chosen wide, high coverage mask')
          elif choice2 == 2:
              # choice2 = fmask_c
              print(f'You chosen wide, medium coverage mask')
          elif choice2 == 3:
              # choice2 = fmask_e
              print(f'You chosen wide, low coverage mask')
          else:
              print("invalid selection, please select again.")
              input("Please enter choice of mask type coverage \nEnter 1 for high \nEnter 2 for medium \nEnter 3 for low :\n")

          # print(choice2)

          結(jié)果

          圖5顯示了原始輸入圖像(Barack Obama的圖像)與使用腳本生成了口罩的輸出圖像之間的比較。我們也可以在人群鏡頭使用這個(gè)腳本。如圖6所示,在著名的Ellen's wefie拍攝中,在檢測到的人臉上疊加口罩的結(jié)果。
          我們能夠成功地復(fù)制生成5種不同類型的口罩的過程(詳見附錄A),這些口罩可以使用dlib和OpenCV疊加在未帶口罩的人臉的圖像上。
          圖7到圖9顯示了在不直接看相機(jī)的臉上的更多示例。

          結(jié)論

          該腳本能夠在檢測到的人臉上生成合成口罩臉,輸出圖像可用于測試或驗(yàn)證其他面向應(yīng)用的ML網(wǎng)絡(luò),如室內(nèi)考勤系統(tǒng)的人臉識別、口罩檢測等。
          你可以在這里下載完整代碼:https://github.com/xictus77/face-mask-overlay-with-OpenCV-Dlib.git

          參考文獻(xiàn):

          • Facial landmarks with dlib, OpenCV, and Python(https://www.pyimagesearch.com/2017/04/03/facial-landmarks-dlib-opencv-python/)
          • Facial point annotations(https://ibug.doc.ic.ac.uk/resources/facial-point-annotations/)
          • Real-Time Face Pose Estimation(http://blog.dlib.net/2014/08/real-time-face-pose-estimation.html)
          • Drawing Functions in OpenCV(https://docs.opencv.org/master/dc/da5/tutorial_py_drawing_functions.html)
          • Sources of images — open source and https://www.kaggle.com/dansbecker/5-celebrity-faces-dataset
          下載1:OpenCV-Contrib擴(kuò)展模塊中文版教程
          在「小白學(xué)視覺」公眾號后臺回復(fù):擴(kuò)展模塊中文教程即可下載全網(wǎng)第一份OpenCV擴(kuò)展模塊教程中文版,涵蓋擴(kuò)展模塊安裝、SFM算法、立體視覺、目標(biāo)跟蹤、生物視覺、超分辨率處理等二十多章內(nèi)容。

          下載2:Python視覺實(shí)戰(zhàn)項(xiàng)目31講
          小白學(xué)視覺公眾號后臺回復(fù):Python視覺實(shí)戰(zhàn)項(xiàng)目31講即可下載包括圖像分割、口罩檢測、車道線檢測、車輛計(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)階。

          下載4:leetcode算法開源書
          小白學(xué)視覺公眾號后臺回復(fù):leetcode即可下載。每題都 runtime beats 100% 的開源好書,你值得擁有!





          交流群


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


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

          手機(jī)掃一掃分享

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

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美大码一区二区免费看 | 美女黄频免费 | 色先锋资源网 | 一区二区小视频 | 大鸡吧插嫩逼视频网站免费 |