Sử dụng framework Vision để xử lý Text Detection trong iOS11
Bài đăng này đã không được cập nhật trong 3 năm
Giới thiệu
Vision là một trong những framework mới được giới thiệu trong phiên bản iOS11. Framework Vision cho phép lập trình viên dễ dàng sử dụng các kỹ thuật, thuật toán xử lý hinh ảnh trong ứng dụng của mình như phát hiện khuôn mặt, phát hiện các đặc điểm trên khuôn mặt (như mặt cười, nhíu mày...), phát hiện barcode, phát hiện và theo dõi đối tượng...
Trong bài viết này, chúng ta sẽ sử dụng framework Vision để xử lý phát hiện chữ viết, từng bước xây dựng một ứng dụng cho phép phát hiện ra chữ viết xuất hiện trong ảnh hoặc camera (không quan tâm tới font chữ, kích thước, chữ in, hay chữ viết tay).
Chuẩn bị
Trước khi đi vào chi tiết các bước, do framework Vision có trong iOS11 nên ta cần chuẩn bị các công cụ sau:
- XCODE 9
- Điện thoại hoặc thiết bị giả lập sử dụng iOS11
Xây dựng chương trình demo
Chương trình demo đơn giản như sau:
- Lấy tín hiệu hình ảnh từ camera (hiển thị trên một Image View)
- Đóng khung các vùng là chữ viết xuất hiện trên ImageView.
Thiết lập để lấy hình ảnh từ camera
Cấu hình project cho phép sử dụng Camera
Từ iOS10 ta cần phải cấu hình thêm info.plist trong project để sử dụng Camera trong ứng dụng, như hình dưới đây
Lấy tín hiệu từ camera hiển thị trên image view
Sử dụng framework AVFoundation để lấy dữ liệu từ camera, đoạn chương trình sau sẽ lấy tín hiệu từ camera để hiển thị trên ImageView
var session = AVCaptureSession()
func startLiveVideo() {
// Thiết lập chế độ Video
session.sessionPreset = AVCaptureSession.Preset.photo
let captureDevice = AVCaptureDevice.default(for: AVMediaType.video)
// Thiết lập cấu hình cho input và output của tín hiệu
let deviceInput = try! AVCaptureDeviceInput(device: captureDevice!)
let deviceOutput = AVCaptureVideoDataOutput()
deviceOutput.videoSettings = [kCVPixelBufferPixelFormatTypeKey as String: Int(kCVPixelFormatType_32BGRA)]
deviceOutput.setSampleBufferDelegate(self, queue: DispatchQueue.global(qos: DispatchQoS.QoSClass.default))
session.addInput(deviceInput)
session.addOutput(deviceOutput)
// Thiết lập cho ImageView hiển thị
let imageLayer = AVCaptureVideoPreviewLayer(session: session)
imageLayer.frame = imageView.bounds
imageView.layer.addSublayer(imageLayer)
session.startRunning()
}
Xử lý phát hiện Text từ tín hiệu camera
Để sử dụng chức năng Text Detection của framework Vision, ta cần phải thực hiện các bước sau:
- Requests - đăng ký thuật toán sẽ sử dụng của Vison framework
- Handlers - đăng ký xử lý sau khi gửi request xử lý
- Observations - đăng ký xử lý khi thuật toán chạy và trả về kết quả
Giờ ta sẽ thực hiện chi tiết các bước trên
Khai báo sử dụng Text Detection
var requests = [VNRequest]()
func startTextDetection() {
let textRequest = VNDetectTextRectanglesRequest(completionHandler: self.detectTextHandler)
textRequest.reportCharacterBoxes = true
self.requests = [textRequest]
}
Đoạn code trên sẽ cho phép phát hiện các vùng chữ nhật có chứa text bên trong nó. Khi qua request được đăng ký nó sẽ trả về kết quả thông qua hàm xử lý detectTextHandler
Xử lý sau khi request Text Detection
func detectTextHandler(request: VNRequest, error: Error?) {
guard let observations = request.results else {
print("no result")
return
}
let result = observations.map({$0 as? VNTextObservation})
DispatchQueue.main.async() {
self.imageView.layer.sublayers?.removeSubrange(1...)
for region in result {
guard let rg = region else {
continue
}
// Xử lý highlight cho một từ
self.highlightWord(box: rg)
if let boxes = region?.characterBoxes {
for characterBox in boxes {
// Xử lý highligh cho một ký tự
self.highlightLetters(box: characterBox)
}
}
}
}
}
- guard let observations = request.results sẽ chứa tất cả các kết quả của** VNDetectTextRectanglesRequest**
- Duyệt qua các kết quả tìm được để highlight các vùng text đã phát hiện được thông qua hai hàm:
- highlightWord
- highlightLetters
Truyền dữ liệu từ camera tới detector
Ta sẽ implement delegate AVCaptureVideoDataOutputSampleBufferDelegate và gửi request tới Text Dectector mỗi khi có tín hiệu từ camera trong hàm này
extension ViewController: AVCaptureVideoDataOutputSampleBufferDelegate {
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else {
return
}
var requestOptions:[VNImageOption : Any] = [:]
if let camData = CMGetAttachment(sampleBuffer, kCMSampleBufferAttachmentKey_CameraIntrinsicMatrix, nil) {
requestOptions = [.cameraIntrinsics:camData]
}
let imageRequestHandler = VNImageRequestHandler(cvPixelBuffer: pixelBuffer, orientation: CGImagePropertyOrientation.right, options: requestOptions)
do {
try imageRequestHandler.perform(self.requests)
} catch {
print(error)
}
}
}
Chạy thử chương trình demo
Khi chạy thử đoạn chương trình trên ta sẽ có kết quả như hình dưới đây:
Kết luận
Vision framework thật sự là một công cụ mạnh mẽ và giúp việc áp dụng các thuật toán xử lý hình ảnh vào các ứng dụng trở nên nhanh chóng và đơn giản hơn rất nhiều. Ngoài việc sử dụng Text Detection ta còn có thể sử dụng các thuật toán phát hiện khác của Vision framework, hoặc có thể kết hợp hai framework Vision và Core ML để triển khai các thuật toán phức tạp hơn và thông minh hơn.
Nguồn thao khảo và mã nguồn chương trình Demo.
- Nguồn tham khảo: https://www.appcoda.com/vision-framework-introduction/
- Mã nguồn chương trình demo: https://github.com/oLeThiVanAnh/R9_2017
All rights reserved