当前位置: 首页 > 编程日记 > 正文

Vision 圖像識別框架的使用

阅读 137
收藏 10
2017-10-18
原文链接:www.itread01.com
Google无人车之父、MIT/斯坦福/耶鲁专家带你进入无人驾驶之域 http://cn.udacity.com/course/intro-to-self-driving-cars--nd113
  • 本文為CocoaChina網友 品位生活 投稿

北京時間2017.6.6日淩晨1點,新一屆的WWDC召開,蘋果在大會上發布了iOS11的beta版,伴隨著iOS 11的發布,也隨之推出了一些新的API,如:ARKit 、Core ML、FileProvider、IdentityLookup 、Core NFC、Vison 等。

本篇文章主要簡單介紹下其中的 Vision API 的使用(Vision更強大的地方是可以結合Core ML模型實現更強大的功能,本篇文章就不詳細展開了)

Vison 與 Core ML 的關系

Vision 是 Apple 在 WWDC 2017 推出的圖像識別框架。

Core ML 是 Apple 在 WWDC 2017 推出的機器學習框架。

Core ML

根據這張圖就可以看出,Core ML的作用就是將一個Core ML模型,轉換成我們的App工程可以直接使用的對象,就是可以看做是一個模型的轉換器。

Vision在這裏的角色,就是相當於一個用於識別Core ML模型的一個角色.

Vision

根據官方文檔看,Vision 本身就有Face Detection and Recognition(人臉檢測識別)、Machine Learning Image Analysis(機器學習圖片分析)、Barcode Detection(條形碼檢測)、Text Detection(文本檢測)。。。。。等等這些功能。

所以可以這樣理解:

Vision庫裏本身就已經自帶了很多訓練好的Core ML模型,這些模型是針對上面提到的人臉識別、條形碼檢測等等功能,如果你要實現的功能剛好是Vision庫本身就能實現的,那麽你直接使用Vision庫自帶的一些類和方法就行,但是如果想要更強大的功能,那麽還是需要結合其它Core ML模型。

Vision 與 Core ML 總結

Core ML可以看做一個模型的轉換器,可以將一個 ML Model 格式的模型文件自動生成一些類和方法,可以直接使用這些類去做分析,讓我們更簡單的在app中使用訓練好的模型。

Vision本身就是能對圖片做分析,他自帶了針對很多檢測的功能,相當於內置了一些Model,另外Vision也能使用一個你設置好的其它的Core ML Model來對圖進行分析。

Vision就是建立在Core ML層之上的,使用Vision其實還是用到了Core ML,只是沒有顯式地直接寫Core ML的代碼而已。

Vison 的應用場景

圖像配準

矩形檢測

二維碼/條形碼檢測

目標跟蹤:臉部,矩形和通用模板

文字檢測:監測文字外框,和文字識別

人臉檢測:支持檢測笑臉、側臉、局部遮擋臉部、戴眼鏡和帽子等場景,可以標記出人臉的矩形區域

人臉特征點:可以標記出人臉和眼睛、眉毛、鼻子、嘴、牙齒的輪廓,以及人臉的中軸線

Vison 的設計理念

蘋果最擅長的,把復雜的事情簡單化,Vision的設計理念也正是如此。

對於使用者我們抽象的來說,我們只需要:提出問題-->經過機器-->得到結果。

開發者不需要是計算機視覺專家,開發者只需要得到結果即可,一切復雜的事情交給Vision。

Vison 的性能對比

Vision 與 iOS 上其他幾種帶人臉檢測功能框架的對比:

根據官方提供的資料可以看出來,Vision 和 Core Image、AV Capture 在精確度,耗時,耗電量來看基本都是Best、Fast、Good。

Vision 支持的圖片類型

Vision 支持多種圖片類型,如:

  • CIImage

  • NSURL

  • NSData

  • CGImageRef

  • CVPixelBufferRef

Vison 的使用 與結構圖

Vision使用中的角色有:

Request,RequestHandler,results和results中的Observation數組。

結果圖

Request類型:

有很多種,比如圖中列出的 人臉識別、特征識別、文本識別、二維碼識別等。

結果圖

使用概述:

我們在使用過程中是給各種功能的 Request 提供給一個 RequestHandler,Handler 持有需要識別的圖片信息,並將處理結果分發給每個 Request 的 completion Block 中。可以從 results 屬性中得到 Observation 數組。

