コンテンツにスキップ

顔98キーポイント認識

修正履歴

NOバージョン修正内容修正日
1Ver1.0新規作成2026/06/30

この文書の情報は、文書を改善するため、事前の通知なく変更されることがあります。最新版は弊社ホームページからご参照ください。

株式会社日昇テクノロジーの書面による許可のない複製は、いかなる形態においても厳重に禁じられています。

1. 顔キーポイント概要

  顔キーポイント位置特定は、顔キーポイント検出または顔アライメントとも呼ばれます。入力された顔画像に対して、眉、目、鼻、口、顔の輪郭など、顔面上の重要領域の位置を推定する処理です。顔検出と同様に、姿勢変化や遮蔽などの影響を受けるため、顔キーポイント検出も難易度の高いタスクです。

顔キーポイント検出には、さまざまな重要な応用シーンがあります。

・顔姿勢アライメント:顔認識などのアルゴリズムでは、モデル精度を向上させるために顔姿勢のアライメントが必要です。

・顔補正・顔編集:キーポイントに基づいて顔型、目の形状、鼻の形状などを正確に解析し、顔の特定部位を加工することで、顔エフェクト、美顔処理、スタンプ貼り付けなどのエンターテインメント機能を実現できます。

・表情解析・唇認識:キーポイントに基づいて顔表情を解析し、インタラクティブエンターテインメントや行動予測などのシーンに使用できます。

本顔98点キーポイントアルゴリズムの、キーポイント位置は次の図に示します:

図1-1 顔98キーポイントのインデックス定義

図1-1 顔98キーポイントのインデックス定義

データセットでのアルゴリズム性能:

顔ランドマークアルゴリズムNME(%)
300W2.78
COFW3.08
AFLW1.42

CSUN RV1126Bでの実行効率:

アルゴリズム種別モデルサイズ実行効率
face_detect44.23MB17ms
face_landmark9810.88MB23ms

2. クイックスタート

2.1 開発環境の準備

  本ドキュメントを初めてお読みになる場合は、『入門ガイド/開発コンパイル環境の準備と更新』を参照し、関連する手順に従ってコンパイル環境をデプロイしてください。

PC側のUbuntuシステムで run スクリプトを実行し、Docker開発環境に入ります。手順は次のとおりです。

Terminal window
cd ~/linuxshare/work/rv1126b/jp/embedded/images/develop_environment
./run.sh 2204

図2-1 Docker開発環境の起動

図2-1 Docker開発環境の起動

2.2 ソースコードのダウンロード

Docker開発環境で、ソースコードリポジトリを保存する管理ディレクトリを作成します。

Terminal window
cd /opt/linuxshare/work/rv1126b/jp/AI/demo/ai-algorithm

gitツールを使用して、管理ディレクトリ内にリモートリポジトリをクローンします。

Terminal window
git clone https://github.com/csunltd/rv1126b-ai-toolkit.git

※GitHubのWebページからダウンロードする場合でも、リポジトリ全体をダウンロードしてください。本サンプルに対応するディレクトリだけを単独でダウンロードしないでください。

※すでにダウンロードした場合、飛ばしてください。

2.3 モデルデプロイ

アルゴリズムDemoを実行するには、まず人体キーポイント認識アルゴリズムモデルをダウンロードする必要があります。

ダウンロードリンク:

顔検出モデル:

https://dl.dragonwake.com/download/rv1126b/AI/demo/01_face-detect.zip

顔キーポイント認識モデル:

https://dl.dragonwake.com/download/rv1126b/AI/demo/11_face_landmark98.zip

その後、ダウンロードした顔検出モデルと人体キーポイント認識モデルを Release/ ディレクトリへコピーしてください。

図2-2 Releaseディレクトリ内のファイル配置

図2-2 Releaseディレクトリ内のファイル配置

2.4 サンプルのビルド

サンプルがあるディレクトリに移動してビルドを実行します。具体的なコマンドは次のとおりです。

Terminal window
cd rv1126b-ai-toolkit/Demos/algorithm-face_landmark98/
Terminal window
./build.sh cpres

* 依存ライブラリは開発ボード上に配置されているため、クロスコンパイル中は /mnt のマウントを保持する必要があります。

Terminal window
sudo mount -t nfs -o vers=3,proto=tcp,mountproto=tcp,nolock,retrans=5,timeo=5 192.168.10.85:/ /mnt

