OpenCVは顔検出と68ポイントの位置決めを実現します

現在、顔の比較が一般的に使用されている機能です。たとえば、タクシーの運転手の顔を運転免許証の写真と比較したり、アクセス制御システムの参加者の顔を顔ライブラリの顔と比較したりします。顔の比較を行うには、まず顔検出を行います。カメラで撮影した写真では、顔の位置を正しく検出して顔を抽出します。

目次

1主預言者

        1.168ポイントキャリブレーションとOpenCV描画ポイント

        1.2コーディングデザインのアイデア

        1.3OpenCV描画機能の概要

2環境の説明

3実験内容

詳細な4つのステップ

        4.1OpenCVが顔検出を実現

        4.2顔の68ポイントの配置


1主預言者

1.168ポイントキャリブレーションとOpenCV描画ポイント

フリーでオープンソースを考慮に入れると、OpenCVはこの機能をうまく実現できます。
ここでは、OpenCVを使用して、適切な顔分類モデルxml:haarcascade_frontalface_alt_tree.xmlを提供します。
同時に、Dlibの公式顔認識予測子「shape_predictor_68_face_landmarks.dat」を使用して68ポイントのキャリブレーションを実行します(画像処理にOpenCVを使用し、顔に68ポイントを描画し、シリアル番号をマークします)。

:OpenCV顔分類モデルxmlおよびDlib顔認識予測子のダウンロードアドレス
https://pan.baidu.com/s/1gZfYupoW9Zo_2lVV524cWA 
抽出コード:w536 

顔の68点位置決めの内容は主に次のとおりです。68点キャリブレーションとOpenCV描画

  • 68ポイントのキャリブレーション:dlibは、顔の68の特徴点を認識できるトレーニング済みモデルを提供します
  • OpenCV描画ポイント:円関数cv2.circle()および出力文字列関数cv2.putText()

1.2コーディングデザインのアイデア

  • 顔認識のためにdlibライブラリを呼び出し、予測子「shape_predictor_68_face_landmarks.dat」を呼び出します
  • 68ポイントのキャリブレーションを実行し、68ポイントの座標を保存します
  • cv2.circleを使用して68ポイントを描画します
  • cv2.putText()関数を使用して、1〜68の数字を描画します

1.3OpenCV描画機能の概要

  1. 円を描くcv2.circle(img、(p1、p2)、r、(255,255,255))
    img画像オブジェクト
    (p1、p2)円の中心座標
    r半径
    (255,255,255) カラー配列
  2. 出力文字cv2.putText(img、 "test"、(p1、p2)、font、4、(255,255,255)、2、cv2、LINE_AA)
    img画像オブジェクト
    "test"  は文字テキストを印刷する必要があります(数字の場合は、 use str()文字に変換
    (p1、p2)座標textOrg
    fontはフォントfontFaceを表します(ここでfont = cv2.FONT_HERSHEY_SIMPLEX)
    4はフォントサイズを表しますfontScale
    (255,255,255)カラーアレイ
    2線幅太さ
    LINE_AA線種line_type;

    約カラー配列:(255,255,255)、(青、緑、赤)、各値は0〜255です。例:青(255,0,0)、紫(255,0,255)

2環境の説明

  • Linux Ubuntu 16.04
  • Python 3.6
  • PyCharm Community2018
  • Opencv-python 3.4.0.12

3実験内容

  1. haarcascade_frontalface_alt_tree.xml顔分類モデルを使用して、顔を検出します。
  2. Dlibの公式顔認識予測子「shape_predictor_68_face_landmarks.dat」を使用して68ポイントのキャリブレーションを行い、OpenCVを使用して画像処理を行い、顔に68ポイントを描画し、シリアル番号をマークします。

詳細な4つのステップ

4.1OpenCVが顔検出を実現

最初に画像を灰色に変換します。OpenCVのcvtColor()を使用して画像の色を変換します。

import cv2  
   
filepath = "/data/opencv12/mv.jpg"  
img = cv2.imread(filepath)  
# 转换灰色,目的是在人脸检测时排除色彩的干扰  
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  
# 显示图像  
cv2.imshow("original", img)  
cv2.imshow("Image", gray)  
cv2.waitKey(0)  
cv2.destroyAllWindows() 

次に、トレーニング分類子を使用して顔を見つけます。OpenCVの顔検出を使用する前に、顔トレーニングモデルが必要です。形式はxmlです。この実験では、OpenCVが提供する適切な顔分類モデルxml:haarcascade_frontalface_alt_tree.xmlを使用します。
Haar機能分類子は、人体のさまざまな部分のHaar機能値を記述するXMLファイルです。人間の顔、目、唇などを含みます。
OpenCVでの顔検出は、detectMultiScale関数を使用します。画像内のすべての顔を検出し、各顔の座標とサイズをベクトル(長方形で表される)で保存できます。

# 加载OpenCV人脸识别分类器  
face_detector = cv.CascadeClassifier("haarcascade_frontalface_alt_tree.xml")  
# 调用函数识别人脸  
faceRects = classifier.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=3, minSize=(32, 32))  

最後に、画像に長方形を描画します。OpenCVのrectangle()を使用して長方形を描画します。