observations數組中的內容根據不同的request請求返回了不同的observation,如:VNFaceObservation、VNTextObservation、VNBarcodeObservation、VNHorizonObservation,不同的Observation都繼承於VNDetectedObjectObservation,而VNDetectedObjectObservation則是繼承於VNObservation。每種Observation有boundingBox,landmarks等屬性,存儲的是識別後物體的坐標,點位等,我們拿到坐標後,就可以進行一些UI繪制。

具體人臉識別使用示例:

1,創建處理圖片處理對應的RequestHandler對象。

    // 轉換CIImageCIImage *convertImage = [[CIImage alloc]initWithImage:image];    // 創建處理requestHandlerVNImageRequestHandler *detectRequestHandler = [[VNImageRequestHandler alloc]initWithCIImage:convertImage options:@{}];

2, 創建回調Handler。(用於識別成功後進行回調執行的一個Block)

    // 設置回調CompletionHandler completionHandler = ^(VNRequest *request, NSError * _Nullable error) {        NSArray *observations = request.results;};

3, 創建對應的識別 Request 請求,指定 Complete Handler

    VNImageBasedRequest *detectRequest = [[VNDetectFaceRectanglesRequest alloc]initWithCompletionHandler: completionHandler];

4,發送識別請求,並在回調中處理回調接受的數據

  [detectRequestHandler performRequests:@[detectRequest] error:nil];

代碼整合:

總的來說一共經過這幾步之後基本的人臉識別就實現了。

    // 轉換CIImageCIImage *convertImage = [[CIImage alloc]initWithImage:image];    // 創建處理requestHandlerVNImageRequestHandler *detectRequestHandler = [[VNImageRequestHandler alloc]initWithCIImage:convertImage options:@{}];    // 設置回調CompletionHandler completionHandler = ^(VNRequest *request, NSError * _Nullable error) {NSArray *observations = request.results;[self handleImageWithType:type image:image observations:observations complete:complete];};    // 創建BaseRequestVNImageBasedRequest *detectRequest = [[VNDetectFaceRectanglesRequest alloc]initWithCompletionHandler:completionHandler];    // 發送識別請求[detectRequestHandler performRequests:@[detectRequest] error:nil];

VNFaceObservation 介紹:

VNFaceObservation裏面,我們能拿到的有用信息就是boundingBox。

/// 處理人臉識別回調+ (void)faceRectangles:(NSArray *)observations image:(UIImage *_Nullable)image complete:(detectImageHandler _Nullable )complete{NSMutableArray *tempArray = @[].mutableCopy;    for (VNFaceObservation *observation  in observations) {CGRect faceRect = [self convertRect:observation.boundingBox imageSize:image.size];}

boundingBox直接是CGRect類型,但是boundingBox返回的是x,y,w,h的比例,需要進行轉換。

/// 轉換Rect+ (CGRect)convertRect:(CGRect)oldRect imageSize:(CGSize)imageSize{CGFloat w = oldRect.size.width * imageSize.width;CGFloat h = oldRect.size.height * imageSize.height;CGFloat x = oldRect.origin.x * imageSize.width;CGFloat y = imageSize.height - (oldRect.origin.y * imageSize.height) - h;    return CGRectMake(x, y, w, h);
}

關於Y值為何不是直接oldRect.origin.y * imageSize.height出來,是因為這個時候直接算出來的臉部是MAX Y值而不是min Y值,所以需要進行轉換一下。

特征識別介紹:

VNDetectFaceLandmarksRequest 特征識別請求返回的也是VNFaceObservation,但是這個時候VNFaceObservation 對象的 landmarks 屬性就會有值,這個屬性裏面存儲了人物面部特征的點。

如:

// 臉部輪廊@property (nonatomic, strong) VNFaceLandmarkRegion2D * _Nonnull faceContour;// 左眼,右眼@property (nonatomic, strong) VNFaceLandmarkRegion2D * _Nullable leftEye;@property (nonatomic, strong) VNFaceLandmarkRegion2D * _Nullable rightEye;// 鼻子,鼻脊@property (nonatomic, strong) VNFaceLandmarkRegion2D * _Nullable nose;@property (nonatomic, strong) VNFaceLandmarkRegion2D * _Nullable noseCrest;@property (nonatomic, strong) VNFaceLandmarkRegion2D * _Nullable medianLine;// 外唇,內唇@property (nonatomic, strong) VNFaceLandmarkRegion2D * _Nullable outerLips;@property (nonatomic, strong) VNFaceLandmarkRegion2D * _Nullable innerLips;// 左眉毛,右眉毛@property (nonatomic, strong) VNFaceLandmarkRegion2D * _Nullable leftEyebrow;@property (nonatomic, strong) VNFaceLandmarkRegion2D * _Nullable rightEyebrow;// 左瞳,右瞳@property (nonatomic, strong) VNFaceLandmarkRegion2D * _Nullable leftPupil;@property (nonatomic, strong) VNFaceLandmarkRegion2D * _Nullable rightPupil;

