深度学习-服务端训练+android客户端物体识别实战(caffe入门教程+mobilenet+ncnn+android)

文章目录

  • 背景
  • 物体识别简介

  • 自动驾驶

    • 淘宝京东使用物体识别技术
    • 公司业务需求
  • 深度学习简介

  • 深度学习的位置

    • 深度学习概念
    • 深度学习优势
  • 深度学习基础知识

  • 感知机

    • 激活函数
    • 多层感知机
    • 卷积神经网络
  • 卷积层 * 池化层

    • 模型训练
  • 前向传播 * 反向传播与参数优化

  • 深度学习服务端框架

  • tensorFlow

    • keras
    • pytorch
    • Caffe/Caffe2.0
  • caffe框架

  • 为何选择caffe

    • caffe环境搭建
    • caffe基础
  • 数据集 模块概要图 solver(prototxt) 执行者配置 神经网络可视化 caffe中的基础概念

  • blobs layer 神经层 net 神经网络 * forward/backward 前向传播/反向传播

* caffe+mnist数据集+lenet
* caffe+cifar10+caffenet
* caffe+cifar10+mobilenet
* caffe+voc2012+vgg(finetune)+ssd(物体检测模型)
  • 轻量级客户端框架-ncnn

  • ncnn简介

    • ncnn+caffe+mobilenet实战
  • ncnn环境搭建 * 模型转化(caffe格式-> ncnn格式)

    • 源码解析
  • 文件目录 执行流程 重点代码 效果展示 其他工程的效果图

  • 相关学习资料

  • 教学视频

    • 开源项目
    • 参考博客

背景

产品以后的发展需要添加更多科技元素,如下:

  • 人脸识别
  • 物体识别
  • 场景识别

以下以物体识别为重点,使用到了深度学习技术,以下我们将逐一展开。
本次分享的重点是深度学习+caffe+ncnn,其余部分将简单的进行带过。
注:本文主要以有监督的学习为主(分类和回归问题),无监督学习不作为分享范围。

物体识别简介

物体识别(俗称Object detection),是近年来兴起的技术,这也是人工智能的首要目标之一。这是一种完全模拟人眼识别的技术,即使在物体旋转、变色、部分展示等的情况下,同样具备优秀的识别效果。
人工智能目标是:

  • 让机器看世界
  • 让机器听世界
  • 让机器独立思考
    在这里插入图片描述

自动驾驶

在驾驶领域中,引入物体识别技术将大大降低交通事故发生的概率。
在这里插入图片描述
在这里插入图片描述

淘宝京东使用物体识别技术

在这里插入图片描述

公司业务需求

近期产品提出物体识别的相应需求,能识别出家长和老师发送图片中的物体,来开展相应的业务。以下是一张海边游玩的照片。
在这里插入图片描述

深度学习简介

深度学习的位置

在这里插入图片描述
深度学习分别属于人工智能和机器学习的一部分。与深度学习相并行的另外一种机器学习方法,被称之为传统的机器学习(例如svm、逻辑回归)。

深度学习概念

人工神经网络是一个分层的有向图,第一层输入节点接受输入的信息,也称为输入层。来自这些点的数值按照它们输出的弧的权重(wn),进行线性加权(得到G),然后再做一次函数变化f(G),赋给第二层的节点Y。
第二层的节点照此将数值向后传递,直到第三层节点,如此一层层传递,直到最后一层,最后一层又被称为输出层。在模式分类时,一个模式(图像、语音、文字等)的特征值(比如坐标),从输入层开始,按照上面的规则和公式一层层向后传递。最后在输出层,哪个节点的数值最大,输入的模式就被分在了哪一类。
------------------引自《数学之美—Google大脑和人工神经网络》

在这里插入图片描述

在这里插入图片描述

深度学习优势

神经网络与传统的机器学习相比:

  • 能支持更复杂的分类边界
  • 非线性表征更加丰富
  • 准确率会随着数据集的增加而突破传统学习的瓶颈
  • 与svm相比,在大数据集上收敛的更快
  • 轻量级神经网络具备高性能的前向传播,方便部署到移动设备
    在这里插入图片描述

在这里插入图片描述

深度学习基础知识

参考:https://www.cnblogs.com/wj-1314/p/9754072.html

感知机

可以简单的理解为是线性分类。假设训练数据集是线性可分的,感知机学习的目标是求得一个能够将训练数据集正实例点和负实例点完全正确分开的分离超平面。
在这里插入图片描述
感知机重点包含以下两点:

  • 线性加权
  • 依靠损失函数进行权重优化

