如何在Movidius计算棒上运行手写数字识别Keras模型

如何在Movidius计算棒上运行手写数字识别Keras模型 [原文来自:www.ii77.com]


[好文分享:www.ii77.com]

国内鲜有基于Movidius的教程,国外开源的项目也寥寥无几,本教程结合了一些国外优秀的教程和自己的一些实践经历。我想通过这个教程帮助大家尽可能快速上手使用Movidius。


在本教程中我会向您展示..简单的MNIST Keras模型并将其部署到树莓派+Movidius中。需要的材料有movidius + 树莓派或其他ubuntu电脑 + 摄像头(树莓派官方的摄像头和usb的均可)同时你还需要在树莓派上安装好Movidius ncsdk,有机会我会再写一个专门介绍movidius安装的教程。


有几个步骤

1.在Keras训练模型(TensorFlow后端)

2.在Keras中保存模型文件和权重

3.将Keras模型转换为TensorFlow

4.将TensorFlow模型编译为NCS graph  (不知道graph是啥的请百度tensorflow的文档)

5.在NCS上部署并运行graph


我使用的..是up board(ubuntu)+神经计算棒+摄像头,均可以在爱板商城购买到

如何在Movidius计算棒上运行手写数字识别Keras模型


01

什么是Keras?

如何在Movidius计算棒上运行手写数字识别Keras模型


在keras中文wiki里面介绍了Keras是一个高层神经网络API,Keras由纯Python编写而成并基Tensorflow、Theano以及CNTK后端。


Keras 为支持快速实验而生,能够把你的idea迅速转换为结果,如果你有如下需求,请选择Keras:

• 简易和快速的原型设计(keras具有高度模块化,极简,和可扩充特性)

• 支持CNN和RNN,或二者的结合

• 无缝CPU和GPU切换


简而言之,Keras就是简单易上手的神经网络,将Tensorflow、Theano以及CNTK等作为后端,将复杂的APi简单化,方便小白上手,小伙伴们可以百度keras中文文档进行学习,当然也可以你看我给大家的英文原版书籍,我会上传到附件,英文书籍正好可以练练阅读能力,学人工智能,英语阅读能力少不了的。


02

..与输出模型

了解了Keras的基本使用后,再来看看如何..Keras的模型的。


直接上..与输出部分的代码,这部分在电脑上运行,windows和linux均可

from keras import layers, models

from keras.models import load_model

from keras.datasets import mnist

from keras.utils import to_categorical

from keras import backend as K

import tensorflow as tf


(x_train, y_train), (x_test, y_test) = mnist.load_data()

正确训练完后控制台打印如下

如何在Movidius计算棒上运行手写数字识别Keras模型


并且应该有三个文件生成

如何在Movidius计算棒上运行手写数字识别Keras模型


03

将Keras转变为TensorFlow模型

查看Movidius官网的WIki,由于Movidius NCSDK2仅编译TensorFlow或Caffe模型。现在tensorflow正好官方支持了树莓派..,那就使用tensorflow来做吧。


from keras.models import model_from_json

from keras import backend as K

import tensorflow as tf


model_file = "model.json"

weights_file = "weights.h5"


with open(model_file, "r") as file:

    config = file.read()


K.set_learning_phase(0)

model = model_from_json(config)

model.load_weights(weights_file)


saver = tf.train.Saver()

sess = K.get_session()

saver.save(sess, "./TF_Model/tf_model")


fw = tf.summary.FileWriter('logs', sess.graph)

fw.close()

如何在Movidius计算棒上运行手写数字识别Keras模型


我们关闭学习阶段,然后从我们先前保存的两个单独文件以标准Keras方式加载模型。


通过调用 K.get_session() 从使用基于TensorFlow后端的 Keras,将提供默认的TensorFlow  session 。您甚至可以调用 sess.graph.get_operations()进一步了解TensorFlow graph中的内容 它将返回一列模型中TensorFlow操作。这对于查找计算棒不支持的操作非常有用,众所周知,movidius的限制还是太多,希望国产的角峰鸟可以解决一些限制。最后,TensorFlow Saver类将模型保存到指定路径中的四个文件中。


每个文件都有不同的用途

1.checkpoint定义模型检查点路径,在我们的例子中是“tf_model”。