每個特征對象裏面都有一個pointCount屬性,通過特征對象的pointAtIndex方法,可以取出來特征裏面的每一個點,我們拿到點進行轉換後,相應的UI繪制或其他操作。

例如:

    UIImage *sourceImage = image;    // 遍歷所有特征for (VNFaceLandmarkRegion2D *landmarks2D in pointArray) {CGPoint points[landmarks2D.pointCount];        // 轉換特征的所有點for (int i=0; i

Vision Demo演示:

圖像識別:

以上是簡單列舉了一些代碼,具體更詳細的可參考官方文檔或Demo代碼(後面有Demo 下載鏈接)

下面GIF演示一下Vision Demo ,此Demo比較簡單,演示了基本的一些Vision的使用

圖像識別:

人臉識別、特征識別、文字識別

動態識別:

動態監測人臉,動態進行添加

Demo下載地址

https://github.com/DaSens/Vision_Demo

https://github.com/DaSens/Vision_Track.git

參考資料:

http://www.jianshu.com/p/174b7b67acc9

http://www.jianshu.com/p/e371099f12bd

https://github.com/NilStack/HelloVision

https://developer.apple.com/documentation/vision

https://github.com/jeffreybergier/Blog-Getting-Started-with-Vision

https://tech.iheart.com/iheart-wwdc-familiar-faces-1093fe751d9e

http://yulingtianxia.com/blog/2017/06/19/Core-ML-and-Vision-Framework-on-iOS-11/


相关文章:

Jmeter性能测试 入门

Jmeter性能测试 入门 原文:Jmeter性能测试 入门Jmeter是一款优秀的开源测试工具, 是每个资深测试工程师,必须掌握的测试工具,熟练使用Jmeter能大大提高工作效率。 熟练使用Jmeter后, 能用Jmeter搞定的事情,你就不会使用…

Hadoop集群搭建(二:集群主机间免密登录配置)

实验目的及要求: 静态网络地址配置;主机名的配置;防火墙的配置,使平台相关软件的常用端口能够远程正常访问;主机地址映射的配置,使所有主机能够通过主机名相互正常访问;免密码登录的配置&#…

你真的会用 CocoaPods 吗?

CocoaPods 可以说是 iOS 开发应用最广泛的包管理工具,本篇文章主要介绍 CocoaPods 的第三方库是怎样从网络集成到我们本地的项目当中,也是制作私有库、开源库和 iOS 项目组件化的一个知识铺垫。 让我们从一张图片开始: CocoaPods 工作流程 …

【spring 5】AOP:spring中对于AOP的的实现

在前两篇博客中&#xff0c;介绍了AOP实现的基础&#xff1a;静态代理和动态代理&#xff0c;这篇博客介绍spring中AOP的实现。 一、采用Annotation方式 首先引入jar包&#xff1a;aspectjrt.jar && aspectweaver.jar applicationContext配置文件&#xff1a; <span…

通过BeanShell获取UUID并将参数传递给Jmeter

有些HTTPS请求报文的报文体中包含由客户端生成的UUID&#xff0c;在用Jmeter做接口自动化测试的时候&#xff0c;因为越过了客户端&#xff0c;直接向服务器端发送报文&#xff0c;所以&#xff0c;需要在Jmeter中通过beanshell获取UUID&#xff0c;并能将参数传递给Jmeter&…

Hadoop集群搭建(四:Zookeeper环境安装)

实验 目的 要求 目的&#xff1a; 1、掌握在完全分布模式的整合平台中Zookeeper的完全分布模式的安装 要求&#xff1a; 完成Zookeeper的完全分布农事的安装&#xff1b;Zookeeper服务能够正常启动和连接&#xff1b;Zookeeper控制台能够正常进入&#xff1b;Zookeeper控制台命…

史上第二走心的 iOS11-Drag Drop 教程

原文链接&#xff1a;www.jianshu.com只需完成个人实名注册&#xff0c;即可获得腾讯云免费套餐&#xff01;云服务器CVM、云数据库 MYSQL、文件存储 CFS.....应有尽有&#xff01;https://cloud.tencent.com/act/free 话不多说&#xff0c;先上效果图 普通view拖拽效果 TableV…

指针的各式定义

