版本記錄
版本號 | 時間 |
---|---|
V1.0 | 2020.10.15 星期四 |
前言
iOS 11+
和macOS 10.13+
新出了Vision
框架徒恋,提供了人臉識別暴浦、物體檢測、物體跟蹤等技術(shù)官觅,它是基于Core ML的刑峡⊙竺觯可以說是人工智能的一部分玄柠,接下來幾篇我們就詳細的解析一下Vision框架突梦。感興趣的看下面幾篇文章。
1. Vision框架詳細解析(一) —— 基本概覽(一)
2. Vision框架詳細解析(二) —— 基于Vision的人臉識別(一)
3. Vision框架詳細解析(三) —— 基于Vision的人臉識別(二)
4. Vision框架詳細解析(四) —— 在iOS中使用Vision和Metal進行照片堆疊(一)
5. Vision框架詳細解析(五) —— 在iOS中使用Vision和Metal進行照片堆疊(二)
6. Vision框架詳細解析(六) —— 基于Vision的顯著性分析(一)
7. Vision框架詳細解析(七) —— 基于Vision的顯著性分析(二)
8. Vision框架詳細解析(八) —— 基于Vision的QR掃描(一)
源碼
1. Swift
首先看下工程組織結(jié)構(gòu):
下面就是源碼了
1. ViewController.swift
import UIKit
import Vision
import AVFoundation
import SafariServices
class ViewController: UIViewController {
// MARK: - Private Variables
var captureSession = AVCaptureSession()
// TODO: Make VNDetectBarcodesRequest variable
lazy var detectBarcodeRequest = VNDetectBarcodesRequest { request, error in
guard error == nil else {
self.showAlert(withTitle: "Barcode error", message: error?.localizedDescription ?? "error")
return
}
self.processClassification(request)
}
// MARK: - Override Functions
override func viewDidLoad() {
super.viewDidLoad()
checkPermissions()
setupCameraLiveView()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// TODO: Stop Session
captureSession.stopRunning()
}
}
extension ViewController {
// MARK: - Camera
private func checkPermissions() {
// TODO: Checking permissions
switch AVCaptureDevice.authorizationStatus(for: .video) {
case .notDetermined:
AVCaptureDevice.requestAccess(for: .video) { [self] granted in
if !granted {
self.showPermissionsAlert()
}
}
case .denied, .restricted:
showPermissionsAlert()
default:
return
}
}
private func setupCameraLiveView() {
// TODO: Setup captureSession
captureSession.sessionPreset = .hd1280x720
// TODO: Add input
let videoDevice = AVCaptureDevice
.default(.builtInWideAngleCamera, for: .video, position: .back)
guard
let device = videoDevice,
let videoDeviceInput = try? AVCaptureDeviceInput(device: device),
captureSession.canAddInput(videoDeviceInput) else {
showAlert(
withTitle: "Cannot Find Camera",
message: "There seems to be a problem with the camera on your device.")
return
}
captureSession.addInput(videoDeviceInput)
// TODO: Add output
let captureOutput = AVCaptureVideoDataOutput()
// TODO: Set video sample rate
captureOutput.videoSettings = [kCVPixelBufferPixelFormatTypeKey as String: Int(kCVPixelFormatType_32BGRA)]
captureOutput.setSampleBufferDelegate(self, queue: DispatchQueue.global(qos: DispatchQoS.QoSClass.default))
captureSession.addOutput(captureOutput)
configurePreviewLayer()
// TODO: Run session
captureSession.startRunning()
}
// MARK: - Vision
func processClassification(_ request: VNRequest) {
// TODO: Main logic
guard let barcodes = request.results else { return }
DispatchQueue.main.async { [self] in
if captureSession.isRunning {
view.layer.sublayers?.removeSubrange(1...)
for barcode in barcodes {
guard
// TODO: Check for QR Code symbology and confidence score
let potentialQRCode = barcode as? VNBarcodeObservation,
potentialQRCode.symbology == .QR,
potentialQRCode.confidence > 0.9
else { return }
observationHandler(payload: potentialQRCode.payloadStringValue)
}
}
}
}
// MARK: - Handler
func observationHandler(payload: String?) {
// TODO: Open it in Safari
guard
let payloadString = payload,
let url = URL(string: payloadString),
["http", "https"].contains(url.scheme?.lowercased())
else { return }
let config = SFSafariViewController.Configuration()
config.entersReaderIfAvailable = true
let safariVC = SFSafariViewController(url: url, configuration: config)
safariVC.delegate = self
present(safariVC, animated: true)
}
}
// MARK: - AVCaptureDelegation
extension ViewController: AVCaptureVideoDataOutputSampleBufferDelegate {
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
// TODO: Live Vision
guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return }
let imageRequestHandler = VNImageRequestHandler(
cvPixelBuffer: pixelBuffer,
orientation: .right)
do {
try imageRequestHandler.perform([detectBarcodeRequest])
} catch {
print(error)
}
}
}
// MARK: - Helper
extension ViewController {
private func configurePreviewLayer() {
let cameraPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
cameraPreviewLayer.videoGravity = .resizeAspectFill
cameraPreviewLayer.connection?.videoOrientation = .portrait
cameraPreviewLayer.frame = view.frame
view.layer.insertSublayer(cameraPreviewLayer, at: 0)
}
private func showAlert(withTitle title: String, message: String) {
DispatchQueue.main.async {
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "OK", style: .default))
self.present(alertController, animated: true)
}
}
private func showPermissionsAlert() {
showAlert(
withTitle: "Camera Permissions",
message: "Please open Settings and grant permission for this app to use your camera.")
}
}
// MARK: - SafariViewControllerDelegate
extension ViewController: SFSafariViewControllerDelegate {
func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
captureSession.startRunning()
}
}
后記
本篇主要講述了基于Vision的QR掃描羽利,感興趣的給個贊或者關(guān)注~~~