* build.sh スクリプトに cpres パラメータを指定すると、Release/ ディレクトリ内のすべてのリソースが開発ボードへコピーされます。

図2-3 サンプルビルド結果

図2-3 サンプルビルド結果

2.5 サンプル実行および結果

コンパイル済みのものを基板にコピーします。

Terminal window
cp Release/\* /mnt/userdata/Demo/algorithm-face_landmark98/

※./build.sh cpresでコンパイルした場合、自動的にコピーされます。

シリアルデバッグまたはSSHデバッグで開発ボードのバックエンドに入り、次のようにサンプルのデプロイ先へ移動します。

Terminal window
cd /userdata/Demo/algorithm-face_landmark98/

サンプルを実行するコマンドは次のとおりです。

Terminal window
./test-face-landmark98 test.jpg

図2-4 サンプル実行結果

図2-4 サンプル実行結果

Docker開発環境でテスト結果写真を基板からコピーしましょう。

Terminal window
cp /mnt/userdata/Demo/algorithm-face_landmark98/result.jpg .

図2-5 結果画像のコピーコマンド

図2-5 結果画像のコピーコマンド

認識結果は下図通りです。

図2-6 顔98キーポイント認識結果画像

図2-6 顔98キーポイント認識結果画像

APIの詳細説明およびAPI呼び出し(本サンプルのソースコード)については、以下を参照してください。

3. 顔検出API説明

3.1 参照方法

お客様がローカルプロジェクトでEASY EAI APIライブラリを直接呼び出せるようにするため、このリストにはプロジェクトにリンクする必要のあるライブラリとヘッダーファイルが表示されており、ユーザーがそれらを直接追加しやすくなっています。

項目説明
ヘッダファイルディレクトリeasyeai-api/algorithm/face_detect
ライブラリファイルディレクトリeasyeai-api/algorithm/face_detect
ライブラリリンクパラメータ-lface_detect

3.2 顔検出を初期化関数

顔検出を初期化関数プロトタイプは次のとおりです。

int face_detect_init(rknn_context \*ctx, const char \*path)

詳細は次のとおりです。

関数名: face_detect_init()
ヘッダファイルface_detect.h
入力パラメータctx:rknn_contextハンドル
入力パラメータpath:アルゴリズムモデルのパス
戻り値成功時の戻り値:0
失敗時の戻り値:-1
注意事項なし

3.3 顔検出実行関数

顔検出実行関数face_detect_run原型次のとおりです。

int face_detect_run(rknn_context ctx, cv::Mat &input_image, std::vector\<det\> &result)

詳細は次のとおりです。

関数名:face_detect_run()
ヘッダファイルface_detect.h
入力パラメータctx:rknn_contextハンドル
入力パラメータinput_image:画像データ入力(cv::MatはOpenCVの型)
出力パラメータresult:物体検出ボックス出力
戻り値成功時の戻り値:0
失敗時の戻り値:-1
注意事項なし

3.4 顔検出解放関数

顔検出解放関数原型次のとおりです。

int face_detect_release(rknn_context ctx)

詳細は次のとおりです。

関数名:face_detect_release ()

ヘッダファイルface_detect.h
入力パラメータctx:rknn_contextハンドル
戻り値成功時の戻り値:0
失敗時の戻り値:-1
注意事項なし

4. 顔98点ランドマークAPI説明

4.1 参照方法

お客様がローカルプロジェクトからEASY EAI APIライブラリを直接呼び出せるように、本プロジェクトでリンクする必必要がありますがあるライブラリおよびヘッダファイルなどを以下に示します。ユーザーはそのまま追加できます。

項目説明
ヘッダファイルディレクトリeasyeai-api/algorithm_api/face_landmark98
ライブラリファイルディレクトリeasyeai-api/algorithm_api/face_landmark98
ライブラリリンクパラメータ-lface_landmark98

4.2 顔98点ランドマーク初期化関数

设置顔検出を初期化関数プロトタイプ次のとおりです。

int face_landmark98_init(rknn_face_landmark_context_t \*p_face_landmark, const char \*p_model_path)

詳細は次のとおりです。

関数名: face_landmark98_init()
ヘッダファイルface_landmark98.h
入力パラメータp_face_landmark:rknn_face_landmark_context_tハンドル
入力パラメータp_model_path:アルゴリズムモデルのパス
戻り値成功時の戻り値:0
失敗時の戻り値:-1
注意事項なし

4.3 顔98点ランドマーク実行関数

设face_landmark98_run原型次のとおりです。