数学公式略,将在其他博文中进行阐述。

感知机的缺陷:只支持线性分类,对于简单的异或问题也不能进行分类。以下是异或问题中最简单的情况,可以看到无论哪一条直线都不能进行完美的分割。
在这里插入图片描述

激活函数

针对于感知机不能表达非线性的问题,激活函数诞生了。

在人工神经网络中,规定神经元函数只能对输入变量(指向他的节点的值)线性组合后的结果进行一次非线性变换。
这次非线性变化成为“激活函数”
----《数学之美》

为了神经网络的通用性,每一层的非线性变化都选择同一类函数。
激活函数包括:

  • relu
  • sigmoid
  • tanh
  • 等等

激活函数参考博客:https://blog.csdn.net/tyhj_sf/article/details/79932893
在这里插入图片描述

多层感知机

多层感知机(MLP,Multilayer Perceptron)也叫人工神经网络(ANN,Artificial Neural Network),除了输入输出层,它中间可以有多个隐层,最简单的MLP只含一个隐层,即三层的结构
在这里插入图片描述

  • 输入层,输入特征数据等加工或者没有加工过的原始数据
  • 隐含层,隐含层可以很多,resnet有128层的,就是说的隐含层
  • 输出层,输出最后的计算结果,很多神经网络里面都把输出层定义为概率值

多层感知机等同于全连接层,信息每向下传递一个神经元,都会产生n*n的计算量(计算量会随着输入的维度增大而变得非常恐怖)

卷积神经网络

卷积神经网络是近年发展起来的,并引起广泛重视的一种高效识别方法,20世纪60年代,Hubel和Wiesel在研究猫脑皮层中用于局部敏感和方向选择的神经元时发现其独特的网络结构可以有效地降低反馈神经网络的复杂性,继而提出了卷积神经网络(Convolutional Neural Networks-简称CNN)

参考资料:https://www.cnblogs.com/wj-1314/p/9754072.html

卷积的原理与人眼观察事物极其相似,过程都是边缘 -> 局部 -> 整体。卷积神经网络的核心就是使用多个局部特征来影响分类结果。
在这里插入图片描述
全连接的计算量非常大。而且是以整体来计算,没有进行有效的特征提取,即使权重最终达到了收敛效果,也不能很好的进行预测。
卷积神经网络则不同,每次卷积完毕后,传入下一层的数据大大降低了维度,而且经过卷积,获得了众多局部特征,后面的层对这些特征数据进行训练,将变得既简单又高效。

卷积层

简单来说,卷积层用于特征提取。
在这里插入图片描述
根据卷积核的滑动,获取到一个新的特征数据(Convolved Feature)。这个特征数据不是那么直观,来看一下实物的效果。
在这里插入图片描述
针对于不同的通道(rgb)进行卷积后,会得到边缘轮廓的图。

池化层

池化层用于降低参数,而降低参数的方法当然是删除参数,保留最有效的参数。

一般我们有最大池化和平均池化。

  • 最大池化是现在使用最多的,可以突出局部特征
  • 平均池化则考虑了所有参数,而计算出了平均值

需要注意的是,池化层一般放在卷积层后面。所以池化层池化的是卷积层的输出。

模型训练

本博客重点关注有监督的训练。在训练之前需要有一批标注好的数据,即训练数据。为了能在训练过程中动态的观测模型的准确率,同样也需要一批标注数据(推荐为训练数据/测试数据比例为4/1)

前向传播

在这里插入图片描述
前向传播,即训练数据在神经网络里从输入层到输出层的方向传播一次,最终得到输出层的输出结果,即在每个分类的概率值。

反向传播与参数优化

用数据语言来表达:假设C为一个成本函数(Cost Function),它表示根据人工神经网络的输出值(分类结果概率)和实际训练数据中的输出值之间的差距。现在,训练人工神经网络的问题就变成了一个最优化的问题,说的通俗点就是数学中的“找最大(最小)值”的问题。解决最优化为题的常用方法是梯度下降法(Gradient Descent)
在这里插入图片描述
注:这里存在一个局部最优解的问题,不过已经被证明:在深度神经网络中,即使收敛过程进入了局部最优,最终结果也与全局最优没有明显差异。

深度学习服务端框架

在这里插入图片描述

tensorFlow

2015年11月谷歌(Google)出品,基于Python和C++编写。GitHub上最热,谷歌搜索最多,使用人数最多(笔者也是其中之一),大多数网上招聘工作描述中也提到了它。由于Google在深度学习领域的巨大影响力和强大的推广能力,TensorFlow一经推出就获得了极大的关注,并迅速成为如今用户最多的深度学习框架。2019年3月已发布最新的TensorFlow2.0 版本。

