matlab cnn 识别苹果,深度学习之Matlab 转C++在iOS上测试CNN手型识别

1 前言

在上一篇Blog,我介绍了在iOS上运行CNN的一些方法。但是,一般来说,我们需要一个性能强劲的机器来跑CNN,我们只不过需要将得到的结果用于移动端。之前在Matlab使用UFLDL的代码修改后跑了手型识别的3层CNN,这里我们就考虑将Matlab转C之后移植到xcode中。

Step 1:Matlab 转c

首先要保证代码可以跑,可以运行,比如我这边,如下测试cnn识别手型:

7e04e4d1155495974f37eb151dd1ba50.png

>> parameters = load('./opt_parameters/opttheta_8epoches_cnn.mat');

cnnPredict(imread('./data/test_five1 (1).bmp'),parameters.opttheta)

ans =

5

大家可以看到,我识别出来是5个手指。OK,CNN没有问题。现在就是要将cnnPredict函数转c,这里大家可以看到这个函数包含了输入数据和已训练的参数。

function labels = cnnPredict(images,opttheta)

基本方式是使用Matlab自带的工具:coder。

在Command窗口输入coder:

新建一个项目:

ba95a479e7be858d8f9611f09d6d055e.png

这里我已经导入了我要转的文件cnnPredict.m,里面有两个输入变量,我需要定义其变量类型,这里我使用autodefine types,就是写一个脚本运行这个函数,就行。也就是我一开始贴的代码,识别出来后是这样:

1b4dde750a0d01ef755ac398a7ff54a5.png

这里大家可以看到我这边CNN的参数并不是很多,也就是19万个参数而已。

接下来就是build了,这里选择c/c++ static library,并且只输出c code:

8432adec44cc594838170cdd27484eb3.png

build结果如下:

e50d98dc0bb737410e0cae8f4defb611.png

有可能你会build失败,这个时候可能是数据类型问题,可以根据具体情况进行修改到成功为止。

生成的code在文件夹的codegen文件夹中:

3a87c1be4db07ff4721f99e01bdc9d33.png

Step 2:将.Mat参数导出为.txt格式

在训练的时候,我们的cnn参数是存储在.mat中,因此,为了能在xcode中使用,我们需要将参数导出,这里我选择导出为.txt格式。

导出方法非常简单,一条代码;

>> save('opttheta.txt','opttheta','-ASCII'); %将opt theta参数保存为opttheta.txt

2f95eb5676f7f8ac4807e6a14286386c.png

Step 3: 新建iOS工程,导入cnnPredict代码

这一步很简单,把整个文件夹拉进来就OK了。

注意cnnPredict.h代码,我们要用的也就是这里面的函数了:

/* * File: cnnPredict.h * * MATLAB Coder version : 2.7 * C/C++ source code generated on : 16-Jul-2015 16:22:01 */

#ifndef __CNNPREDICT_H__

#define __CNNPREDICT_H__

/* Include Files */

#include

#include

#include

#include

#include "rt_nonfinite.h"

#include "rtwtypes.h"

#include "cnnPredict_types.h"

/* Function Declarations */

extern double cnnPredict(const double images[9216], const double opttheta[195245]);

#endif

/* * File trailer for cnnPredict.h * * [EOF] */

注意的是导入运行里面有个interface文件夹会导致运行失败,应删除之,不会影响其他。

Step 4 在Xcode中导入参数

这一步就是读取txt文件中的数据并转存为double的数组,直接贴代码:

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"opttheta" ofType:@"txt"];

NSString *testString = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];

NSMutableArray *thetaString = (NSMutableArray *)[testString componentsSeparatedByString:@"\n"];

[thetaString removeLastObject];

NSLog(@"Theta1 count:%lu",(unsigned long)thetaString.count);

for (int i = 0; i < thetaString.count; i++) {

NSString *data = [thetaString objectAtIndex:i];

theta[i] = [data doubleValue];

}

从代码中可以看到,就是用’\n’来分割数据,道理非常简单。

Step 5 将图片转换为double数组

为了使用函数,我们必须将图片转换为数组。我们这里显然是使用灰度图片,转换的代码如下:

UIImage *image = [UIImage imageNamed:@"one.bmp"];

CGImageRef imageRef = [image CGImage];

CGDataProviderRef provider = CGImageGetDataProvider(imageRef);

NSData *data = (id)CFBridgingRelease(CGDataProviderCopyData(provider));

NSLog(@"image:%lu",(unsigned long)data.length);

const uint8_t *bytes = [data bytes];

这里就转换为uint8的数组了,接下来我这边根据需要对图片的灰度矩阵需要进行转置:

double newBytes[9216];

for (int y = 0; y < 96 ; y++) {

for (int x = 0; x < 96; x++) {

newBytes[x*96 + y] = bytes[y*96 + x];

}

}

Step 6: 运行cnn

有了上面的处理,这一步直接运行cnnPredict

double result = cnnPredict(newBytes, theta);

NSLog(@"result:%f",result);

直接就输出结果了:

ec0541e8435f7cd19f1a22e2b100f7a5.png

大家看到了吗?识别出的结果为1,就是大拇指的意思。

其实看到这里,我自己都是有点激动的。特别爽是不是,iOS上运行的CNN直接识别手势,虽然这边的图片是黑白的比较简单一点。

小结

本文总结了如何将CNN的MATLAB代码转换为C++代码然后在iOS上直接运行的方法。希望对同道中人有启发!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值