AI应用快速上手:姿态检测

9 篇文章 0 订阅
本文详细描述了一种利用高通SnapdragonNeuralProcessingEngineSDK和HRNET模型实现的姿态检测应用,涉及从摄像头捕获图像、预处理、模型推理到后期处理的完整流程,适用于Snapdragon8Gen2系列手机。
摘要由CSDN通过智能技术生成

文章介绍

       姿态检测是通过算法从给定的图像中识别人物的关键点,如检测出人体的眼睛、鼻子、肩膀、手臂、臀部、膝盖等关键点,然后再将各关键点有序连接,形成骨架。本文介绍了基于高通Snapdragon Neural Processing Engine SDK和HRNET模型实现一个姿态检测功能的应用。此应用程序打开相机预览,采集所有帧并将其转换为bitmap位图。位图经过预处理,然后输入给YoloNAS模型来识别人,模型推理后显示人的坐标。当检测出人时,我们处理帧以包含人类的框之内的的所有数据到HRNET模型,然后该模型返回人类姿势的坐标。

该应用的所有源代码都可以在https://github.com/quic/qidk/tree/master/Solutions/VisionSolution4-PoseEstimation上获得。

我们使用Snapdragon® 8 Gen 2 的Android手机验证测试这些代码,实际上这些示例代码在任何支持Snapdragon Neural Processing Engine SDK的手机上都可以运行,一次编写多次部署。

前置条件

  • 在启动Android应用程序之前,请按照提供的链接说明进行设置Qualcomm Neural Processing SDK。Snapdragon Neural Processing Engine SDK: SNPE Setup
  • 下载CocoDataset 2014并将其路径提供给Generate_DLC.ipynb。在两个模型的量化过程中更改变量“dataset_path”。
  • 高通Snapdragon 安卓手机,推荐Snapdragon 8 Gen 2系列手机,可以用于测试应用程序
  • 一台Linux机器

操作步骤:

1. 生成DLC

      使用jupyter运行 GenerateDLC.ipynb。此脚本将生成两个dlc。

  • 生成YoloNAS SSD型号为Quant_YoloNAS_s_320.dlc
  • 生成HRNET模型为HRNET_axis_int8.dlc

2. 代码实现过程

代码架构

demo : 包含演示GIF

app : 包含标准Android应用程序格式的源文件

app\src\main\assets:包含模型二进制文件DLC

app\src\main\java\com\qc\objectdetectionYoloNas:应用程序java源代码

app\src\main\cpp:本机源代码

sdk:包含openCV sdk

相机预览设置

相机预览帧的权限在以下文件中授予:

/app/src/main/AndroidManifest.xml

<uses-permission android:name="android.permission.CAMERA" />

为了使用camera2 API,请添加以下功能

<uses-feature android:name="android.hardware.camera2" />

加载模型

神经网络连接和加载模型的代码片段:

snpe = snpeBuilder.setOutputLayers({})

            .setPerformanceProfile(zdl::DlSystem::PerformanceProfile_t::BURST)

            .setExecutionPriorityHint(

                    zdl::DlSystem::ExecutionPriorityHint_t::HIGH)

            .setRuntimeProcessorOrder(runtimeList)

            .setUseUserSuppliedBuffers(useUserSuppliedBuffers)

            .setPlatformConfig(platformConfig)

            .setInitCacheMode(useCaching)

            .setCPUFallbackMode(true)

            .setUnconsumedTensorsAsOutputs(true) //To get output from two nodes

            .build();  //builds the network

后期处理

这包括为每2100 boxes去获得具有最高置信度的类,并应用“Non-Max Suppression”来删除重叠的boxes。 // Non-Max Suppression-- 非最大抑制即抑制不是极大值的元素,搜索局部的极大值

for(int i =0;i<(2100);i++) 

   {

       int start = i*80;

       int end = (i+1)*80;

       auto it = max_element (BBout_class.begin()+start, BBout_class.begin()+end);

       int index = distance(BBout_class.begin()+start, it);

       std::string classname = classnamemapping[index];

       if(*it>=0.5 )

       {

           int x1 = BBout_boxcoords[i * 4 + 0];

           int y1 = BBout_boxcoords[i * 4 + 1];

           int x2 = BBout_boxcoords[i * 4 + 2];

           int y2 = BBout_boxcoords[i * 4 + 3];

           Boxlist.push_back(BoxCornerEncoding(x1, y1, x2, y2,*it,classname));

       }

   }

   std::vector<BoxCornerEncoding> reslist = NonMaxSuppression(Boxlist,0.20);