官方网站:https://www.tensorflow.org/
优点:

  • 自带tensorboard可视化工具,能够让用户实时监控观察训练过程在这里插入图片描述
  • 拥有大量的开发者,有详细的说明文档、可查询资料多
  • 支持多GPU、分布式训练,跨平台运行能力强
  • 具备不局限于深度学习的多种用途,还有支持强化学习和其他算法的工具

缺点:

  • 频繁变动的接口。TensorFlow的接口一直处于快速迭代之中,并且没有很好地考虑向后兼容性,这导致现在许多开源代码已经无法在新版的TensorFlow上运行,同时也间接导致了许多基于TensorFlow的第三方框架出现BUG
  • 接口设计过于晦涩难懂,在设计TensorFlow时,创造了图、会话、命名空间、PlaceHolder等诸多抽象概念,对初学者来说较难上手
  • 运行明显比其他框架速度慢

keras

Keras 于2015年3月首次发布,拥有“为人类而不是机器设计的API”,得到Google的支持。它是一个用于快速构建深度学习原型的高层神经网络库,由纯Python编写而成,以TensorFlow,CNTK,Theano和MXNet为底层引擎,提供简单易用的API接口,能够极大地减少一般应用下用户的工作量。
如果你是深度学习的初学者,想要快速入门,建议从Keras开始。
官方网站:https://keras.io

优点:

  • 更简洁,更简单的API
  • 丰富的教程和可重复使用的代码
  • 更多的部署选项(直接并且通过TensorFlow后端),更简单的模型导出

缺点:

  • 过度封装导致丧失灵活性,导致用户在新增操作或是获取底层的数据信息时过于困难
  • 初学者容易依赖于 Keras 的易使用性而忽略底层原理

pytorch

PyTorch于2016年10月发布,是一款专注于直接处理数组表达式的低级API。 前身是 Torch(一个基于 Lua 语言的深度学习库)。Facebook 人工智能研究院对PyTorch提供了强力支持。 PyTorch 支持动态计算图,为更具数学倾向的用户提供了更低层次的方法和更多的灵活性,目前许多新发表的论文都采用PyTorch作为论文实现的工具,成为学术研究的首选解决方案。

如果你是一名科研工作者,倾向于理解你的模型真正在做什么,那么就考虑选择PyTorch。

官方网站:https://pytorch.org/

Caffe/Caffe2.0

Caffe的全称是Convolutional Architecture for Fast Feature Embedding,它是一个清晰、高效的深度学习框架,于2013年底由加州大学伯克利分校开发,核心语言是C++。它支持命令行、Python和MATLAB接口。Caffe的一个重要特色是可以在不编写代码的情况下训练和部署模型。

具体介绍见下文。

caffe框架

为何选择caffe

我们暂时先选择caffe框架作为分享目标,原因如下:

  • 与ncnn的兼容性好(最重点)
  • 不需要写代码就可以实现训练(可以作为深度学习的突破口)
  • 支持python接口,可以丰富编程化实现
  • 丰富的demo实现等

caffe环境搭建

推荐ubuntu系统,参考博客:https://blog.csdn.net/wangjie5540/article/details/97786182
mac系统也可搭建,参考博客:https://blog.csdn.net/wangjie5540/article/details/99571832

caffe使用了众多的依赖库,再加上caffe年久失修,出现编译兼容问题也不奇怪。推荐大家在ubuntu上进行编译,可以驱动gpu,mac的最新14.14不支持n卡,据说需要降到14.13才可以。

caffe基础

针对于神经网络的模型,caffe设计了对应的概念。并且使用caffe来训练模型的过程非常简单,甚至都不用写一行代码,仅仅改改配置文件也同样能直接开始训练(当然,用python去写训练过程的话,会更加的灵活)。

数据集

  • 原始数据,本文主要针对的是图片数据,可能有不同的格式(image格式、bytes格式、lmdb格式等)
  • 标注数据,监督学习,必须进行标注

caffe倾向于先把数据集转化成lmdb或者hdf5格式,然后输入神经网络进行训练。

模块概要图

在这里插入图片描述
概要:

  • 使用数据构建脚本,构建训练数据和测试数据
  • caffe train命令加载solver的prototxt配置
  • solver配置加载神经网络配置
  • 神经网络对接训练数据和测试数据
  • 成千上万次迭代,最终按照solver中的配置策略,周期性生成权重模型文件

solver(prototxt) 执行者配置

