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

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

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

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

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

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

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

結(jié)果圖片如下所示:

API的詳細說明,以及API的調(diào)用(本例程源碼),詳細信息見下方說明。
3.人體關(guān)鍵點檢測API說明
- 引用方式
為方便客戶在本地工程中直接調(diào)用我們的EASY EAIapi庫,此處列出工程中需要鏈接的庫以及頭文件等,方便用戶直接添加。
選項 | 描述 |
| 頭文件目錄 | easyeai-api/algorithm/person_pose |
| 庫文件目錄 | easyeai-api/algorithm/person_pose |
| 庫鏈接參數(shù) | -lperson_pose |
3.1人體關(guān)鍵點識別初始化函數(shù)
人體關(guān)鍵點識別初始化函數(shù)原型如下所示。
int person_pose_init(const char *c, person_pose_context_t *p_person_pose, int cls_num)
具體介紹如下所示。
| 函數(shù)名:person_pose_init() | |
| 頭文件 | person_pose.h |
| 輸入?yún)?shù) | p_model_path:算法模型的路 |
| 輸入?yún)?shù) | p_person_pose:算法的句柄 |
| 輸入?yún)?shù) | cls_num:類別數(shù) |
| 返回值 | 成功返回:0 |
| 失敗返回:-1 | |
| 注意事項 | 無 |
3.2人體關(guān)鍵點識別運行函數(shù)
人體關(guān)鍵點識別運行函數(shù)person_pose_run原型如下所示。
std::vector person_pose_run(cv::Mat image, person_pose_context_t *p_person_pose, float nms_threshold, float conf_threshold);
具體介紹如下所示。
| 函數(shù)名:person_pose_run() | |
| 頭文件 | person_pose.h |
| 輸入?yún)?shù) | image:圖像數(shù)據(jù)輸入(cv::Mat是Opencv的類型) |
| 輸入?yún)?shù) | p_person_pose:算法的句柄 |
| 輸入?yún)?shù) | nms_threshold:NMS閾值 |
| 輸入?yún)?shù) | conf_threshold:置信度閾值 |
| 返回值 | std::vector:person pose檢測結(jié)果 |
| 注意事項 | 無 |
3.3人體關(guān)鍵點識別釋放函數(shù)
人體關(guān)鍵點識別釋放函數(shù)原型如下所示。
int person_pose_release(person_pose_context_t* p_person_pose)
具體介紹如下所示。
| 函數(shù)名:person_pose_release() | |
| 頭文件 | person_pose.h |
| 輸入?yún)?shù) | p_person_pose:算法句柄 |
| 返回值 | 成功返回:0 |
| 失敗返回:-1 | |
| 注意事項 | 無 |
4.人體關(guān)鍵識別算法例程
例程目錄為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; } // 繪制結(jié)果: // 0鼻子, 1左眼, 2右眼,3左耳,4右耳,5左肩,6右肩,7左肘,8右肘,9左腕,10右腕,11左髖關(guān)節(jié),12右髖關(guān)節(jié),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; } /// 主函數(shù) 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; // 繪制結(jié)果 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; }
-
算法
+關(guān)注
關(guān)注
23文章
4790瀏覽量
98423 -
人工智能
+關(guān)注
關(guān)注
1819文章
50231瀏覽量
266606 -
rk3576
+關(guān)注
關(guān)注
1文章
286瀏覽量
1660
發(fā)布評論請先 登錄
瑞芯微RK3588與RK3576技術(shù)參數(shù)詳解
米爾瑞芯微RK3576實測輕松搞定三屏八攝像頭
國產(chǎn)開發(fā)板的端側(cè)AI測評-基于米爾瑞芯微RK3576
適配多種系統(tǒng),米爾瑞芯微RK3576核心板解鎖多樣化應(yīng)用
Onenet云網(wǎng)關(guān)方案應(yīng)用--基于米爾瑞芯微RK3576開發(fā)板
單板挑戰(zhàn)4路YOLOv8!米爾瑞芯微RK3576開發(fā)板性能實測
RK3576機器人核心:三屏異顯+八路攝像頭,重塑機器人交互與感知
如何精準驅(qū)動菜品識別模型--基于米爾瑞芯微RK3576邊緣計算盒
怎樣使用Rock-X SDK對人體骨骼點關(guān)鍵點進行開發(fā)獲取呢
瑞芯微RK3576與RK3576S有什么區(qū)別,性能參數(shù)配置與型號差異解析
瑞芯微RK3576人體關(guān)鍵點識別算法(骨骼點)
評論