昇腾Atlas200DevBoard 开发板部署手势识别DNN网络及终端显示

举报
豪气冲霄 发表于 2022/12/21 15:22:38 2022/12/21
【摘要】 本文聚焦于将手势识别DNN网络部署在华为开发板上,采用的开发套件是Atlas200DevBoard 国产昇腾 AL实验板,其主芯片是Ascend310。Ascend310的性能支持模型的推理而非训练。为了产生交互效果,将手势识别的预测结果显示在DOS终端和开发板上,使用了开发板集成好的LED灯,OLED屏和PCA9557数码管作为输出显示。

内容描述

在Atlas板上完成以下有关手势识别的计算机视觉任务:手势识别数字0-5,一个握紧的拳头表示数字0,数字1、2、3、4、5就是手指头竖起来的个数,在完成好手势检测后,将识别的手指头数显示在Atlas板上,具体表现为数码管和OLED屏上显示该数字,并且该数字是多少,LED灯就做多少次灯“呼吸”。灯“呼吸”,是灯一会儿熄灭,一会儿发亮,有规律的闪烁活动。

部署手势识别DNN网络

本文采用的模型是Caffe框架训练的OpenPose 手部关键点检测模型。该模型可以直接部署在开发板上,不需要进行模型的转化,代码和注释说明如下。

   //模型尺寸大小
    int width = cols;//cols是摄像头设置好的一帧画面的宽度
    int height = rows;//rows是摄像头设置好的一帧画面的高度
    float ratio = width / (float)height;//计算长宽比
    int modelHeight = 368;  //由模型输入维度决定
    int modelWidth = int(ratio*modelHeight);
 
    //模型文件
    string model_file = "../model/pose_deploy.prototxt";  //网络模型
    string model_weight = "../model/pose_iter_102000.caffemodel";//网络训练权重
 
    //加载caffe模型
    Net net = readNetFromCaffe(model_file, model_weight);
 
    //将输入图像转成blob形式,也就是进行图像的缩放、归一化
    Mat blob = blobFromImage(src, 1.0 / 255, Size(modelWidth, modelHeight), Scalar(0, 0, 0));
 
    //将图像转换的blob数据输入到网络的第一层“image”层,见deploy.protxt文件
    net.setInput(blob, "image");

模型文件需要自行从网上下载,一个是网络模型文件pose_delay.prototxt,一个是网络权重文件pose_iter_102000.caffemodel。以上部署仅针对输入图像的预处理部分,没有实现输出图像的后处理。

实验步骤

1.按如下图所示进行Atlas板的硬件接线。
图1 硬件连线

2.通电源,配置以太网,使得Atlas板与电脑在同一局域网内。打开DOS窗口,输入账号HwHiAiUser和密码,登录Atlas板。
3.在root用户权限下,给予摄像头外设相应的访问、执行权限:chmod 777 /dev/video0。创建LED灯GPIO相应的管脚文件::echo 500 > /sys/class/gpio/export。并且赋予其中相关文件的访问、执行权限:chmod 777 /sys/class/gpio/gpio500/direction ; chmod 777 /sys/class/gpio/gpio500/value。
4.在主目录下进入即将编译链接的文件目录。在电脑的DOS终端(已经连接了昇腾板)输入cd finger_detect/build,然后执行 cmake …/src/ && make编译工程生成可执行文件。
5.进入 finger_detect/out 目录,执行chmod 755 main && ./main。DOS终端将会输出打印相关的提示。
6.手指摆出任意0-5的数字,然后等待摄像头捕捉画面完毕后观察Led灯的闪烁情况,数码管显示的数字和OLED屏上的数字。
7.重复5的步骤多次,因为有手势预测失败的可能,有可能是实验者手势不标准,21个手部关键点的位置坐标比较存在错误所导致。

实验流程图

主函数设计