2..meta存储图形结构,

3..data存储图中每个变量的值

4..index标识检查点。


04

使用mvNCCompile编译TensorFlow模型

在装有ncsdk的树莓派或主机上,使用mvNCCompile。mvNCCompile命令行工具自带NCSDK2工具包,可以转换来自Caffe或Tensorflow网络到graph,也就是可由Movidius计算棒使用的文件。我们将' conv2d_1_input '作为输入节点,将' dense_2 / Softmax '作为输出节点。一行命令即可在当前目录生成名为”graph“的文件。

mvNCCompile TF_Model / tf_model.meta -in = conv2d_1_input -on = dense_2 / Softmax


05

部署graph并进行预测

from mvnc import mvncapi as mvnc

# 获取计算棒的设备名

devices = mvnc.enumerate_devices()

dev = mvnc.Device(devices[0])

# 从文件中读取已编译的网络图(为图形文件正确设置graph_filepath)

with open("graph", mode='rb') as f:

    graphFileBuff = f.read()


graph = mvnc.Graph('graph1')


# 在设备上分配图形并创建输入和输出

in_fifo, out_fifo = graph.allocate_with_fifos(dev, graphFileBuff)


# 将输入写入input_fifo缓冲区并在一次调用中对推理进行排队

graph.queue_inference_with_fifo_elem(in_fifo, out_fifo, input_img.astype('float32'), 'user object')


# 将结果读取到输出Fifo

output, userobj = out_fifo.read_elem()

print('Predicted:',output.argmax())


06

使用Raspberry Pi上的摄像头实时图像进行预测

训练MNIST模型以识别28×28分辨率的灰度图像的手写数字,所以必需转换摄像头捕获的图像,下面是一些预处理步骤。

1. 裁剪图像的中心区域

2. 使用边缘检测找到图像的边缘,此步骤也可以将图像转换为灰度

3. 扩大边缘,使边缘更厚,以填充两个紧密平行边缘之间的区域。

4. 将图像大小调整为28 x 28


对于每个捕获的帧,我们将其传递给图像预处理函数,然后输入NCS graph,该graph返回最终的预测概率。从那里,我们将最终预测的结果呈现为在显示器上显示的图像上。


图像处理过程的代码片段如下

import numpy as np

import cv2

class ImageProcessor:

    """

    A singleton class for ImageProcessor

    """


    p1 = 90

    p2 = 30

    ROI_ratio = 0.2

    label_text_color = (0, 120, 0)

    min_score_percent = 60


    def __new__(cls, min_score_percent=60):

        if not hasattr(cls, 'instance'):

            cls.instance = super(ImageProcessor, cls).__new__(cls)

        return cls.instance


    def __init__(self, min_score_percent=60):

        self.min_score_percent = min_score_percent

    def preprocess_image(self, input_image):

        self.sz = input_image.shape

        self.cx = self.sz[0]//2

        self.cy = self.sz[1]//2

        self.ROI = int(self.sz[0]*self.ROI_ratio)

        edges = cv2.Canny(input_image,self.p1,self.p2)

        cropped = edges[self.cx-self.ROI:self.cx+self.ROI,self.cy-self.ROI:self.cy+self.ROI]

        kernel = np.ones((4,4),np.uint8)

        cropped = cv2.dilate(cropped,kernel,iterations = 2)

        cropped_input = cv2.resize(cropped,(28,28)) / 255.0

        cv2.rectangle(input_image, (self.cy-self.ROI, self.cx-self.ROI), (self.cy+self.ROI, self.cx+self.ROI),(255,255,0), 5)

        return cropped_input, cropped

    def postprocess_image(self, input_image, percentage, label_text, cropped=None):

        if cropped is not None:

            cropped = np.stack((cropped,)*3, -1)

            input_image[-cropped.shape[0]:, -cropped.shape[1]:] = cropped

        if percentage >= self.min_score_percent:

            cv2.putText(input_image, label_text, (self.cy-self.ROI - 1, self.cx-self.ROI - 1),cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 255), 2)

        else:

            cv2.putText(input_image, '?', (self.cy-self.ROI - 1, self.cx-self.ROI - 1),cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 255), 2)



下面就是重头戏使用movidius ncs进行摄像头拍摄识别