然后我们只缩放原始图像的坐标

        float top,bottom,left,right;

        left = reslist[k].y1 * ratio_1;   //y1

        right = reslist[k].y2 * ratio_1;  //y2

        bottom = reslist[k].x1 * ratio_2;  //x1

        top = reslist[k].x2 * ratio_2;   //x2

姿势检测

位图图像作为openCV Mat传递给本机,然后将BGR Mat大小转换为256x192x3。基本图像处理取决于模型所需的输入形状类型,然后将处理后的图像写入应用程序缓冲区。根据我们接收到到框体坐标,我们对图像进行变换,因此只有框体中包含的像素会被点亮,所有其他像素都会变黑。这样做是为了隐藏框架中的任何其他人,因为HRNET被设计为最适合单人使用。

    //Preprocessing

    getcenterscale(img.cols, img.rows, center, scale, bottom, left, top, right); //get center and scale based on Box coordinates

    cv::Mat trans = get_affine_transform(HRNET_model_input_height, HRNET_model_input_width, 0, center, scale);

    cv::Mat model_input(HRNET_model_input_width,HRNET_model_input_height, img.type());

    cv::warpAffine(img, model_input, trans,model_input.size(), cv::INTER_LINEAR);

    cvtColor(model_input, model_input, CV_BGRA2BGR);  //Changing num of channels

    //Writing into buffer for inference

    int lim = model_input.rows*model_input.cols*3;

    float * accumulator = reinterpret_cast<float *> (&dest_buffer[0]);

    for(int idx = 0; idx<lim; ){

        accumulator[idx]= (float) (((model_input.data[idx] / 255.0f) - 0.485f) / 0.229f);

        accumulator[idx+1] = (float) (((model_input.data[idx+1] / 255.0f) - 0.456f) / 0.224f);

        accumulator[idx+2] = (float) (((model_input.data[idx+2] / 255.0f) - 0.406f) / 0.225f);

        idx=idx+3;

}

绘制姿势

Model返回相应的Float张量,从中可以推断出对象的形状及其名称。画布用于为所有已识别的人及其姿势绘制一个矩形。

   for (int i = 0; i < Connections.length; i++) {

                int kpt_a = Connections[i][0];

                int kpt_b = Connections[i][1];

                int x_a = (int) coords[kpt_a][0];

                int y_a = (int) coords[kpt_a][1];

                int x_b = (int) coords[kpt_b][0];

                int y_b = (int) coords[kpt_b][1];

                if ((x_a | y_a) != 0) {

                    canvas.drawCircle(x_a, y_a, 8, mPosepaint);

                    if ((x_b | y_b) != 0) {

                        canvas.drawCircle(x_b, y_b, 8, mPosepaint);

                        canvas.drawLine(x_a, y_a, x_b, y_b, mPosepaint);

                    }

                }

3. 整体执行操作流程

  1. Clone QIDK repo。
  2. 从脚本所在的目录中运行以下脚本,以解析此项目的依赖项。
  • 将把snpe-release.aar文件从$snpe_ROOT复制到Android项目中的“snpe-reease”目录。

Note:如果您使用的是SNPE 2.11或更高版本,请更改resolveDependencies.sh中的以下行。windows版本如果找不到对应文件,可以在LINUX版本获取

From: cp $SNPE_ROOT/android/snpe-release.aar snpe-release

 To : cp $SNPE_ROOT/lib/android/snpe-release.aar snpe-release

  • 下载opencv并粘贴到sdk目录,启用android Java的opencv。

bash resolveDependencies.sh

     3. 运行jupyter notebook GenerateDLC.ipynb为YoloNAS_SSD生成DLC,生成HRNET_axis_int8.DLC。更改dataset_path 为Coco Dataset路径。

  • 此脚本生成所需的dlc并将其粘贴到适当的位置。

     4. gradle sync

     5. 编译项目

     6. 应生成APK文件: app-debug.apk

     7. 使用Snapdragon 8 Gen 2手机安装应用程序(不要在模拟器上运行APK)

     8. 如果未检测到未签名或已签名的DSP runtime,请检查logcat日志中的FastRPC错误。如果由于SELinux权限的原因,可能会无法检测到DSP runtime。请尝试以下命令来设置SELinux权限。

adb disable-verity

adb reboot

adb root

adb remount

adb shell setenforce 0

    9. 安装和测试应用程序: app-debug.apk

adb install -r -t enhancement-debug.apk

    10. 启动应用程序

以下是“Pose Detection Yolo NAS”Android应用程序的基本操作

           1. 首次启动应用程序时,用户需要提供相机权限

           2. 相机将打开,如果屏幕上可以看到有人,就可以看到人物姿态

           3. 用户可以为模型选择合适的run-time,并观察性能差异

演示视频和性能细节如下所示:

作者:戴忠忠(Zhongzhong Dai),高通工程师,

  • 26
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值