ML5.face

def setup
  createCanvas(320, 240)
  @video = createCapture(VIDEO)
  @results = []
  @video.elt.onloadeddata = proc {
    # キャンバスに対する縮小率を計算
    # (ロードが完了するまで videoサイズは不定)
    @sx = width / @video.width
    @sy = height / @video.height
    # p @sx, @sy
    ML5.face(@video, @results)
    @video.hide
  }
end

def draw
  background(220)
  image(@video, 0, 0, width, height)

  scale(@sx, @sy) if @sx and @sy   # 検出座標をキャンバスサイズに一致させる
  @results.each do |faces|
    # p faces
    faces.each do |face|
      stroke(255)
      strokeWeight(3)
      noFill
      rect(face._box.x,
           face._box.y,
           face._box.w,
           face._box.h)
      face[:scaledMesh].each do |p|
        fill(0, 255, 0)
        noStroke
        ellipse(p[0], p[1], 3, 3)
      end
    end
  end
end

ml5.jsリファレンス(参考情報)

[ml5.js] Facemesh

概要

カメラ映像からリアルタイムに顔を検出します。

書式

ML5.face(video, results)

引数

引数名内容備考オプションデフォルト値
videoカメラ映像p5.Element
results検出結果をセットする配列後述の備考の記載を参照

戻値

なし

備考

・ML5.faceメソッドは setupメソッドで使用してください。
 その後、カメラ画像に対象が検出されるたびに
 配列「results」にデータがセットされるので、その内容を drawメソッドで処理してください。