int main(int argc, char *argv[]) {

    
    pca9557_init("/dev/i2c-1");
    oled_init();       
        //使用opencv打开视频流
    cv::VideoCapture capture(0);
    if (!capture.isOpened()) {
        cout << "Movie open Error" << endl;
        return ATLAS_ERROR;
    }
    //设置断点以检查是否运行过长时间
    printf("111\n");
    Ledhandler led;
    Led_Init(500,&led); //初始化LED灯
    printf("222\n");
    while(1) {

        pca9557_setnum(0,0,0,0);//数码管初始设置数字0
        
        printf("1\n");
        pca9557_show();//显示数码管的数字
        printf("2\n");
        Led_Low(&led);//将LED灯初始化熄灭
        printf("3\n");
        ColorTurn(TURNOVER_DISPLAY);//OLED屏字体反色显示
        DisplayTurn(NORMAL_COLOR);//OLED屏背景正常显示
        char cc[2];
        cc[0]='0';
        ShowString(20,0,cc,size1206);//OLED屏上设置数字0
        Refresh();//刷新OLED屏的缓冲显示新数字
        printf("333\n");
        cv::Mat frame; 
        printf("When 444 is shown,you can free your finger and wait for the detect result.");
         //读取一帧图片
        if (!capture.read(frame))
        {
            ATLAS_LOG_INFO("Video capture return false");
            break;
        }
        printf("444\n");
        vector<Point>HandKeypoints(nPoints);//定义长度为nPoints,元素是Point类型的向量HandKeypoints
        HandKeypoints_Detect(frame, HandKeypoints);//手部关键点检测
        printf("555\n");
        int count = 0;//保存手势识别的结果
        Handpose_Recognition(HandKeypoints, count);//手势识别,将结果保存在count
        printf("The number of finger:%d\n",count);//DOS终端输出手势识别的结果
        printf("666\n");
        
        pca9557_setnum(count,0,0,0);//数码管显示结果
        pca9557_show();
        printf("777\n");
        
        ColorTurn(TURNOVER_DISPLAY);//OLED屏字体反色显示结果
        DisplayTurn(NORMAL_COLOR);//OLED屏背景正常显示结果
        char str[100];
        sprintf(str,"%d",count);
        ShowString(20,0,str,size1206);
        Refresh();
         //LED做count次灯呼吸
       for(int i=0;i<count;i++){
        Led_High(&led);
        usleep(1000000);
        Led_Low(&led);
        usleep(1000000);
       }
        //程序休眠3秒让实验者进行手势准备
        usleep(3000000);
    }

}

实验结果

1.程序运行开始后,立刻摆手势,如下图所示,我摆的手势是数字2。

2.观察DOS窗口的运行情况,如下图所示,可以看出PAC9557数码管,OLED屏和led灯均已初始化完毕。中途为了检测每个程序语句运行正常,所以加了断点,每行打印一个数字,比如111,222,1,2,3等。当出现如下图所示的最后一行时,表示摄像头已经捕捉到手势照片,便可以把手释放。

3.在等待caffe手势识别模型加载并成功推理的期间内,可以观察到昇腾板的初始化结果,如下图所示,可以看到数码管的第一位显示数字0,OLED屏也显示数字0,同时最左边的LED1熄灭,因此可以判断昇腾板的内设初始化成功。

4.等待大约20秒的时间,返回到DOS窗口检查结果,如下图所示,终端打印出手势识别的运行结果2,说明模型推理无误。

5.快速将拍摄镜头给到昇腾板(因为LED灯只会闪烁2次,每次闪烁只会进行2秒),如下图所示,可以看到数码管显示数字2,OLED屏也显示数字2,十分幸运可以看到LED灯处于明亮状态。

6.再次捕捉昇腾板的画面,如下图所示,可以看到LED灯最终熄灭。

展望

直接在昇腾Atlas板上部署Caffe手部关键点检测模型的弊端是,模型加载时间较长,在实际需求中,很可能就会遇上需要随时加载模型,随时手势识别的场合,这就需要将Caffe模型转化成Atlas板原生态支持的om模型。这就需要事先配置好Configuration源文件,在Atlas板上进行手动的命令输入,以下是给的2个例子是将训练好的Tensorflow网络模型迁移到Atlas板上,仅供参考。
Configuration 源文件的配置示例,文件名为insert_op.cfg。

aipp_op { 
related_input_rank : 0
src_image_size_w : 512
src_image_size_h : 512
crop : false
aipp_mode : static
input_format : RGB888_U8
csc_switch : false
rbuv_swap_switch : true
}

在Atlas板DOS终端手动输入命令进行模型转换示例。pb文件是一种用Tensorflow训练好的表示模型(神经网络)结构的二进制文件。

--input_shape="input_rgb:1,512,512,3"
--input_format=NHWC
--output=human_segmentation
--soc_version=Ascend310
--insert_op_conf=./insert_op.cfg
--framework=3
--model=./human_segmentation.pb”

希望之后的学习能将Caffe模型迁移为Atlas板支持的om模型。(●’◡’●)

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。