超参数配置文件。
超参数的概念如下:

在机器学习的上下文中,超参数是在开始学习过程之前设置值的参数,而不是通过训练得到的参数数据。通常情况下,需要对超参数进行优化,给学习机选择一组最优超参数,以提高学习的性能和效果

神经网络可视化

http://ethereon.github.io/netscope/#/editor
下面是对lenet的可视化,可以清楚的看到lenet的全貌。

  • mnist数据输入
  • conv1,第一次卷积层
  • pool1,第一池化层
  • conv2,第二次卷积层
  • pool2,第二次池化层
  • ip1,全连接层(即多层感知机)
  • relu1,激活层
  • ip2,全连接层
  • loss,损失层(同时激发bn反向传播操作)
    在这里插入图片描述

caffe中的基础概念

blobs

  • 对待处理数据带一层封装用于在Caffe中通信传递
  • 也为CPU和GPU间提供同步能力
  • 数学上,是一个N维的C风格的存储数组

总的来说,Caffe使用Blob来交流数据,其是Caffe中标准的数组与统一的内存接口,它是多功能的,在不同的应用场景具有不同的含义,如可以是:batches of images, model parameters, and derivatives for optimization等
作者:沤江一流
链接:https://www.jianshu.com/p/0ac09c3ffec0

layer 神经层

layer是caffe神经网络的基本组成单元。layer包括不同的种类:

  • Data,也就是blob的层
  • Convolution,卷积层
  • Pooling,池化层
  • InnerProduct,全连接
  • SoftmaxWithLoss,激活函数+loss层

不同的层次对应了神经网络中的不通过概念。另外,每种类型的层在caffe的源码中有特定的实现,之后会在其他博客中展开讨论,这里不再赘述。

net 神经网络

net是指神经网络定义,可以认为是layer的总和。在python版本编程中会出现net的概念。

forward/backward 前向传播/反向传播

forward和backward在python编程版本中会出现,手动执行会触发一次前向传播或反向传播(python实现的caffe训练最终的本质是在循环中每次手动触发forward函数,重点看一下本博客的caffe+mnist的python实现注释版)。

caffe+mnist数据集+lenet

参考博客:https://blog.csdn.net/wangjie5540/article/details/98615226
python实现mnist(注释版):https://gitee.com/simple_projects/caffe_learning/blob/master/01-learning-lenet-mine.ipynb

caffe+cifar10+caffenet

非常类似mnist数据集,参考:https://blog.csdn.net/wangjie5540/article/details/98615226

caffe+cifar10+mobilenet

参考:https://github.com/shicai/MobileNet-Caffe.git
shicai的mobilenet提供了预训练模型,可以直接进行数据预测。
在这里插入图片描述
大家肯定想,预训练模型没什么意思,要自己训练才来实际。
参考:https://blog.csdn.net/lwplwf/article/details/82415525,可以使用cifar10进行模型训练。
(ps,作者用cpu训练了几天,最终迭代了19w次,最终准确率在70%,没有达到很好的收敛效果。之后准备好gpu的机器,还会再次训练,以观后效)

注:cifar10的数据集进行模型训练的时候,出现mean的概念(即均值,rgb每个通道上的像素的平均值)。这样做的目的是让个像素的值以0为对称点进行均匀分布,训练过程更容易收敛。有两种获取均值的方法:

  • 以数据集为目标,把每个通道上的像素值全部加和,然后求平均(caffe的cifar10就是使用的这种方法)
  • 直接使用均值(128,128,128),简单暴力。(mobilenet+ssd的训练过程中就是这么做的,最终也能收敛)

以上两种方法,暂时没有证实哪个效果最好。

caffe+voc2012+vgg(finetune)+ssd(物体检测模型)

参考:https://github.com/weiliu89/caffe.git
voc的数据集需要在外网下载,时间要好久好久。。我已经把这些数据都下载完毕,上传到云盘。以下是下载地址:https://download.csdn.net/download/wangjie5540/11598810
由于本次是迁移训练,预训练模型是vggnet,还需要下载vggnet,地址是:https://download.csdn.net/download/wangjie5540/11603902

注:博主用cpu训练跑了两天,还没有跑到第一次的快照地点。如果想自己训练的话,就选gpu的机器吧。

轻量级客户端框架-ncnn

ncnn简介