・配列「results」には下記のようなデータ構造の検出結果がセットされます。

  [                                            # 検出された人数分の要素(ハッシュ)を持つ配列
    {                                          # 1人目
      faceInViewConfidence: r,                 # 存在確率
      boundingBox: {                           # 境界領域
        topLeft:     [ [232.28, 145.26] ],     #   左上座標
        bottomRight: [ [449.75, 308.36] ],     #   右下座標
      },
      _box: {                                  # 境界領域(boundingBoxの値をもとに設定)
        x: x,                                  #   左上x座標
        y: y,                                  #   左上y座標
        w: w,                                  #   幅
        h: h                                   #   高さ
      }
      mesh: [                                  # ポイント(468ヶ所)
        [x0, y0, z0],
        [x1, y1, z1],
        ...
        ...
        ...
        [x467, y467, z467]
      ],
      scaledMesh: [                            # スケーリング済みポイント(468ヶ所)
        [x0, y0, z0],
        [x1, y1, z1],
        ...
        ...
        ...
        [x467, y467, z467]
      ],
      annotations: {                           # 部位ごとのスケーリング済みポイント
        silhouette: [                          # シルエット (36ヶ所)
          [x0, y0, z0],
          [x1, y2, z3],
          ...
          [x35, y35, z35]
        ],
        lipsUpperOuter:  [                     # 唇 上外側 (11ヶ所)
          [x0, y0, z0],
          [x1, y2, z3],
          ...
          [x10, y10, z10]
        ],
        lipsLowerOuter:  [                     # 唇 下外側 (10ヶ所)
          [x0, y0, z0],
          [x1, y2, z3],
          ...
          [x9, y9, z9]
        ],
        lipsUpperInner: [                      # 唇 上内側 (11ヶ所)
          [x0, y0, z0],
          [x1, y2, z3],
          ...
          [x10, y10, z10]
        ],
        lipsLowerInner: [                      # 唇 下内側 (11ヶ所)
          [x0, y0, z0],
          [x1, y2, z3],
          ...
          [x10, y10, z10]
        ],
        rightEyeUpper0: [                      # 右目 上側0 (7ヶ所)
          [x0, y0, z0],
          [x1, y2, z3],
          ...
          [x6, y6, z6]
        ],
        rightEyeLower0: [                      # 右目 下側0 (9ヶ所)
          [x0, y0, z0],
          [x1, y2, z3],
          ...
          [x8, y8, z8]
        ],
        rightEyeUpper1: [                      # 右目 上側1 (7ヶ所)
          [x0, y0, z0],
          [x1, y2, z3],
          ...
          [x6, y6, z6]
        ],
        rightEyeLower1: [                      # 右目 下側1 (9ヶ所)
          [x0, y0, z0],
          [x1, y2, z3],
          ...
          [x8, y8, z8]
        ],
        rightEyeUpper2: [                      # 右目 上側2 (7ヶ所)
          [x0, y0, z0],
          [x1, y2, z3],
          ...
          [x6, y6, z6]
        ],
        rightEyeLower2: [                      # 右目 下側2 (9ヶ所)
          [x0, y0, z0],
          [x1, y2, z3],
          ...
          [x8, y8, z8]
        ],
        rightEyeLower3:  [                     # 右目 下側3 (9ヶ所)
          [x0, y0, z0],
          [x1, y2, z3],
          ...
          [x8, y8, z8]
        ],
        rightEyebrowUpper: [                   # 右眉 上側 (8ヶ所)
          [x0, y0, z0],
          [x1, y2, z3],
          ...
          [x7, y7, z7]
        ],
        rightEyebrowLower: [                   # 右眉 上側 (6ヶ所)
          [x0, y0, z0],
          [x1, y2, z3],
          ...
          [x5, y5, z5]
        ],
        leftEyeUpper0: [                       # 左目 上側0 (7ヶ所)
          [x0, y0, z0],
          [x1, y2, z3],
          ...
          [x6, y6, z6]
        ],
        leftEyeLower0: [                       # 左目 下側0 (9ヶ所)
          [x0, y0, z0],
          [x1, y2, z3],
          ...
          [x8, y8, z8]
        ],
        leftEyeUpper1: [                       # 左目 上側1 (7ヶ所)
          [x0, y0, z0],
          [x1, y2, z3],
          ...
          [x6, y6, z6]
        ],
        leftEyeLower1: [                       # 左目 下側1 (9ヶ所)
          [x0, y0, z0],
          [x1, y2, z3],
          ...
          [x8, y8, z8]
        ],
        leftEyeUpper2: [                       # 左目 上側2 (7ヶ所)
          [x0, y0, z0],
          [x1, y2, z3],
          ...
          [x6, y6, z6]
        ],
        leftEyeLower2: [                       # 左目 下側2 (9ヶ所)
          [x0, y0, z0],
          [x1, y2, z3],
          ...
          [x8, y8, z8]
        ],
        leftEyeLower3: [                       # 左目 下側3 (9ヶ所)
          [x0, y0, z0],
          [x1, y2, z3],
          ...
          [x8, y8, z8]
        ],
        leftEyebrowUpper: [                    # 左眉 上側 (8ヶ所)
          [x0, y0, z0],
          [x1, y2, z3],
          ...
          [x7, y7, z7]
        ],
        leftEyebrowLower: [                    # 右眉 下側 (6ヶ所)
          [x0, y0, z0],
          [x1, y2, z3],
          ...
          [x5, y5, z5]
        ],
        midwayBetweenEyes: [                   # 両目の間(1ヶ所)
          [x0, y0, z0]
        ],
        noseTip: [                             # 鼻 先端 (1ヶ所)
          [x0, y0, z0]
        ],
        noseBottom: [                          # 鼻 底 (1ヶ所)
          [x0, y0, z0]
        ],
        noseRightCorner: [                     # 鼻 右隅 (1ヶ所)
          [x0, y0, z0]
        ],
        noseLeftCorner: [                      # 鼻 左隅 (1ヶ所)
          [x0, y0, z0]
        ],
        rightCheek: [                          # 右頬 (1ヶ所)
          [x0, y0, z0]
        ],
        leftCheek: [                           # 左頬 (1ヶ所)
          [x0, y0, z0]
        ]
      }
    }
  ]

関連