人工智能當(dāng)今最流行的詞語沒有之一猾普。在 WWDC 2017 中颈将,Apple 發(fā)表許多令開發(fā)者們?yōu)橹駣^的新框架(Framework) 及API 。 在這之中如叼,最引注的莫過于 Core ML和Vision 纠俭。
這篇文章我只是介紹一下CoreML沿量,借由 Core ML,你可以為你的 App 添 增機(jī)器學(xué)習(xí)(Machine Learning)的能 柑晒。最棒的是你不需要深入的解關(guān)于神經(jīng)網(wǎng)絡(luò)(Neural Network)以及機(jī)器學(xué)習(xí)(Machine Learning)的相關(guān)知識(shí)欧瘪。
素材開始準(zhǔn)備
蘋果給封裝好的模型下載地址:https://developer.apple.com/machine-learning
大家根據(jù)需求去下載不同的模型,蘋果給的模型能夠識(shí)別1000種匙赞,包的大小不同是計(jì)算的精度不同佛掖。
名字 | 大小 | 介紹 | 使用場(chǎng)景 |
---|---|---|---|
MobileNet | 17.1 MB | MobileNets基于一個(gè)流線型的架構(gòu),它有深度的可分離的卷積來構(gòu)建輕量級(jí)的涌庭、深度的神經(jīng)網(wǎng)絡(luò)芥被。從一組1000個(gè)類別中檢測(cè)出圖像中的占主導(dǎo)地位的物體,如樹坐榆、動(dòng)物拴魄、食物、車輛席镀、人等等匹中。 | 檢測(cè)出圖像中的占主導(dǎo)地位的物體,如樹豪诲、動(dòng)物顶捷、食物、車輛屎篱、人 |
SqueezeNet | 5 MB | 從一組1000個(gè)類別中檢測(cè)出圖像中的占主導(dǎo)地位的物體服赎,如樹葵蒂、動(dòng)物、食物重虑、車輛践付、人等等。雖然只有5 MB的內(nèi)存空間缺厉,但是永高,壓縮zenet與alex net的精度相同,但其參數(shù)卻少了50倍芽死。 | 檢測(cè)出圖像中的占主導(dǎo)地位的物體乏梁,如樹、動(dòng)物关贵、食物、車輛卖毁、人揖曾。包小適用在項(xiàng)目中適用 |
Places205-GoogLeNet | 24.8 MB | 偵測(cè)到一個(gè)來自205個(gè)類別的圖像的場(chǎng)景,如機(jī)場(chǎng)終端亥啦、臥室炭剪、森林、海岸等翔脱。 | 檢測(cè)場(chǎng)景 |
ResNet50 | 102.6 MB | 從一組1000個(gè)類別中檢測(cè)出圖像中的占主導(dǎo)地位的物體奴拦,如樹、動(dòng)物届吁、食物错妖、車輛、人等等疚沐。 | 同MobileNet |
Inception v3 | 94.7 MB | 從一組1000個(gè)類別中檢測(cè)出圖像中的占主導(dǎo)地位的物體暂氯,如樹、動(dòng)物亮蛔、食物痴施、車輛、人等等究流。 | 同MobileNet 辣吃,包越大計(jì)算精度越大 |
VGG16 | 553.5 MB | 從一組1000個(gè)類別中檢測(cè)出圖像中的占主導(dǎo)地位的物體,如樹芬探、動(dòng)物神得、食物、車輛灯节、人等等循头。 | 同MobileNet 绵估,包越大計(jì)算精度越大 |
創(chuàng)建項(xiàng)目
我們創(chuàng)建一個(gè)AR項(xiàng)目,這次使用蘋果提供的Resnet50.mlmodel模型
-
講模型拖入項(xiàng)目卡骂,成功之后就是這個(gè)樣子的国裳。。全跨。
引入需要的框架Vison
Vison 與 Core ML 的關(guān)系
Vision 是 Apple 在 WWDC 2017 推出的圖像識(shí)別框架缝左。
Core ML 是 Apple 在 WWDC 2017 推出的機(jī)器學(xué)習(xí)框架。代碼
- 實(shí)現(xiàn)思路
- 添加一個(gè)點(diǎn)擊手勢(shì)浓若,每次點(diǎn)擊的時(shí)候截取屏幕中的畫面渺杉。
- 將圖片轉(zhuǎn)換成像素,喂給CoreML識(shí)別挪钓,返回結(jié)果
- 創(chuàng)建AR文字以及底座放到指定位置
- 拿到模型
// 拿到模型
var resentModel = Resnet50()
- 創(chuàng)建點(diǎn)擊手勢(shì)
//創(chuàng)建點(diǎn)擊手勢(shì)
func regiterGestureRecognizers(){
let tapGes = UITapGestureRecognizer(target: self, action: #selector(tapped))
self.sceneView.addGestureRecognizer(tapGes)
}
//手勢(shì)的點(diǎn)擊方法,方法前面添加@objc
@objc func tapped(recognizer: UITapGestureRecognizer) {
//拿到當(dāng)前的屏幕的畫面===截圖
let sceneView = recognizer.view as! ARSCNView
//拿到圖片的中心位置,以作為點(diǎn)擊的位置
let touchLoaction = self.sceneView.center
//判別當(dāng)前是否有像素
guard let currentFrame = sceneView.session.currentFrame else {return}
//識(shí)別物件的特征點(diǎn)
let hitTestResults = sceneView.hitTest(touchLoaction, types: .featurePoint)
//判斷點(diǎn)擊結(jié)果是否為空
if hitTestResults.isEmpty {return}
// 拿到第一個(gè)結(jié)果是越,判斷是否為空
guard let hitTestResult = hitTestResults.first else { return }
//記錄拿到點(diǎn)擊的結(jié)果
self.hitTestResult = hitTestResult
// 拿到的圖片轉(zhuǎn)換成像素
let pixelBuffer = currentFrame.capturedImage
//識(shí)別圖片像素
perfomVisionRequest(pixelBuffer: pixelBuffer)
}
- 識(shí)別圖片像素
//識(shí)別圖片像素
func perfomVisionRequest(pixelBuffer: CVPixelBuffer) {
// 拿出mlmodel
let visionModel = try! VNCoreMLModel(for: self.resentModel.model)
//創(chuàng)建CoreMLRequest
let request = VNCoreMLRequest(model: visionModel) { (request, error) in
//處理識(shí)別結(jié)果,如果存在error直接返回
if error != nil {return}
//判斷結(jié)果是否為空
guard let observations = request.results else {return}
//把結(jié)果中的第一位拿出來分析
let observation = observations.first as! VNClassificationObservation
print("Name \(observation.identifier) and confidence is \(observation.confidence)")
//回到主線程更新UI
DispatchQueue.main.async {
self.displayPredictions(text: observation.identifier)
}
}
//進(jìn)行喂食碌上,設(shè)置請(qǐng)求識(shí)別圖片的樣式
request.imageCropAndScaleOption = .centerCrop
//記錄請(qǐng)求數(shù)組
self.visionRequests = [request]
//創(chuàng)建圖片請(qǐng)求
let imageRequestHandler = VNImageRequestHandler(cvPixelBuffer: pixelBuffer, orientation: .upMirrored, options: [:])
//異步處理所有請(qǐng)求
DispatchQueue.global().async {
try! imageRequestHandler.perform(self.visionRequests)
}
}
- 展示結(jié)果
//展示預(yù)測(cè)的結(jié)果
func displayPredictions(text: String) {
//創(chuàng)建node
let node = createText(text: text)
//設(shè)置位置倚评,// 把模型展示在我們點(diǎn)擊位置(中央)
node.position = SCNVector3(self.hitTestResult.worldTransform.columns.3.x,
self.hitTestResult.worldTransform.columns.3.y,
self.hitTestResult.worldTransform.columns.3.z)
//將父節(jié)點(diǎn)放到sceneView上
self.sceneView.scene.rootNode.addChildNode(node) // 把AR結(jié)果展示出來
}
//根據(jù)傳入的文字創(chuàng)建AR展示文字以及底座
func createText(text: String) -> SCNNode {
//創(chuàng)建父節(jié)點(diǎn)
let parentNode = SCNNode()
//創(chuàng)建底座圓球,1 cm 的小球幾何形狀
let sphere = SCNSphere(radius: 0.01)
//創(chuàng)建渲染器
let sphereMaterial = SCNMaterial()
sphereMaterial.diffuse.contents = UIColor.red
sphere.firstMaterial = sphereMaterial
//創(chuàng)建底座節(jié)點(diǎn)
let sphereNode = SCNNode(geometry: sphere)
//創(chuàng)建文字
let textGeo = SCNText(string: text, extrusionDepth: 0)
textGeo.alignmentMode = kCAAlignmentCenter
textGeo.firstMaterial?.diffuse.contents = UIColor.red
textGeo.firstMaterial?.specular.contents = UIColor.white
textGeo.firstMaterial?.isDoubleSided = true
textGeo.font = UIFont(name: "Futura", size: 0.15)
//創(chuàng)建節(jié)點(diǎn)
let textNode = SCNNode(geometry: textGeo)
textNode.scale = SCNVector3Make(0.2, 0.2, 0.2)
//將底座以及文字添加父節(jié)點(diǎn)
parentNode.addChildNode(sphereNode)
parentNode.addChildNode(textNode)
return parentNode;
}
效果圖
小編送上Dome地址:https://github.com/dongdongca/CoreML