Toybrick

人工智能开发系列(1) 中文手势识别例程

 

troy

版主

积分
2346
发表于 2019-1-10 17:51:59    查看: 161827|回复: 68 | [复制链接]    打印 | 显示全部楼层

本教程视频直播回看:


1.快速上手


Project地址:https://github.com/tz28/Chinese-number-gestures-recognition
CSDN博客地址:https://blog.csdn.net/u012328159/article/details/81123018

运行结果如下:


2.概述
一个简单的AI开发sample

Github开源的数字手势识别CNN模型,识别数字0-10十一种手势

类LeNet-5,两个卷积层,两个池化层,一个全连接层,一个Softmax输出层



识别结果



3.RKNN使用解析
Rknn运行相关的源码集中在rknn_test下,目录结构如下所示:

rknn_test/
├── digital_gesture.rknn        //转换之后的rknn模型
├── rknn_camera.py        //使用rknn模型进行对camera数据进行推理运算
├── rknn_picture.py        //使用rknn模型进行对图片数据进行推理运算
└── rknn_transfer.py        //用于将TensorFlow的pb模型转换为rknn模型

3.1 rknn_transfer.py
  1. from rknn.api import RKNN        

  2. INPUT_SIZE = 64

  3. if __name__ == '__main__':
  4.         # 创建RKNN执行对象
  5.         rknn = RKNN()

  6.         #初始化RKNN运行环境,指定host=’rk3399pro’,后续的操作将会运行在NPU上
  7.         print('--> Init runtime environment')
  8.         ret = rknn.init_runtime(host='rk3399pro')
  9.         if ret != 0:
  10.                 print('Init runtime environment failed')
  11.                 exit(ret)
  12.                 print('done')

  13.         # 配置模型输入,用于NPU对数据输入的预处理
  14.         # channel_mean_value='0 0 0 255',那么模型推理时,将会对RGB数据做如下转换
  15.         # (R - 0)/255, (G - 0)/255, (B - 0)/255。推理时,RKNN模型会自动做均值和归一化处理
  16.         # reorder_channel=’0 1 2’用于指定是否调整RBG顺序,设置成0 1 2即按输入的RGB顺序不做调整
  17.         # reorder_channel=’2 1 0’表示交换0和2通道,如果输入是RGB,将会被调整为BGR。如果是BGR将会被
  18.         # 调整为RGB
  19.         rknn.config(channel_mean_value='0 0 0 255', reorder_channel='0 1 2')

  20.         # 加载TensorFlow模型
  21.         # tf_pb='../digital_gesture_recognition/model_2500/digital_gesture.pb'指定待转换的TensorFlow模型
  22.         # inputs指定模型中的输入节点
  23.         # outputs指定模型中输出节点
  24.         # input_size_list指定模型输入的大小
  25.         print('--> Loading model')
  26.         rknn.load_tensorflow(tf_pb='../digital_gesture_recognition/model_2500/digital_gesture.pb',
  27.                                 inputs=['input_x'],
  28.                                 outputs=['probability'],
  29.                                 input_size_list=[[INPUT_SIZE, INPUT_SIZE, 3]])
  30.         print('done')

  31.         # 创建解析pb模型
  32.         # do_quantization=False指定不进行量化
  33.         # 量化会减小模型的体积和提升运算速度,但是会有精度的丢失
  34.         print('--> Building model')
  35.         rknn.build(do_quantization=False)
  36.         print('done')

  37.         # 导出保存rknn模型文件
  38.         rknn.export_rknn('./digital_gesture.rknn')

  39.         # Release RKNN Context
  40.         rknn.release()
复制代码