1&#xff0c;一个整形数&#xff1a; int a; 2&#xff0c;一个指向整形数的指针&#xff1a; int *a; 3&#xff0c;一个指向指针的指针&#xff0c;它指向的指针指向一个整形数&#xff1a; int **a; 4&#xff0c;一个有10个整形数的数组&#xff1a; int a[10]; 5&#…

AS 400 常用命令

转自&#xff1a;http://blog.chinaunix.net/uid-22375044-id-3049793.html 一、命令技巧 命令构成&#xff1a; CRT* (Creat) 创建 WRK* (Work With) 操作 RMV* (Remove) 去除 DSP* (Display) 显示 ADD* (Add) 添加 CHG* (Change) 改变 DLT* (Delete) 删除 CFG* (Config) 配置…

Hadoop集群搭建(五:Hadoop HA集群模式的安装)

实验 目的 要求 目的&#xff1a; 1、Hadoop的高可用完全分布模式的安装和验证 要求&#xff1a; 完成Hadoop的高可用完全分布模式的安装&#xff1b;Hadoop的相关服务进程能够正常的启动&#xff1b;HDFS能够正常的使用&#xff1b;MapReduce示例程序能够正常运行&#xff1b…

iOS开发业界毒瘤 Hook

原文地址 为什么有这篇博文 不知道何时开始iOS面试开始流行起来询问什么是 Runtime&#xff0c;于是 iOSer 一听 Runtime 总是就提起 MethodSwizzling&#xff0c;开口闭口就是黑科技。但其实如果读者留意过C语言的 Hook 原理其实会发现所谓的钩子都是框架或者语言的设计者预留…

常用rsync命令操作梳理

作为一个运维工程师&#xff0c;经常可能会面对几十台、几百台甚至上千台服务器&#xff0c;除了批量操作外&#xff0c;环境同步、数据同步也是必不可少的技能。说到“同步”&#xff0c;不得不提的利器就是rsync。rsync不但可以在本机进行文件同步&#xff0c;也可以作为远程…

Word英文字符间距太大 中英文输入切换都不行

在Word中输入文字时会遇到这样的情况&#xff0c;就是说中文字符的间距是正常的&#xff0c;但是英文字符间的间距却不正常&#xff0c;总是太宽了&#xff0c;如图&#xff1a; 。 而且这时切换中英文输入都没用&#xff0c;Word的字体设置也正常。后来上网查了下&#xff0c;…

Hadoop集群搭建(六:HBase的安装配置)

实验 目的 要求 目的&#xff1a; 1、HBase的高可用完全分布模式的安装和验证 要求&#xff1a; 完成HBase的高可用完全分布模式的安装&#xff1b;HBase的相关服务进程能够正常的启动&#xff1b;HBase控制台能够正常使用&#xff1b;表创建、数据查询等数据库操作能够正常…

架构师的第一阶段:准备做(Pre-Architecture)

上节说到&#xff0c;做任何事情都可以分为三个阶段&#xff1a;准备做、做、做好。本文&#xff0c;就将进入第一个阶段&#xff0c;准备做阶段。 Pre-Architecture&#xff1a;准备架构 准备架构阶段&#xff0c;最最重要的是弄清楚要做什么东西&#xff0c;即掌握用户需求。…

iOS动画系列之八:使用CAShapeLayer绘画动态流量图

这篇文章通过使用CAShapeLayer和UIBezierPath来画出一个动态显示剩余流量的小动画。 最终实现的效果如下&#xff1a; Paste_Image.png 动态效果图&#xff1a; shapeLayerAni.gif 1. CAShapeLayer 实际中&#xff0c;能够用CALayer完成的任务是比较少的&#xff0c;如果使用这…

hiho_1139_二分+bfs搜索

题目 给定N个点和M条边&#xff0c;从点1出发&#xff0c;到达点T。寻找路径上边的个数小于等于K的路径&#xff0c;求出所有满足条件的路径中最长边长度的最小值。 题目链接:二分 最小化最大值&#xff0c;考虑采用二分搜索。对所有的边长进行排序&#xff0c;二分&#x…

Hadoop集群搭建(七:MySQL的安装配置)

实验 目的 要求 目的&#xff1a; 1、掌握MySQL在集群平台中的安装 要求&#xff1a; 完成MySQL的集群版的安装&#xff1b;MySQL集群的相关服务进程能够正常启动&#xff1b;MySQL集群的SQL服务能够作为系统服务开机自动启动&#xff1b;MySQL客户端能够远程连接MySQL集群的…

如何在VMware虚拟机上安装Linux操作系统(Ubuntu)

