1.人體關鍵點識別簡介
人體關鍵點識別是一種基于深度學習的對人進行檢測定位與姿勢估計的模型,廣泛應用于體育分析、動物行為監測和機器人等領域,幫助機器實時解讀物理動作。本算法具有運行效率高、實時性強的特點。
本人員檢測算法在數據集表現如下所示:
| 人體關鍵點識別算法 | mAP pose@0.5 |
| Person Pose-S | 86.3 |
| Person Pose-M | 89.3 |
基于EASY-EAI-Orin-Nano(RK3576)硬件主板的運行效率:
| 算法種類 | 運行效率 |
| Person Pose-S | 53ms |
| Person Pose-M | 93ms |
17個人體關鍵點索引定義:
| 索引 | 定義 |
| 0 | 鼻子 |
| 1 | 左眼 |
| 2 | 右眼 |
| 3 | 左耳 |
| 4 | 右耳 |
| 5 | 左肩 |
| 6 | 右肩 |
| 7 | 左肘 |
| 8 | 右肘 |
| 9 | 左腕 |
| 10 | 右腕 |
| 11 | 左髖關節 |
| 12 | 右髖關節 |
| 13 | 左膝 |
| 14 | 右膝 |
| 15 | 左腳踝 |
| 16 | 右腳踝 |
2.快速上手
如果您初次閱讀此文檔,請閱讀:《入門指南/源碼管理及編程介紹/源碼工程管理》,按需管理自己工程源碼(注:此文檔必看,并建議采用【遠程掛載管理】方式,否則有代碼丟失風險!!!)。
2.1開源碼工程下載
先在PC虛擬機定位到nfs服務目錄,再在目錄中創建存放源碼倉庫的管理目錄:
cd ~/nfsroot mkdir GitHub cd GitHub
再通過git工具,在管理目錄內克隆遠程倉庫(需要設備能對外網進行訪問)
git clone https://github.com/EASY-EAI/EASY-EAI-Toolkit-3576.git

注:
* 此處可能會因網絡原因造成卡頓,請耐心等待。
* 如果實在要在gitHub網頁上下載,也要把整個倉庫下載下來,不能單獨下載本實例對應的目錄。
2.2開發環境搭建
通過adb shell進入板卡開發環境,如下圖所示。

通過以下命令,把nfs目錄掛載上nfs服務器。
mount -t nfs -o nolock : /home/orin-nano/Desktop/nfs/

2.3例程編譯
然后定位到板卡的nfs的掛載目錄(按照實際掛載目錄),進入到對應的例程目錄執行編譯操作,具體命令如下所示:
cd EASY-EAI-Toolkit-3576/Demos/algorithm-person_pose/ ./build.sh

2.4模型部署
要完成算法Demo的執行,需要先下載人體關鍵點識別算法模型。
百度網盤鏈接為:https://pan.baidu.com/s/1ln9kclhgl6JqXtOzS3y5PQ?pwd=1234(提取碼:1234)。

同時需要把下載的人體關鍵點識別算法模型復制粘貼到Release/目錄:

2.5例程運行及效果
進入開發板Release目錄,執行下方命令,運行示例程序:
cd Release/ ./test-person_pose person_pose_m.model test.jpg
運行例程命令如下所示:

結果圖片如下所示:

API的詳細說明,以及API的調用(本例程源碼),詳細信息見下方說明。
3.人體關鍵點檢測API說明
- 引用方式
為方便客戶在本地工程中直接調用我們的EASY EAIapi庫,此處列出工程中需要鏈接的庫以及頭文件等,方便用戶直接添加。
選項 | 描述 |
| 頭文件目錄 | easyeai-api/algorithm/person_pose |
| 庫文件目錄 | easyeai-api/algorithm/person_pose |
| 庫鏈接參數 | -lperson_pose |
3.1人體關鍵點識別初始化函數
人體關鍵點識別初始化函數原型如下所示。
int person_pose_init(const char *c, person_pose_context_t *p_person_pose, int cls_num)
具體介紹如下所示。
| 函數名:person_pose_init() | |
| 頭文件 | person_pose.h |
| 輸入參數 | p_model_path:算法模型的路 |
| 輸入參數 | p_person_pose:算法的句柄 |
| 輸入參數 | cls_num:類別數 |
| 返回值 | 成功返回:0 |
| 失敗返回:-1 | |
| 注意事項 | 無 |
3.2人體關鍵點識別運行函數
人體關鍵點識別運行函數person_pose_run原型如下所示。
std::vector person_pose_run(cv::Mat image, person_pose_context_t *p_person_pose, float nms_threshold, float conf_threshold);
具體介紹如下所示。
| 函數名:person_pose_run() | |
| 頭文件 | person_pose.h |
| 輸入參數 | image:圖像數據輸入(cv::Mat是Opencv的類型) |
| 輸入參數 | p_person_pose:算法的句柄 |
| 輸入參數 | nms_threshold:NMS閾值 |
| 輸入參數 | conf_threshold:置信度閾值 |
| 返回值 | std::vector:person pose檢測結果 |
| 注意事項 | 無 |
3.3人體關鍵點識別釋放函數
人體關鍵點識別釋放函數原型如下所示。
int person_pose_release(person_pose_context_t* p_person_pose)
具體介紹如下所示。
| 函數名:person_pose_release() | |
| 頭文件 | person_pose.h |
| 輸入參數 | p_person_pose:算法句柄 |
| 返回值 | 成功返回:0 |
| 失敗返回:-1 | |
| 注意事項 | 無 |
4.人體關鍵識別算法例程
例程目錄為Demos/algorithm-person_pose/test-person_pose.cpp,操作流程如下。