3.2 rknn_picture.py
  1. import numpy as np
  2. from PIL import Image
  3. from rknn.api import RKNN

  4. # 解析模型的输出,获得概率最大的手势和对应的概率
  5. def get_predict(probability):
  6.         data = probability[0][0]
  7.         data = data.tolist()
  8.         max_prob = max(data)

  9. return data.index(max_prob), max_prob;

  10. def load_model():
  11.         # 创建RKNN对象
  12.         rknn = RKNN()

  13.         # 载入RKNN模型
  14.         print('-->loading model')
  15.         rknn.load_rknn('./digital_gesture.rknn')
  16.         print('loading model done')

  17.         # 初始化RKNN运行环境
  18.         print('--> Init runtime environment')
  19.         ret = rknn.init_runtime(host='rk3399pro')
  20.         if ret != 0:
  21.                 print('Init runtime environment failed')
  22.                 exit(ret)

  23.         print('done')

  24.         return rknn

  25. def predict(rknn):
  26.         im = Image.open("../picture/6_7.jpg")        # 加载图片
  27.         im = im.resize((64, 64),Image.ANTIALIAS)  # 图像缩放到64x64
  28.         mat = np.asarray(im.convert('RGB'))           # 转换成RGB格式
  29.         outputs = rknn.inference(inputs=[mat])      # 运行推理,得到推理结果
  30.         pred, prob = get_predict(outputs)               # 将推理结果转化为可视信息

  31.         print(prob)
  32.         print(pred)

  33. if __name__=="__main__":
  34.         rknn = load_model()
  35.         predict(rknn)
复制代码


3.3 TensorFlow迁移到RKNN
3.3.1 模型的加载
  1. # tensorflow 模型加载,加载的是pb模型,并且获得pb对应的graph进行使用。
  2. def load_model():
  3.         with tf.gfile.GFile('./digital_gesture_recognition/model_2500/digital_gesture.pb', "rb") as f:  #读取模型数据
  4.                 graph_def = tf.GraphDef()
  5.                 graph_def.ParseFromString(f.read())                   #得到模型中的计算图和数据
  6.                 with tf.Graph().as_default() as graph:                 # 这里的Graph()要有括号,不然会报TypeError
  7.                         tf.import_graph_def(graph_def, name="")   # 导入模型中的图到现在这个新的计算图中
  8.                         return graph
复制代码
  1. #RKNN模型加载,需要加载的是pb转换后的rknn模型,并且设置RKNN运行环境即可使用
  2. def load_model():
  3.         # 创建RKNN对象
  4.         rknn = RKNN()

  5.         # 载入RKNN模型
  6.         print('-->loading model')
  7.         rknn.load_rknn('./digital_gesture.rknn')
  8.         print('loading model done')

  9.         # 初始化RKNN运行环境
  10.         print('--> Init runtime  environment')
  11.         ret = rknn.init_runtime(host='rk3399pro')
  12.         if ret != 0:
  13.                 print('Init runtime environment failed')
  14.                 exit(ret)
  15.         print('done')

  16.         return rknn
复制代码


3.3.2. 图像的预处理
  1. # 对于TensorFlow,输入图像数据必须为float32类型,且归一化的(1,64,64,3)形状的矩阵
  2. im = Image.open("dataset//new_pic//test6.jpg")
  3. im = im.resize((64, 64),Image.ANTIALIAS)        # 图像缩放到64x64
  4. mat = np.asarray(im.convert('RGB'))                 # 转成RGB格式,此时数据类型为UINT8
  5. mat = mat.reshape(1,64,64,3)                         # TensorFlow需要的是(1,64,64,3)的float32类型数据
  6. mat = mat / 255.                                            # 数据归一化
复制代码
  1. # 对于RKNN,图像的归一化和转float32,已经在模型转换时设置好,推理时会自动完成
  2. im = Image.open("dataset//new_pic//test6.jpg")
  3. im = im.resize((64, 64),Image.ANTIALIAS)        # 图像缩放到64x64
  4. mat = np.asarray(im.convert('RGB'))                 # 转成RGB格式,此时数据类型为UINT8
复制代码


3.3.3. 模型输入与输出
  1. # TensorFlow:需要输入(1,64,64,3)且进行归一后之后的float32类型矩阵
  2. mat = img_to_mat("./picture/0_10.jpg")
  3. x = graph.get_tensor_by_name("input_x:0")                # 输入节点,RKNN转换模型时,input为"input_x"
  4. outlayer = graph.get_tensor_by_name("outlayer:0")     # 输出节点,RKNN转换模型时,output为"outlayer"
  5. prob = graph.get_tensor_by_name("probability:0")       # 输出节点,RKNN转换模型时,output为"probability"
  6. predict = graph.get_tensor_by_name("predict:0")         # 输出节点,RKNN转换模型时,output为"predict"
