|
本教程视频直播回看:
1.快速上手
- 准备3399pro开发板一块,USB摄像头一个,键盘,鼠标,显示屏
- 连接USB摄像头到3399pro开发板,连接鼠标键盘,接通电源
- 获取Chinese-number-gestures-recognition源码
- git clone [url]https://github.com/tz28/Chinese-number-gestures-recognition.git
- 解压附件到Chinese-number-gestures-recognition目录
- cd Chinese-number-gestures-recognition/rknn_test
- python3 rknn_transfer.py将TensorFlow的pb模型转换为rknn模型
- python3 rknn_camera.py 读取摄像头的输入并进行测试
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
- from rknn.api import RKNN
- INPUT_SIZE = 64
- if __name__ == '__main__':
- # 创建RKNN执行对象
- rknn = RKNN()
- #初始化RKNN运行环境,指定host=’rk3399pro’,后续的操作将会运行在NPU上
- print('--> Init runtime environment')
- ret = rknn.init_runtime(host='rk3399pro')
- if ret != 0:
- print('Init runtime environment failed')
- exit(ret)
- print('done')
- # 配置模型输入,用于NPU对数据输入的预处理
- # channel_mean_value='0 0 0 255',那么模型推理时,将会对RGB数据做如下转换
- # (R - 0)/255, (G - 0)/255, (B - 0)/255。推理时,RKNN模型会自动做均值和归一化处理
- # reorder_channel=’0 1 2’用于指定是否调整RBG顺序,设置成0 1 2即按输入的RGB顺序不做调整
- # reorder_channel=’2 1 0’表示交换0和2通道,如果输入是RGB,将会被调整为BGR。如果是BGR将会被
- # 调整为RGB
- rknn.config(channel_mean_value='0 0 0 255', reorder_channel='0 1 2')
- # 加载TensorFlow模型
- # tf_pb='../digital_gesture_recognition/model_2500/digital_gesture.pb'指定待转换的TensorFlow模型
- # inputs指定模型中的输入节点
- # outputs指定模型中输出节点
- # input_size_list指定模型输入的大小
- print('--> Loading model')
- rknn.load_tensorflow(tf_pb='../digital_gesture_recognition/model_2500/digital_gesture.pb',
- inputs=['input_x'],
- outputs=['probability'],
- input_size_list=[[INPUT_SIZE, INPUT_SIZE, 3]])
- print('done')
- # 创建解析pb模型
- # do_quantization=False指定不进行量化
- # 量化会减小模型的体积和提升运算速度,但是会有精度的丢失
- print('--> Building model')
- rknn.build(do_quantization=False)
- print('done')
- # 导出保存rknn模型文件
- rknn.export_rknn('./digital_gesture.rknn')
- # Release RKNN Context
- rknn.release()
3.2 rknn_picture.py
- import numpy as np
- from PIL import Image
- from rknn.api import RKNN
- # 解析模型的输出,获得概率最大的手势和对应的概率
- def get_predict(probability):
- data = probability[0][0]
- data = data.tolist()
- max_prob = max(data)
- return data.index(max_prob), max_prob;
- def load_model():
- # 创建RKNN对象
- rknn = RKNN()
- # 载入RKNN模型
- print('-->loading model')
- rknn.load_rknn('./digital_gesture.rknn')
- print('loading model done')
- # 初始化RKNN运行环境
- print('--> Init runtime environment')
- ret = rknn.init_runtime(host='rk3399pro')
- if ret != 0:
- print('Init runtime environment failed')
- exit(ret)
- print('done')
- return rknn
- def predict(rknn):
- im = Image.open("../picture/6_7.jpg") # 加载图片
- im = im.resize((64, 64),Image.ANTIALIAS) # 图像缩放到64x64
- mat = np.asarray(im.convert('RGB')) # 转换成RGB格式
- outputs = rknn.inference(inputs=[mat]) # 运行推理,得到推理结果
- pred, prob = get_predict(outputs) # 将推理结果转化为可视信息
- print(prob)
- print(pred)
- if __name__=="__main__":
- rknn = load_model()
- predict(rknn)
3.3 TensorFlow迁移到RKNN
3.3.1 模型的加载
- # tensorflow 模型加载,加载的是pb模型,并且获得pb对应的graph进行使用。
- def load_model():
- with tf.gfile.GFile('./digital_gesture_recognition/model_2500/digital_gesture.pb', "rb") as f: #读取模型数据
- graph_def = tf.GraphDef()
- graph_def.ParseFromString(f.read()) #得到模型中的计算图和数据
- with tf.Graph().as_default() as graph: # 这里的Graph()要有括号,不然会报TypeError
- tf.import_graph_def(graph_def, name="") # 导入模型中的图到现在这个新的计算图中
- return graph
- #RKNN模型加载,需要加载的是pb转换后的rknn模型,并且设置RKNN运行环境即可使用
- def load_model():
- # 创建RKNN对象
- rknn = RKNN()
- # 载入RKNN模型
- print('-->loading model')
- rknn.load_rknn('./digital_gesture.rknn')
- print('loading model done')
- # 初始化RKNN运行环境
- print('--> Init runtime environment')
- ret = rknn.init_runtime(host='rk3399pro')
- if ret != 0:
- print('Init runtime environment failed')
- exit(ret)
- print('done')
- return rknn
3.3.2. 图像的预处理
- # 对于TensorFlow,输入图像数据必须为float32类型,且归一化的(1,64,64,3)形状的矩阵
- im = Image.open("dataset//new_pic//test6.jpg")
- im = im.resize((64, 64),Image.ANTIALIAS) # 图像缩放到64x64
- mat = np.asarray(im.convert('RGB')) # 转成RGB格式,此时数据类型为UINT8
- mat = mat.reshape(1,64,64,3) # TensorFlow需要的是(1,64,64,3)的float32类型数据
- mat = mat / 255. # 数据归一化
- # 对于RKNN,图像的归一化和转float32,已经在模型转换时设置好,推理时会自动完成
- im = Image.open("dataset//new_pic//test6.jpg")
- im = im.resize((64, 64),Image.ANTIALIAS) # 图像缩放到64x64
- mat = np.asarray(im.convert('RGB')) # 转成RGB格式,此时数据类型为UINT8
3.3.3. 模型输入与输出
- # TensorFlow:需要输入(1,64,64,3)且进行归一后之后的float32类型矩阵
- mat = img_to_mat("./picture/0_10.jpg")
- x = graph.get_tensor_by_name("input_x:0") # 输入节点,RKNN转换模型时,input为"input_x"
- outlayer = graph.get_tensor_by_name("outlayer:0") # 输出节点,RKNN转换模型时,output为"outlayer"
- prob = graph.get_tensor_by_name("probability:0") # 输出节点,RKNN转换模型时,output为"probability"
- predict = graph.get_tensor_by_name("predict:0") # 输出节点,RKNN转换模型时,output为"predict"
- # RKNN:需要的输入为(64, 64, 3)的UINT8类型矩阵,归一化和转float在模型转换时已定义好
- # 转换模型时,inputs和outputs列表可以tensor名得到,目前我们output只关心'probability',因此,outputs只设置成 outputs=['probability']
- rknn.load_tensorflow(tf_pb='../digital_gesture_recognition/model_2500/digital_gesture.pb',
- inputs=['input_x'],
- outputs=['probability'],
- input_size_list=[[INPUT_SIZE, INPUT_SIZE, 3]])
3.3.4. 模型的推理
- # Tensorflow使用run进行推理
- with tf.Session(graph=graph) as sess:
- np.set_printoptions(suppress=True)
- out, prob, pred = sess.run([outlayer, prob,predict],feed_dict={x:mat})
- print(out)
- print(prob)
- print(pred)
- # RKNN使用inference进行推理
- outputs = rknn.inference(inputs=[image])
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
|