git地址:https://github.com/Tencent/ncnn
ncnn 是一个为手机端极致优化的高性能神经网络前向计算框架。ncnn 从设计之初深刻考虑手机端的部署和使用。无第三方依赖,跨平台,手机端 cpu 的速度快于目前所有已知的开源框架。基于 ncnn,开发者能够将深度学习算法轻松移植到手机端高效执行,开发出人工智能 APP,将 AI 带到你的指尖。ncnn 目前已在腾讯多款应用中使用,如 QQ,Qzone,微信,天天P图等。

支持大部分常用的 CNN 网络

  • Classical CNN: VGG AlexNet GoogleNet Inception …
  • Practical CNN: ResNet DenseNet SENet FPN …
  • Light-weight CNN: SqueezeNet MobileNetV1/V2/V3 ShuffleNetV1/V2 MNasNet …
  • Detection: MTCNN facedetection …
  • Detection: VGG-SSD MobileNet-SSD SqueezeNet-SSD MobileNetV2-SSDLite …
  • Detection: Faster-RCNN R-FCN …
  • Detection: YOLOV2 YOLOV3 MobileNet-YOLOV3 …
  • Segmentation: FCN PSPNet UNet …

ncnn+caffe+mobilenet实战

ncnn环境搭建

先下载release版本的ncnn,我这里现在ncnn-20190611

$ cd <ncnn-root-dir>
$ mkdir -p build-android-armv7
$ cd build-android-armv7$ cmake -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \-DANDROID_ABI="armeabi-v7a" -DANDROID_ARM_NEON=ON \-DANDROID_PLATFORM=android-14 ..# if you want to enable vulkan, platform api version >= android-24 is needed
$ cmake -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \-DANDROID_ABI="armeabi-v7a" -DANDROID_ARM_NEON=ON \-DANDROID_PLATFORM=android-24 -DNCNN_VULKAN=ON ..$ make -j4
$ make installpick build-android-armv7/install folder for further jni usage

编译完成后,生成以下文件
在这里插入图片描述
支持库和头文件供android的arm-v7a使用

模型转化(caffe格式-> ncnn格式)

首先需要编译caffe的环境。
参考:
https://blog.csdn.net/wangjie5540/article/details/97786182
https://blog.csdn.net/wangjie5540/article/details/99571832

源码解析

文件目录

├── README.md
├── app
│   ├── build.gradle // android工程配置
│   ├── proguard-rules.pro // 混淆配置
│   └── src
│       ├── androidTest
│       │   └── java
│       │       └── com
│       │           └── ztjy
│       │               └── ncnndemo
│       │                   └── ExampleInstrumentedTest.java
│       ├── main
│       │   ├── AndroidManifest.xml
│       │   ├── assets
│       │   │   ├── mobilenet_v2.bin // mobilenet权重文件
│       │   │   ├── mobilenet_v2.param.bin // 神经网络参数文件
│       │   │   └── synset.txt // 分类索引文件
│       │   ├── cpp
│       │   │   ├── CMakeLists.txt
│       │   │   ├── include // ncnn的头文件
│       │   │   │   ├── allocator.h
│       │   │   │   ├── benchmark.h
│       │   │   │   ├── blob.h
│       │   │   │   ├── caffe.pb.h
│       │   │   │   ├── command.h
│       │   │   │   ├── cpu.h
│       │   │   │   ├── gpu.h
│       │   │   │   ├── layer.h
│       │   │   │   ├── layer_type.h
│       │   │   │   ├── layer_type_enum.h
│       │   │   │   ├── mat.h
│       │   │   │   ├── mobilenet_v2.id.h
│       │   │   │   ├── mobilenet_v2.mem.h
│       │   │   │   ├── modelbin.h
│       │   │   │   ├── net.h
│       │   │   │   ├── opencv.h
│       │   │   │   ├── option.h
│       │   │   │   ├── paramdict.h
│       │   │   │   ├── pipeline.h
│       │   │   │   └── platform.h
│       │   │   ├── jniLibs
│       │   │   │   └── armeabi-v7a
│       │   │   │       └── libncnn.a // ncnn静态库
│       │   │   └── native-lib.cpp
│       │   ├── java
│       │   │   └── com
│       │   │       └── ztjy
│       │   │           └── ncnndemo
│       │   │               ├── MainActivity.java // 主窗体
│       │   │               ├── NcnnJni.java // jni交互文件
│       │   │               └── PhotoUtil.java // 图片工具文类(从相册中取文件)
│       │   └── res
│       │       ├── drawable
│       │       │   └── ic_launcher_background.xml
│       │       ├── drawable-v24
│       │       │   └── ic_launcher_foreground.xml
│       │       ├── layout
│       │       │   └── activity_main.xml
│       │       ├── mipmap-anydpi-v26
│       │       │   ├── ic_launcher.xml
│       │       │   └── ic_launcher_round.xml
│       │       ├── mipmap-hdpi
│       │       │   ├── ic_launcher.png
│       │       │   └── ic_launcher_round.png
│       │       ├── mipmap-mdpi
│       │       │   ├── ic_launcher.png
│       │       │   └── ic_launcher_round.png
│       │       ├── mipmap-xhdpi
│       │       │   ├── ic_launcher.png
│       │       │   └── ic_launcher_round.png
│       │       ├── mipmap-xxhdpi
│       │       │   ├── ic_launcher.png
│       │       │   └── ic_launcher_round.png
│       │       ├── mipmap-xxxhdpi
│       │       │   ├── ic_launcher.png
│       │       │   └── ic_launcher_round.png
│       │       └── values
│       │           ├── colors.xml
│       │           ├── strings.xml
│       │           └── styles.xml
│       └── test
│           └── java
│               └── com
│                   └── ztjy
│                       └── ncnndemo
│                           └── ExampleUnitTest.java
├── build.gradle
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
└── settings.gradle