std::vector\<cv::Point\> face_landmark98_run(cv::Mat image, rknn_face_landmark_context_t \*p_face_landmark)

詳細は次のとおりです。

関数名:face_landmark98_run ()
ヘッダファイルface_landmark98.h
入力パラメータp_face_landmark:rknn_face_landmark_context_tハンドル
入力パラメータimage:画像データ入力(cv::MatはOpenCVの型)
戻り値std::vector<cv::Point>:アルゴリズム出力される顔ランドマーク座標
注意事項なし

4.4 顔98点ランドマーク解放関数

顔98点ランドマーク解放関数原型次のとおりです。

int face_landmark98_release(rknn_face_landmark_context_t\* p_face_landmark)

詳細は次のとおりです。

関数名:face_landmark98_release ()
ヘッダファイルface_landmark98.h
入力パラメータp_face_landmark:rknn_face_landmark_context_tハンドル
戻り値成功時の戻り値:0
失敗時の戻り値:-1
注意事項なし

5. 人体キーポイント認識サンプル

サンプルディレクトリとしてDemos/algorithm-face_landmark98/test-face-landmark98.cpp、操作フロー如以下。

図5-1 顔98キーポイント認識アルゴリズム処理フロー

図5-1 顔98キーポイント認識アルゴリズム処理フロー

参考サンプルは次のとおりです。

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <fstream>
#include <iostream>
#include <vector>
#include <fstream>
#include <atomic>
#include <queue>
#include <thread>
#include <mutex>
#include <chrono>
#include <sys/time.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>
#include <opencv2/opencv.hpp>
#include <unistd.h>
#include <sys/syscall.h>
#include "face_detect.h"
#include "face_landmark98.h"
using namespace std;
using namespace cv;
int main(int argc, char **argv)
{
if( argc != 2) {
printf("./test-face-landmark98 xxx.jpg \n");
return -1;
}
struct timeval start;
struct timeval end;
float time_use=0;
rknn_context detect_ctx;
std::vector<det> result;
int ret;
cv::Mat src;
src = cv::imread(argv[1], 1);
face_detect_init(&detect_ctx, "./face_detect.model");
/* 顔ランドマーク位置推定を初期化します */
rknn_face_landmark_context_t face_landmark;
ret = face_landmark98_init(&face_landmark, "./face_landmark98.model");
if( ret < 0) {
printf("face_mask_judgement_init fail! ret=%d\n", ret);
return -1;
}
gettimeofday(&start,NULL);
face_detect_run(detect_ctx, src, result);
gettimeofday(&end,NULL);
time_use=(end.tv_sec-start.tv_sec)*1000000+(end.tv_usec-start.tv_usec);//マイクロ秒
printf("face_detect time_use is %f\n",time_use/1000);
printf("face num:%d\n", (int)result.size());
for (int i = 0; i < (int)result.size(); i++)
{
int x = (int)(result[i].box.x);
int y = (int)(result[i].box.y);
int w = (int)(result[i].box.width);
int h = (int)(result[i].box.height);
int max = (w > h)?w:h;
// 画像の切り出し範囲が境界を超えていないか確認します
if( (x < 0) || (y < 0) || ((x +max) > src.cols) || ((y +max) > src.rows) ) {
continue;
}
// 顔位置
cv::Rect rect(x, y, w, h);
cv::Mat face_roi =src(rect).clone();
gettimeofday(&start,NULL);
std::vector<cv::Point> keys = face_landmark98_run(&face_landmark, face_roi);
gettimeofday(&end,NULL);
time_use=(end.tv_sec-start.tv_sec)*1000000+(end.tv_usec-start.tv_usec);//マイクロ秒
printf("face_landmark time_use is %f\n",time_use/1000);
// 元画像上の位置
for (int i = 0; i < (int)keys.size(); i++) {
keys[i].x += rect.x;
keys[i].y += rect.y;
}
for (int i = 0; i < (int)keys.size(); i++)
{
printf("keyPoints %d :[%d, %d]\n", i, keys[i].x, keys[i].y);
cv::circle(src, keys[i], 2, CV_RGB(0, 255, 0), 2);
}
//cv::rectangle(src, rect, CV_RGB(0, 255, 0), 2);
}
cv::imwrite("result.jpg", src);
/* 顔検出を解放します */
face_detect_release(detect_ctx);
/* 顔ランドマーク位置推定を解放します */
face_landmark98_release(&face_landmark);
return 0;
}