color = (0, 255, 0)    
if len(faceRects):  # 大于0则检测到人脸  
    for faceRect in faceRects:  # 单独框出每一张人脸  
        x, y, w, h = faceRect # x、y表示坐标;w、h表示矩形宽和高  
        # 框出人脸  
        cv2.rectangle(img, (x, y), (x + h, y + w), color, 2)  
        # 左眼  
        cv2.circle(img, (x + w // 4, y + h // 4 + 30), min(w // 8, h // 8),color)  
        #右眼  
        cv2.circle(img, (x + 3 * w // 4, y + h // 4 + 30), min(w // 8, h // 8),color)  
        #嘴巴  
        cv2.rectangle(img, (x + 3 * w // 8, y + 3 * h // 4),(x + 5 * w // 8, y + 7 * h // 8), color)  

OpenCVは、次のように顔検出の完全なコードを実装します。

import cv2  
      
filepath = "/data/opencv12/mv.jpg"  
img = cv2.imread(filepath)    
cv2.imshow("original", img)    
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)    
       
classifier = cv2.CascadeClassifier("/data/opencv12/haarcascade_frontalface_alt_tree.xml")  
faceRects = classifier.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=3, minSize=(32, 32))  
      
color = (0, 255, 0)    
if len(faceRects):    
    for faceRect in faceRects:    
        x, y, w, h = faceRect   
        cv2.rectangle(img, (x, y), (x + h, y + w), color, 2)  
        cv2.circle(img, (x + w // 4, y + h // 4 + 30), min(w // 8, h // 8),color)  
        cv2.circle(img, (x + 3 * w // 4, y + h // 4 + 30), min(w // 8, h // 8),color)  
        cv2.rectangle(img, (x + 3 * w // 8, y + 3 * h // 4),(x + 5 * w // 8, y + 7 * h // 8), color)  
      
cv2.imshow("image", img)    
cv2.waitKey(0)  
cv2.destroyAllWindows()  

OpenCVは、以下に示すような顔検出の実行結果を実現します。

4.2顔の68ポイントの配置

OpenCVを使用して顔検出を実現することに加えて、OpenCVよりも正確な画像顔検出用のDlibライブラリを使用して、68ポイントの顔ポジショニングを実現することもできます。

まず、呼び出す必要のあるライブラリをインポートします。

import dlib                     #人脸识别的库dlib  
from PIL import Image           #图像处理的库PIL   
import numpy as np              #数据处理的库numpy  
import cv2                      #图像处理的库OpenCv  

次に、画像を読み、画像をグレースケールに変換します。

path = "/data/opencv12/mv.jpg"  
img = cv2.imread(path)  
cv2.imshow("original", img)  
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  

次に、トレーニングモデルを読み取ることにより、顔の68の特徴点を検出できます。

# 人脸分类器  
detector = dlib.get_frontal_face_detector()  
# 获取人脸检测器  
predictor = dlib.shape_predictor("/data/opencv12/shape_predictor_68_face_landmarks.dat")  

最後に、顔のすべての検出ポイントをトラバースしてマークを付け、番号1〜68をマークします。

rects = detector(gray, 0)  
for i in range(len(rects)):  
     landmarks = np.matrix([[p.x, p.y] for p in predictor(img, rects[i]).parts()]) # 寻找人脸的68个标定点  
     # 遍历所有点,打印出其坐标,并圈出来,并标注1-68数字  
     for idx, point in enumerate(landmarks):  
         pos = (point[0, 0], point[0, 1])  
         # 利用cv2.circle给每个特征点画一个圈,共68个  
         cv2.circle(img, pos, 3, color=(0, 255, 0))  
         # 利用cv2.putText输出1-68  
         font = cv2.FONT_HERSHEY_SIMPLEX  
         cv2.putText(img, str(idx+1), pos, font, 0.3, (0, 0, 255), 1, cv2.LINE_AA)  

68ポイントの顔の位置決めの完全なコード次のとおりです。

import cv2  
import dlib  
import numpy as np  
path = "/data/opencv12/mv.jpg"  
img = cv2.imread(path)  
cv2.imshow("original", img)  
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  
  
  
detector = dlib.get_frontal_face_detector()  
predictor = dlib.shape_predictor("/data/opencv12/shape_predictor_68_face_landmarks.dat")  
rects = detector(gray, 0)  
for i in range(len(rects)):  
     landmarks = np.matrix([[p.x, p.y] for p in predictor(img, rects[i]).parts()])  
     for idx, point in enumerate(landmarks):  
         pos = (point[0, 0], point[0, 1])  
         cv2.circle(img, pos, 3, color=(0, 255, 0))  
         font = cv2.FONT_HERSHEY_SIMPLEX  
         cv2.putText(img, str(idx+1), pos, font, 0.3, (0, 0, 255), 1, cv2.LINE_AA)  
cv2.imshow("imgdlib", img)  
cv2.waitKey(0)  
cv2.destroyAllWindows() 

68点面位置決め動作結果を以下に示します。
dlibは目、鼻、口などの顔を検出し、68点の画像を下図に示し、顔を正確に特定・検出できることがわかります。


メッセージを残し、学び、一緒にコミュニケーションすることを歓迎します〜

読んでくれてありがとう

終わり

おすすめ

転載: blog.csdn.net/IT_charge/article/details/112329944