执行流程

https://www.processon.com/view/link/5d5cfe08e4b08b95b82695bb
在这里插入图片描述

重点代码

java层代码

//  predict imageprivate void predict_image(String image_path) {// picture to float arrayBitmap bmp = PhotoUtil.getScaleBitmap(image_path);Bitmap rgba = bmp.copy(Bitmap.Config.ARGB_8888, true);// resize to 227x227Bitmap input_bmp = Bitmap.createScaledBitmap(rgba, ddims[2], ddims[3], false);try {// Data format conversion takes too long// Log.d("inputData", Arrays.toString(inputData));long start = System.currentTimeMillis();// get predict result(调用jni层代码,进行预测)float[] result = squeezencnn.detect(input_bmp);long end = System.currentTimeMillis();Log.d(TAG, "origin predict result:" + Arrays.toString(result));long time = end - start;Log.d(TAG, String.valueOf(result.length));// show predict result and timeint r = get_max_result(result);Log.d(TAG, r + "");Log.d(TAG, resultLabel.toString());Log.d(TAG, resultLabel.get(r));Log.d(TAG, result[r] + "");Log.d(TAG, time + "");String show_text = "result:" + r + ",name:" + resultLabel.get(r) + "\nprobability:" + result[r] + "\ntime:" + time + "ms";Log.d(TAG, show_text);result_text.setText(show_text);} catch (Exception e) {e.printStackTrace();}}

jni层代码

// public native String Detect(Bitmap bitmap);
JNIEXPORT jfloatArray JNICALL
Java_com_ztjy_ncnndemo_NcnnJni_detect(JNIEnv *env, jobject thiz, jobject bitmap) {// ncnn from bitmapncnn::Mat in;{AndroidBitmapInfo info;// 获取位图信息AndroidBitmap_getInfo(env, bitmap, &info);// 获取位图宽高int width = info.width;int height = info.height;// demo只支持rgba格式的图片if (info.format != ANDROID_BITMAP_FORMAT_RGBA_8888)return NULL;void *indata;AndroidBitmap_lockPixels(env, bitmap, &indata);// 把像素转换成data,并指定通道顺序in = ncnn::Mat::from_pixels((const unsigned char *) indata, ncnn::Mat::PIXEL_RGBA2BGR,width, height);AndroidBitmap_unlockPixels(env, bitmap);}// ncnn_net// std::vector<float> cls_scores;{// 减去均值和乘上比例(来源与caffe神经网络的配置文件,即prototxt文件)const float mean_vals[3] = {103.94f, 116.78f, 123.68f};const float scale[3] = {0.017f, 0.017f, 0.017f};// 设置均值与标准化参数in.substract_mean_normalize(mean_vals, scale);// 创建ncnn前向传播的结果提取器ncnn::Extractor ex = ncnn_net.create_extractor();// 如果不加密使用ex.input("data", in);ex.input(mobilenet_v2_param_id::BLOB_data, in);ncnn::Mat out;// 如果不加密是使用ex.extract("prob", out);ex.extract(mobilenet_v2_param_id::BLOB_prob, out);int output_size = out.w;jfloat *output[output_size];for (int j = 0; j < out.w; j++) {output[j] = &out[j];}// 获取结果预测结果,并返回给android层jfloatArray jOutputData = env->NewFloatArray(output_size);if (jOutputData == nullptr) return nullptr;env->SetFloatArrayRegion(jOutputData, 0, output_size,reinterpret_cast<const jfloat *>(*output));  // copyreturn jOutputData;}
}