參考例程如下所示。
#include #include #include #include #include "person_pose.h" #include // 畫線 cv::Mat draw_line(cv::Mat image, float *key1, float *key2, cv::Scalar color) { if (key1[2] > 0.1 && key2[2] > 0.1) { cv::Point pt1(key1[0], key1[1]); cv::Point pt2(key2[0], key2[1]); cv::circle(image, pt1, 2, color, 2); cv::circle(image, pt2, 2, color, 2); cv::line(image, pt1, pt2, color, 2); } return image; } // 繪制結果: // 0鼻子, 1左眼, 2右眼,3左耳,4右耳,5左肩,6右肩,7左肘,8右肘,9左腕,10右腕,11左髖關節,12右髖關節,13左膝,14右膝,15左腳踝,16右腳踝 cv::Mat draw_image(cv::Mat image, std::vector results) { long unsigned int i =0; for (i = 0; i < results.size(); i++) { // 繪制臉部 image = draw_line(image, results[i].keypoints[0], results[i].keypoints[1], CV_RGB(0, 255, 0)); image = draw_line(image, results[i].keypoints[0], results[i].keypoints[2], CV_RGB(0, 255, 0)); image = draw_line(image, results[i].keypoints[1], results[i].keypoints[3], CV_RGB(0, 255, 0)); image = draw_line(image, results[i].keypoints[2], results[i].keypoints[4], CV_RGB(0, 255, 0)); image = draw_line(image, results[i].keypoints[3], results[i].keypoints[5], CV_RGB(0, 255, 0)); image = draw_line(image, results[i].keypoints[4], results[i].keypoints[6], CV_RGB(0, 255, 0)); // 繪制上半身 image = draw_line(image, results[i].keypoints[5], results[i].keypoints[6], CV_RGB(0, 0, 255)); image = draw_line(image, results[i].keypoints[5], results[i].keypoints[7], CV_RGB(0, 0, 255)); image = draw_line(image, results[i].keypoints[7], results[i].keypoints[9], CV_RGB(0, 0, 255)); image = draw_line(image, results[i].keypoints[6], results[i].keypoints[8], CV_RGB(0, 0, 255)); image = draw_line(image, results[i].keypoints[8], results[i].keypoints[10], CV_RGB(0, 0, 255)); image = draw_line(image, results[i].keypoints[5], results[i].keypoints[11], CV_RGB(0, 0, 255)); image = draw_line(image, results[i].keypoints[6], results[i].keypoints[12], CV_RGB(0, 0, 255)); image = draw_line(image, results[i].keypoints[11], results[i].keypoints[12], CV_RGB(0, 0, 255)); // 繪制下半身 image = draw_line(image, results[i].keypoints[11], results[i].keypoints[13], CV_RGB(255, 255, 0)); image = draw_line(image, results[i].keypoints[13], results[i].keypoints[15], CV_RGB(255, 255, 0)); image = draw_line(image, results[i].keypoints[12], results[i].keypoints[14], CV_RGB(255, 255, 0)); image = draw_line(image, results[i].keypoints[14], results[i].keypoints[16], CV_RGB(255, 255, 0)); cv::Rect rect(results[i].left, results[i].top, (results[i].right - results[i].left), (results[i].bottom - results[i].top)); cv::rectangle(image, rect, CV_RGB(255, 0, 0), 2); } return image; } /// 主函數 int main(int argc, char **argv) { if (argc != 3) { printf("%s \n", argv[0]); return -1; } const char *p_model_path = argv[1]; const char *p_img_path = argv[2]; printf("Model path = %s, image path = %s\n\n", p_model_path, p_img_path); cv::Mat image = cv::imread(p_img_path); printf("Image size = (%d, %d)\n", image.rows, image.cols); int ret; person_pose_context_t yolo11_pose; memset(&yolo11_pose, 0, sizeof(yolo11_pose)); person_pose_init(p_model_path, &yolo11_pose, 1); double start_time = static_cast(cv::getTickCount()); std::vector results = person_pose_run(image, &yolo11_pose, 0.35, 0.35); double end_time = static_cast(cv::getTickCount()); double time_elapsed = (end_time - start_time) / cv::getTickFrequency() * 1000; std::cout << "person pose run time: " << time_elapsed << " ms" << std::endl; // 繪制結果 image = draw_image(image, results); cv::imwrite("result.jpg", image); printf("Detect size = %ld\n", results.size()); ret = person_pose_release(&yolo11_pose); return ret; }
-
算法
+關注
關注
23文章
4764瀏覽量
97310 -
人工智能
+關注
關注
1813文章
49806瀏覽量
262195 -
rk3576
+關注
關注
1文章
230瀏覽量
1395
發布評論請先 登錄

瑞芯微RK3576人體關鍵點識別算法(骨骼點)
評論