阅读 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/

Vision 圖像識別框架的使用相关推荐

  1. python使用opencv_教你快速使用OpenCV/Python/dlib進行眨眼檢測識別!

    摘要: 影象識別的新思路:眼睛縱橫比,看看大牛如果用這種思路玩轉識別眨眼動作! 今天我們來使用面部標誌和OpenCV 檢測和計算視訊流中的眨眼次數.為了構建我們的眨眼檢測器,我們將計算一個稱為眼睛縱橫 ...

  2. easypr arm linux,arm linux下交叉編譯EasyPR中文車牌識別系統開發(一)

    EasyPR中文車牌識別系統開發(一),我主要介紹如何使用開源的EasyPR中文車牌識別系統,當然后面我會介紹訓練機器學習 SVM 支持向量機和 ANN 人工神經網絡模型在車牌識別的應用. 目錄: 一 ...

  3. UVA1103古代象形文字識別

    題幹 為了理解早期文明,考古學家經常學習用古代語言寫的文本.有一個這樣的語言,最早被使用於三千年前的埃及.這種語言是基於象形文字的符號.下圖是六種象形文字和它們的名稱.在這個問題中,你將寫一個程序來識 ...

  4. unrecongnized workspace file version : 未識別的工作空間文件版本

    unrecongnized workspace file version : 未識別的工作空間文件版本 1,高版本的AD,要导入其他的插件,点击 File–>Import Wizard -> ...

  5. 數據移動時發生***識別欄位其外顯值只有當使用了資料行清單且 IDENTITY_INSERT 為 ON 時才能指定...

    當數據在兩個相同結構的表中移動并且發生: ***識別欄位其外顯值只有當使用了資料行清單且 IDENTITY_INSERT 為 ON 時才能指定的錯誤時 用以下方法解決: SET IDENTITY_IN ...

  6. host速度 mtk usb_Openwrt MTK USB3.0 識別UASP存儲失敗的解決方案

    手裏有個MT7621的設備自己鼓搗鼓搗廢物利用用來做NAS用 發現之前用USB3.0的U盤都可以正常使用 換了USB3.0的移動硬盤盒無法識別出硬盤 執行lsusb -t發現該設備的驅動標示爲uas ...

  7. matlab intergral,matlab學習:人臉識別之HOG(Histograms of Oriented Gradients)

    HOG descriptors 是應用在計算機視覺和圖像處理領域,用於目標檢測的特征描述器.這項技術是用來計算局部圖像梯度的方向信息的統計值.這種方法跟邊緣方向直方圖(edge orientation ...

  8. Swift 教學:如何使用iOS Charts API 製作漂亮的圖表

    在應付許多的資料時,比起只在表格中呈現,使用圖表來顯示資料,可以幫助使用者容易地了解資訊.有了圖表,相對於讀取整個資料表(或幾個資料表)你可以輕鬆地一眼便見到以圖形表示的資料,取得所需的資訊.圖表的使 ...

  9. stm32h7内存分配_【STM32H7教程】第25章 STM32H7的TCM,SRAM等五塊內存基礎知識

    第25章       STM32H7的TCM,SRAM等五塊內存基礎知識 本章教程為大家介紹STM32H7帶的ITCM,DTCM,AXI SRAM,SRAM1,SRAM2,SRAM3,SRAM4和備份 ...

最新文章

  1. 简书 SSH 登录流程分析
  2. matlab画微分方程的矢量场图_MATLAB偏微分方程
  3. 后裂变时代:拼团、砍价、分销等主流玩法盘点及未来趋势
  4. python模拟postman发https请求_【接口测试】Postman入门01-特点和简介
  5. S3C2440与SDRAM的地址连线分析
  6. php excel 垂直居中,完美实现文字图片水平垂直居中
  7. oracle em配置报错,oracle em 启动报错OC4J Configuration issue
  8. python教材答案字典与集合_Python——集合与字典练习
  9. Jetson TX2入门学习之Ubuntu默认密码
  10. 数据结构与算法---常用三大排序算法
  11. McAfee迈克菲杀毒软件企业版8.8.13-McAfee VirusScan Enterprise8.8 百度云
  12. java 8 64_java8离线安装包64位
  13. WPS表格如何将二维表转为一维表
  14. 使用gimp批量处理图片
  15. 关于深圳商事登记招商ukey签名无效
  16. 不同网段的计算机怎么远程桌面,不同网段也可以远程桌面
  17. 同济大学计算机学院东华大学,东华大学原校长蒋昌俊调任同济大学正局级副校长...
  18. html邮箱图标代码,CSS3 单元素邮件图标
  19. 白鹭引擎的微信分享接口
  20. Loaders 的使用,结合Fragments

热门文章

  1. 使用html5进行视频播放
  2. [vs2008]Visual Studio 2008 SP1添加或删除功能提示查找SQLSysClrTypes.msi文件
  3. 关于ognl+struts-tag与el+jstl互相代替,以及el和jstl的学习笔记
  4. HotSpot模板解释器目标代码生成过程源码分析
  5. 堆和栈的区别(面试经验总结)
  6. 内容协商 (Content Negotiation)
  7. Joomla和Drupal简介
  8. 事半功倍系列 javascript
  9. 线上java问题排查
  10. PE文件和COFF文件格式分析——签名、COFF文件头和可选文件头3