当前位置: 首页 > news >正文

深度学习之Matlab 转C++在iOS上測试CNN手型识别

1 前言

在上一篇Blog。我介绍了在iOS上执行CNN的一些方法。

可是,一般来说。我们须要一个性能强劲的机器来跑CNN,我们仅仅只是须要将得到的结果用于移动端。

之前在Matlab使用UFLDL的代码改动后跑了手型识别的3层CNN,这里我们就考虑将Matlab转C之后移植到xcode中。

Step 1:Matlab 转c

首先要保证代码能够跑。能够执行,比方我这边。例如以下測试cnn识别手型:
手型图片

>> 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:
这里写图片描写叙述
新建一个项目:
这里写图片描写叙述
这里我已经导入了我要转的文件cnnPredict.m,里面有两个输入变量,我须要定义其变量类型,这里我使用autodefine types。就是写一个脚本执行这个函数。即可。

也就是我一開始贴的代码,识别出来后是这样:
这里写图片描写叙述
这里大家能够看到我这边CNN的參数并非非常多,也就是19万个參数而已。


接下来就是build了。这里选择c/c++ static library。而且仅仅输出c code:
这里写图片描写叙述
build结果例如以下:
这里写图片描写叙述
有可能你会build失败。这个时候可能是数据类型问题,能够依据详细情况进行改动到成功为止。
生成的code在目录的codegen目录中:
这里写图片描写叙述

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

在训练的时候,我们的cnn參数是存储在.mat中,因此,为了能在xcode中使用,我们须要将參数导出,这里我选择导出为.txt格式。
导出方法非常easy,一条代码;

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

这里写图片描写叙述

Step 3: 新建iOSproject。导入cnnPredict代码

这一步非常easy,把整个目录拉进来就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 <math.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#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’来切割数据,道理非常easy。

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);

直接就输出结果了:
这里写图片描写叙述
大家看到了吗?识别出的结果为1。就是大拇指的意思。
事实上看到这里,我自己都是有点激动的。特别爽是不是,iOS上执行的CNN直接识别手势。尽管这边的图片是黑白的比較简单一点。

小结

本文总结了怎样将CNN的MATLAB代码转换为C++代码然后在iOS上直接执行的方法。

希望对同道中人有启示!

转载于:https://www.cnblogs.com/claireyuancy/p/7262746.html

相关文章:

  • C++中struct和class的区别
  • Socket网络编程实例2
  • Oracle查询锁表和解锁
  • Spring学习笔记——Spring依赖注入原理分析
  • 这本将shell的书应该不错
  • System.Web.UI.Page
  • TensorFlow 101 | 原理与概念
  • Apache POI
  • [转]Spring Boot应用的后台运行配置
  • 博客第五天
  • 百度知道芝麻将,申请资格权限介绍奖惩制度(简剖)
  • Android真机调试访问本地服务器(localhost)的解决方案
  • matplotlib之scatter绘制散点
  • IBM 存储高可用HA解决方案和DR连续性解决方案
  • [luoguP2401] 不等数列
  • Angularjs之国际化
  • ES6核心特性
  • Hibernate最全面试题
  • JavaScript中的对象个人分享
  • JS专题之继承
  • laravel with 查询列表限制条数
  • Mac 鼠须管 Rime 输入法 安装五笔输入法 教程
  • mysql中InnoDB引擎中页的概念
  • PAT A1017 优先队列
  • PHP 使用 Swoole - TaskWorker 实现异步操作 Mysql
  • Python爬虫--- 1.3 BS4库的解析器
  • 测试如何在敏捷团队中工作?
  • 基于MaxCompute打造轻盈的人人车移动端数据平台
  • 极限编程 (Extreme Programming) - 发布计划 (Release Planning)
  • 如何使用 JavaScript 解析 URL
  • 实现菜单下拉伸展折叠效果demo
  • 用jquery写贪吃蛇
  • 中文输入法与React文本输入框的问题与解决方案
  • ​LeetCode解法汇总518. 零钱兑换 II
  • ​第20课 在Android Native开发中加入新的C++类
  • ​软考-高级-信息系统项目管理师教程 第四版【第19章-配置与变更管理-思维导图】​
  • #etcd#安装时出错
  • #预处理和函数的对比以及条件编译
  • #中的引用型是什么意识_Java中四种引用有什么区别以及应用场景
  • %@ page import=%的用法
  • (16)Reactor的测试——响应式Spring的道法术器
  • (2/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
  • (Forward) Music Player: From UI Proposal to Code
  • (vue)el-checkbox 实现展示区分 label 和 value(展示值与选中获取值需不同)
  • (规划)24届春招和25届暑假实习路线准备规划
  • (南京观海微电子)——COF介绍
  • (四)docker:为mysql和java jar运行环境创建同一网络,容器互联
  • (四)JPA - JQPL 实现增删改查
  • (四)图像的%2线性拉伸
  • (一)插入排序
  • (原創) 如何讓IE7按第二次Ctrl + Tab時,回到原來的索引標籤? (Web) (IE) (OS) (Windows)...
  • ***测试-HTTP方法
  • .NET/C# 异常处理:写一个空的 try 块代码,而把重要代码写到 finally 中(Constrained Execution Regions)
  • .NET/MSBuild 中的发布路径在哪里呢?如何在扩展编译的时候修改发布路径中的文件呢?
  • .netcore如何运行环境安装到Linux服务器