复制代码
  1. # RKNN:需要的输入为(64, 64, 3)的UINT8类型矩阵,归一化和转float在模型转换时已定义好
  2. # 转换模型时,inputs和outputs列表可以tensor名得到,目前我们output只关心'probability',因此,outputs只设置成 outputs=['probability']
  3. rknn.load_tensorflow(tf_pb='../digital_gesture_recognition/model_2500/digital_gesture.pb',
  4.                                inputs=['input_x'],
  5.                                outputs=['probability'],
  6.                                input_size_list=[[INPUT_SIZE, INPUT_SIZE, 3]])
复制代码


3.3.4. 模型的推理
  1. # Tensorflow使用run进行推理
  2. with tf.Session(graph=graph) as sess:
  3.         np.set_printoptions(suppress=True)
  4.         out, prob, pred = sess.run([outlayer, prob,predict],feed_dict={x:mat})

  5.         print(out)
  6.         print(prob)
  7.         print(pred)
复制代码
  1. # RKNN使用inference进行推理
  2. outputs = rknn.inference(inputs=[image])
复制代码



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

onepiece

中级会员

积分
256
发表于 2019-1-11 15:29:04 | 显示全部楼层
写的很详细!!!
回复

使用道具 举报

andornot

注册会员

积分
130
发表于 2019-1-11 16:12:11 | 显示全部楼层
回复

使用道具 举报

user_one

新手上路

积分
36
发表于 2019-1-16 09:23:57 | 显示全部楼层

很棒很棒很棒很棒很棒很棒很棒很棒很棒很棒
回复

使用道具 举报

123456

新手上路

积分
17
发表于 2019-1-25 08:54:33 | 显示全部楼层
user_one 发表于 2019-1-16 09:23
很棒很棒很棒很棒很棒很棒很棒很棒很棒很棒

加一+1+1+1+1+1+1
回复

使用道具 举报

administer

中级会员

积分
305
发表于 2019-1-26 17:13:59 | 显示全部楼层
学习学习
回复

使用道具 举报

duckduckgo

新手上路

积分
33
发表于 2019-2-11 01:49:42 | 显示全部楼层
很详细,辛苦了。
回复

使用道具 举报

linuxsky

注册会员

积分
151
发表于 2019-2-16 09:06:32 | 显示全部楼层
请问下这个能做到 几帧呢? 整个任务处理时间
回复

使用道具 举报

someone9388

注册会员

积分
86
发表于 2019-2-21 11:53:22 | 显示全部楼层
[toybrick@localhost rknn_test]$ python3 rknn_transfer.py
/usr/lib64/python3.6/site-packages/h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.
  from ._conv import register_converters as _register_converters
--> Init runtime environment
Traceback (most recent call last):
  File "rknn_transfer.py", line 12, in <module>
    ret = rknn.init_runtime(host='rk3399pro')
TypeError: init_runtime() got an unexpected keyword argument 'host'

遇到一个错误
回复

使用道具 举报

someone9388

注册会员

积分
86
发表于 2019-2-21 12:01:06 | 显示全部楼层
你好 遇到一个错误, 没有HOST 参数名:
[toybrick@localhost rknn_test]$ python3 rknn_transfer.py
/usr/lib64/python3.6/site-packages/h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.
  from ._conv import register_converters as _register_converters
--> Init runtime environment
Traceback (most recent call last):
  File "rknn_transfer.py", line 12, in <module>
    ret = rknn.init_runtime(host='rk3399pro')
TypeError: init_runtime() got an unexpected keyword argument 'host'
麻烦指导解决一下
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

产品中心 购买渠道 开源社区 Wiki教程 资料下载 关于Toybrick


快速回复 返回顶部 返回列表