效果展示

caffe+mobilenet分类
在这里插入图片描述

其他工程的效果图

https://github.com/chehongshu/ncnnforandroid_objectiondetection_Mobilenetssd.git
ncnn+mobilenet-ssd
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

相关学习资料

教学视频

唐宇迪-深度学习Caffe框架入门视频课程:https://edu.csdn.net/course/detail/3506
会写代码的好厨师-Caffe实战入门:https://www.imooc.com/learn/1040

开源项目

caffe官网:https://github.com/BVLC/caffe
ncnn:https://github.com/Tencent/ncnn.git
ncnn+mobilenet-ssd:https://github.com/chehongshu/ncnnforandroid_objectiondetection_Mobilenetssd
shicai_mobilenet:https://github.com/shicai/MobileNet-Caffe.git
weiliu89:https://github.com/weiliu89/caffe.git(需要check_out到ssd分支)

参考博客

在Android手机上使用腾讯的ncnn实现图像分类:
https://blog.csdn.net/qq_33200967/article/details/82421089

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/547748.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java+包装类,装箱和拆箱_Java包装类,装箱和拆箱详解

下面要给大家讲到的就是Java内置包装类方面的知识&#xff0c;这章主要会讲到Java包装类装箱和拆箱方面的知识&#xff0c;一起来了解一下。Java为每种基本数据类型分别设计了对应的类&#xff0c;这就被叫做是包装类(WrapperClasses)&#xff0c;当然&#xff0c;也有的地方叫…

Using JSON for data transfer

为什么80%的码农都做不了架构师&#xff1f;>>> JSON basics At its simplest, JSON allows you to transform a set of data represented in a JavaScript object into a string that you can easily pass from one function to another, or -- in the case of as…

Visual Studio 2010 中JS注释制作

Visual Studio 2010中的js注释已经很强大了&#xff0c;但怎么才能和调用c#的方法一样容易呢&#xff1f;怎样才能让每个参数都有注释说明呢&#xff1f;底下就是想要的答案。 先上图&#xff0c;如图所示&#xff1a; 其中红色的办法为注释效果&#xff0c;当然制作的方法也在…

windows下配置caffe-matlab接口

一、环境说明 也是安装顺序。特别强调的是除VS2015以外&#xff0c;其他软件的安装路径都最好不要包含空格。 1、Windows 64位系统。 2、Visual Studio 2015(VS2015, 对应VC14)。 3、Matlab 2017a。Matlab的版本倒不是很重要&#xff0c;只要支持Matlab 2015a之后的版本都应该…

NVelocity标签使用详解

本文使用的NVelocity版本为1.1.1&#xff0c;应该是目前为止最新的版本吧&#xff0c;前几天在google上找了一个自称是NVelocity 1.6.1 bate2的dll&#xff0c;下载下来一看更新时间是2009年的&#xff0c;还没版本NVelocity 1.1.1&#xff08;2010年出的&#xff09; 新呢&…

一文搞懂蓝绿发布、灰度发布和滚动发布

一文搞懂蓝绿发布、灰度发布和滚动发布 应用程序升级面临最大挑战是新旧业务切换&#xff0c;将软件从测试的最后阶段带到生产环境&#xff0c;同时要保证系统不间断提供服务。 长期以来&#xff0c;业务升级渐渐形成了几个发布策略&#xff1a;蓝绿发布、灰度发布和滚动发布&…

NVelocity标签设置缓存的解决方案

意外的问题总会让人措手不及&#xff0c;今天与大家分享的就是NVelocity设置缓存的问题&#xff0c;之前刚google了一下发现没什么太好的解决方案&#xff0c;希望在这能为需要的朋友找出满意的答案&#xff0c;上一篇blog刚说了NVelocity的用法&#xff0c;这就不在重复了&…

java成员方法的一般格式为_Java基本知识(四)

一、二维数组1、定义方式m&#xff1a;代表当前二维数组中有多少个一维数组&#xff1b;n&#xff1a;代表每个一维数组的长度(1)数据类型[][] 数组名new 数据类型[m][n](2)数据类型[][] 数组名new 数据类型[m][ ]&#xff0c;只给定m个一维数组&#xff0c;每个一维数组长度动…

免费的定时任务托管 clock.sh

自己有很多定时任务要跑&#xff0c;所以之前搞了一个定时运行的系统。 在 V2EX 看到很多有类似需求的朋友&#xff1a; https://www.v2ex.com/t/252810https://www.v2ex.com/t/448726https://www.v2ex.com/t/579740https://www.v2ex.com/t/241229https://hk.v2ex.com/t/1134…