#!/usr/bin/env python3

from mvnc import mvncapi as mvnc

import numpy as np

from ImageProcessor import ImageProcessor

import cv2


cv_window_name = "predict-mnist"

CAMERA_INDEX = 0

REQUEST_CAMERA_WIDTH = 640

REQUEST_CAMERA_HEIGHT = 480


def handle_keys(raw_key):

    global processor

    ascii_code = raw_key & 0xFF

    if ((ascii_code == ord('q')) or (ascii_code == ord('Q'))):

        return False

    elif (ascii_code == ord('w')):

        processor.p1 +=10

        print('processor.p1:' + str(processor.p1))

    elif (ascii_code == ord('s')):

        processor.p1 -=10

        print('processor.p1:' + str(processor.p1))

    elif (ascii_code == ord('a')):

        processor.p2 +=10

        print('processor.p2:' + str(processor.p2))

    elif (ascii_code == ord('d')):

        processor.p2 -=10

        print('processor.p1:' + str(processor.p2))

    return True

processor = ImageProcessor()

# 检测有没有连接上计算棒

devices = mvnc.enumerate_devices()

if len(devices) == 0:

    print('No devices found')

    quit()


dev = mvnc.Device(devices[0])


# 尝试打开设备。 如果其他进程已经打开它,这将报异常

try:

    dev.open()

except:

    print("Error - Could not open NCS device.")

    quit()


# 从文件中读取已编译的graph

with open("graph", mode='rb') as f:

    graphFileBuff = f.read()


graph = mvnc.Graph('graph1')


# 在设备上分配graph并创建输入和输出Fifos

in_fifo, out_fifo = graph.allocate_with_fifos(dev, graphFileBuff)

cv2.namedWindow(cv_window_name)

cv2.moveWindow(cv_window_name, 10,  10)


cap = cv2.VideoCapture(CAMERA_INDEX)

cap.set(cv2.CAP_PROP_FRAME_WIDTH, REQUEST_CAMERA_WIDTH)

cap.set(cv2.CAP_PROP_FRAME_HEIGHT, REQUEST_CAMERA_HEIGHT)


actual_frame_width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)

actual_frame_height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)

print ('actual video resolution: ' + str(actual_frame_width) + ' x ' + str(actual_frame_height))


if ((cap == None) or (not cap.isOpened())):

    print ('Could not open camera.  Make sure it is plugged in.')

    print ('Also, if you installed python opencv via pip or pip3 you')

    print ('need to uninstall it and install from source with -D WITH_V4L=ON')

    print ('Use the provided script: install-opencv-from_source.sh')

    exit_app = True

    exit()

exit_app = False

while(True):

    ret, input_image = cap.read()


    if (not ret):

        print("No image from from video device, exiting")

        break


    # 程序自检,看看检测窗口可被叉掉了

    prop_val = cv2.getWindowProperty(cv_window_name, cv2.WND_PROP_ASPECT_RATIO)

    if (prop_val < 0.0):

        exit_app = True

        break

    cropped_input, cropped = processor.preprocess_image(input_image)

    # 将输入写入input_fifo缓冲区并在一次调用中对推理进行排队

    graph.queue_inference_with_fifo_elem(in_fifo, out_fifo, cropped_input.astype('float32'), 'user object')

    # 将结果读取到输出Fifo

    output, userobj = out_fifo.read_elem()

    predict_label = output.argmax()

    percentage = int(output[predict_label] * 100)

    label_text = str(predict_label) + " (" + str(percentage) + "%)"

    print('Predicted:',label_text)

    processor.postprocess_image(input_image, percentage, label_text, cropped)

    cv2.imshow(cv_window_name, input_image)

    raw_key = cv2.waitKey(1)

    if (raw_key != -1):

        if (handle_keys(raw_key) == False):

            exit_app = True

            break

cap.release()

# 取消分配并清除fifo和图形,关闭设备

try:

    in_fifo.destroy()

    out_fifo.destroy()

    graph.destroy()

    dev.close()

    dev.destroy()

except:

    print("Error - could not close/destroy Graph/NCS device.")

    quit()


下面是实际运行的照片:

如何在Movidius计算棒上运行手写数字识别Keras模型


小广告


文中所使用的计算棒