作为初学者想变为计算机大牛非一朝一夕&#xff0c;但掌握基本的计算机操作和常识却也不是多么难的事情。所以作为一名工科男&#xff0c;为了把握住接近女神的机会&#xff0c;也为了避免当白痴&#xff0c;学会装系统吧&#xff01;of course为避免把自己的电脑作为牺牲品&am…

cf #363 b

B. One Bombtime limit per test1 secondmemory limit per test256 megabytesinputstandard inputoutputstandard outputYou are given a description of a depot. It is a rectangular checkered field of n  m size. Each cell in a field can be empty (".") or…

swift-video-generator:图片加音频生成视频及多视频合并库及演示

阅读 80收藏 92017-11-07原文链接&#xff1a;github.com腾讯云学生优惠套餐&#xff0c;985高校学习云计算的主力机型&#xff0c;2G2核&#xff0c;1M带宽系统盘&#xff08;Linux 50G/Windows 50G&#xff09;免费赠送50GB对象存储空间还有.cn域名一年使用权&#xff01;不要…

Hadoop集群搭建(八:Hive的安装配置)

实验 目的 要求 目的&#xff1a; &#xff08;1&#xff09;掌握数据仓库工具Hive的安装和配置&#xff1b; 要求&#xff1a; 完成Hive工具的安装和配置&#xff1b;Hive工具能够正常启动运行&#xff1b;Hive控制台命令能够正常使用&#xff1b;能够正常操作数据库、表、…

iOS 富文本编辑工厂, 让书写更简便.

由于最近常用富文本, 在编辑一个富文本时需要操作很多的属性, 书写起来很不方便. 所以我将这些相关属性整理并使用链式方式将它简化了一下. 效果请看下面Demo. 项目工程 实现很简单, 我嘴太笨, 这里就不介绍了, 如有兴趣直接看源码吧. 同时可以通过cocoapods来使用它. pod SJAt…

ORACLE 数据的逻辑组成

数据块&#xff08;block&#xff09;Oracle数据块&#xff08;Data Block&#xff09;是一组连续的操作系统块。分配数据库块大小是在Oracle数据库创建时设置的&#xff0c;数据块是Oracle读写的基本单位。数据块的大小一般是操作系统块大小的整数倍&#xff0c;这样可以避免不…

Java 的zip压缩和解压缩

Java 的zip压缩和解压缩好久没有来这写东西了&#xff0c;今天中秋节&#xff0c;有个东西想拿出来分享&#xff0c;一来是工作中遇到的问题&#xff0c;一来是和csdn问候一下&#xff0c;下面就分享一个Java中的zip压缩技术&#xff0c;代码实现比较简单,代码如下&#xff1a;…

Hadoop集群搭建(九:各服务的启动)

1、查看Zookeeper服务状态&#xff0c;若集群中只有一个"leader"节点&#xff0c; 其余的均为"follower"节点&#xff0c;则集群的工作状态正常 $zkServer.sh status 2、在集群中所有主机上使用此命令&#xff0c;启动Zookeeper服务 $zkServer.sh start…

iOS 后台下载及管理库

说起下载第一个想起的就是ASI。一年前接手的新项目是核心功能是视频相关业务&#xff0c;在修改和解决视频下载相关的问题的时候让我体会到了ASI的下载的强大。后来新需求需要视频后台下载&#xff0c;使用NSURLSession的时候&#xff0c;更加深刻的体会到了ASI的强大好用。后来…

(转) 使用Speech SDK 5.1文字转音频

下载地址&#xff1a; http://www.microsoft.com/en-us/download/details.aspx?id10121 SeppchSDK51.exe 语音合成引擎 SpeechSDK51LangPack.exe 支持日语和简体中文需要这个支持。 SpeechSDK51MSM.exe 如果要将引擎作为产品的一部分发布需要这个。 Sp5TTintXP.exe XP下Mike和…

IE8下面的line-height的bug

当line-height小于正常值时&#xff0c;超出的部分将被剪裁掉转载于:https://www.cnblogs.com/jsingleegg/p/js_ie8.html

Hadoop集群的基本操作(一:HDFS操作及MapReduce程序练习)

实验 目的 要求 目的&#xff1a; 理解HDFS在Hadoop体系结构中的角色&#xff1b;熟练使用HDFS操作常用的Shell命令&#xff1b;了解Hadoop集群MapReduce程序的简单使用&#xff1b;&#xff08;上传WordCount的jar执行程序&#xff1b;使用WordCount进行MapReduce计算&#x…