vCenter Server Appliance(VCSA )6.7部署指南

VCSA 6.7版本于2018年4月17日提供下载&#xff0c;同时发布的还有ESXi 6.7&#xff0c;根据官方文档&#xff0c;6.7版本升级主要为了发布vSAN 6.7版本。 第1步&#xff0c;下载VMware-VCSA-all-6.7.0-8217866文件&#xff0c;用虚拟光驱挂载或者解压运行&#xff0c;选择“安…

Ansible无敌详细入门教程

Ansible 是什么 ? ansible架构图 ansible特性 模块化&#xff1a;调用特定的模块&#xff0c;完成特定的任务&#xff1b; 基于Python语言研发&#xff0c;由Paramiko, PyYAML和Jinja2三个核心库实现&#xff1b; 部署简单&#xff1a;agentless&#xff1b; 支持自定义模…

Nginx学习笔记(五) 源码分析内存模块内存对齐

Nginx源码分析&内存模块 今天总结了下C语言的内存分配问题&#xff0c;那么就看看Nginx的内存分配相关模型的具体实现。还有内存对齐的内容~~不懂的可以看看~~ src/os/unix/Ngx_alloc.h&Ngx_alloc.c 先上源码&#xff1a; /** Copyright (C) Igor Sysoev* Copyright (C…

reactor p java_Java反应式框架Reactor中的Mono和Flux

1. 前言最近写关于响应式编程的东西有点多&#xff0c;很多同学反映对Flux和Mono这两个Reactor中的概念有点懵逼。但是目前Java响应式编程中我们对这两个对象的接触又最多&#xff0c;诸如Spring WebFlux、RSocket、R2DBC。我开始也对这两个对象头疼&#xff0c;所以今天我们就…

Visual Studio 20xx试用版升级为正式版(WIN7同样有效)图解、附带序列号

Visual Studio 2005|2008 试用版升级为正式版&#xff08;WIN7同样有效&#xff09;。 目录 一、步骤图解 二、win7破解工具下载 三、序列号 一、步骤图解 1.控制面板 > 程序和功能 > Visual Studio 2005|2008 启动、修复程序。如图&#xff1a; 2.填写序列号&#xff0…

NHibernate使用之详细图解

本文档适合初级开发者或者是第一次接触NHibernate框架的朋友&#xff0c;其中NHibernate不是最新的版本&#xff0c;但是一个比较经典的版本 NHibernate 2.1.2&#xff0c;其中用红线标注的部分一定要仔细看&#xff0c;这些都是容易忽略和出错的地方&#xff0c;笔者在此给大家…

disabling directory browsing

2019独角兽企业重金招聘Python工程师标准>>> I have seen several recommendation to increase web application security by disabling directory browsing (for example pg 388 in IBM WebSphere Deployment and Advanced Configuration by Barcia, Hines, et al)…

水印生成器第2版[原图质量水印可自定义设置]

简介&#xff1a;水印生成器&#xff0c;原理很简单&#xff0c;一时在网上没有找到打水印的网站&#xff0c;自己便做了一个&#xff0c;效果如下图&#xff0c;可自定义字体大小、字体类型以及颜色。 开发环境&#xff1a;vs 2010 [net 3.5 WindowsForms应用程序] 本文带给…

服务发现与负载均衡traefik ingress

ingress就是从kubernetes集群外访问集群的入口&#xff0c;将用户的URL请求转发到不同的service上。Ingress相当于nginx、apache等负载均衡方向代理服务器&#xff0c;其中还包括规则定义&#xff0c;即URL的路由信息&#xff0c;路由信息得的刷新由 Ingress controller 提供 …

GentleNet使用之详细图解[语法使用增强版]

目录第一章 开发环境第二章 简介第三章 Gentle.Net-1.5.0 下载文件包介绍第四章 使用步骤第五章 源码下载 第一章、开发环境&#xff1a;Vs 2010 Sql 2005 GentleNet 1.5.0 【Web网站程序 .Net Framework 3.5】第二章、简介&#xff1a;Gentle.Net是一个开源的优秀O/R M…

NBear简介与使用图解

NBear简介与使用图解框架类型&#xff1a;ORM映射框架简介&#xff1a;NBear是一个基于.Net 2.0、C#2.0开放全部源代码的的软件开发框架类库。NBear的设计目标是尽最大努力减少开发人员的工作量&#xff0c;最大程度提升开发效率&#xff0c;同时兼顾性能及可伸缩性。Demo版本&…