在爱板商城有售哟

如何在Movidius计算棒上运行手写数字识别Keras模型

热门文章

  1. 脚手架扣件种类及规格(脚手架扣件种类及规格型号)2024-05-03
  2. 中国象棋下载到桌面(中国象棋下载到桌面打不开)2024-05-03
  3. 真武大帝和玉皇大帝谁的地位高(真武大帝与玉皇大帝谁大)2024-05-03
  4. 雪走(雪莲果的功效和作用)2024-05-03
  5. “泥”好,自然——托一班家长进课堂活动2024-05-03
  6. 铁甲小宝主题曲叫什么(铁甲小宝主题曲中文叫什么)2024-05-03
  7. 特大暴雨是指24小时降水量超过多少毫米(特大暴雨是指24小时降水量超过多少毫米米)2024-05-03
  8. 熊耀华(熊耀华多大)2024-05-03
  9. 小影记相册制作电脑版下载(小影记怎么没有了)2024-05-03
  10. 90后男子久坐突发“肺梗”,继心梗、脑梗之后又一沉默杀手2024-05-03
  11. 可与言而不与之言失人大意是什么(可与言而不与之言,失人;不可言而与之言,失言翻译)2024-05-03
  12. 面由心生是什么意思(通过面相能看出什么样的人吗)2024-05-03
  13. 【为中国式现代化挺膺担当——青春年少好读书】电影艺术系学生会开展“以书入心,与智同行”读书分享活动2024-05-03
  14. 桃红又是一年春——莱西市第六届王家庄油桃节盛大开幕!2024-05-03
  15. 正盐是什么概念(正盐百科)2024-05-03
  16. 燃气灶自动熄火维修实例(燃气灶熄火保护装置图片)2024-05-03
  17. 云教室(云教室教学管理软件)2024-05-03
  18. 查贵琴:温水煮青蛙,变革中的危机与机遇2024-05-03
  19. 潘多拉的盒子寓意(潘多拉的盒子寓意和象征)2024-05-03
  20. 新法速递丨中华人民共和国学位法2024-05-03
自媒体 微信号:ii77 扫描二维码关注公众号
爱八卦,爱爆料。

小编推荐

  1. 1 主人因找狗不慎掉进深坑,一回头……狗竟然也在!

    9月3号,重庆璧山的一位主人深夜遛狗时发生搞笑一幕。

  2. 2 竟被富婆往XX里塞螺丝钉.....难道是钢丝球玩腻了???

    哈哈哈哈惊恐了

  3. 3 母女双飞简直太太太太刺激了!

    前后左右自拍教学你难道不兴奋吗?这可是工具箱诶!! 毫不犹豫他不是一个合格的微商实物与图片严重不符

  4. 4 开心一刻|拿到新生点名册,老师默默翻开了字典

    据说最近电影《碟中谍6》口碑最好里面的打戏可以说是非常形象了▽生活本尊亲自下场 感谢这些网友 如果没有工作,

  5. 5 超酷暗黑风格游戏主题页设计!

    超酷游戏界面设计

  6. 6 新生儿摄影不简单!

    儿童摄影微刊,一个真正可以学到摄影知识的大平台!添加微信号:sheyingweikan

  7. 7 被爆出这位人妻“恋上”蔡徐坤,她老公的眼神说明了一切

    想必真爱粉应该能猜的出来这是谁了吧~Bingo!就是你们的坤坤啦~~~大家对于坤坤的深刻印象应该就是偶像练习

  8. 8 袁咏仪:女人要学会花男人的钱

    女人真正的独立,不应该是“我只花我自己的钱”,而是“我敢于花你的钱,我也有能力给你花钱”。

  9. 9 男人最不喜欢的六种女人!不会有你吧?

    一、大手大脚,不懂得管理家庭经济收入与支出。无论是男人还是女人,一个家庭有一个人大手大脚都可能会有被生活所迫

  10. 10 这幅神图,红了一千年

    当今世上,有这样一副传世“神图”,拥有着一种一千年都不曾改变的神奇魅力。既不是山水花鸟人物,也不是水墨重彩。

本文内容来自网友供稿,如有信息侵犯了您的权益,请联系反馈核实

Copyright 2024.爱妻自媒体,让大家了解更多图文资讯!