ios - iOS 上的 MLKit 文本检测适用于从 Assets.xcassets 拍摄的照片,但与在相机上拍摄/从相机胶卷上传的照片不同
问题描述
我正在使用来自 MLKit 的 Google 文本检测 API 来检测图像中的文本。它似乎在屏幕截图上效果很好,但是当我尝试在应用程序中拍摄的图像(使用 AVFoundation)或从相机胶卷上传的照片上使用它时,它会吐出少量看似随机的字符。
这是我运行实际文本检测的代码:
func runTextRecognition(with image: UIImage) {
let visionImage = VisionImage(image: image)
textRecognizer.process(visionImage) { features, error in
self.processResult(from: features, error: error)
}
}
func processResult(from text: VisionText?, error: Error?) {
guard error == nil, let text = text else {
print("oops")
return
}
let detectedText = text.text
let okAlert = UIAlertAction(title: "OK", style: .default) { (action) in
// handle user input
}
let alert = UIAlertController(title: "Detected text", message: detectedText, preferredStyle: .alert)
alert.addAction(okAlert)
self.present(alert, animated: true) {
print("alert was presented")
}
}
这是我使用相机胶卷图像的代码(适用于屏幕截图,不适用于相机拍摄的图像):
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let image = info[.originalImage] as? UIImage {
self.runTextRecognition(with: image)
uploadView.image = image
} else {
print("error")
}
self.dismiss(animated: true, completion: nil)
}
这是我在应用程序内使用相机拍摄的照片的代码(从不工作,结果总是无稽之谈):
func photoOutput(_ output: AVCapturePhotoOutput,
didFinishProcessingPhoto photo: AVCapturePhoto,
error: Error?) {
PHPhotoLibrary.shared().performChanges( {
let creationRequest = PHAssetCreationRequest.forAsset()
creationRequest.addResource(with: PHAssetResourceType.photo, data: photo.fileDataRepresentation()!, options: nil)
}, completionHandler: nil)
let testImage = UIImage(data: photo.fileDataRepresentation()!)
self.runTextRecognition(with: testImage!)
}
这就是我使用放在 Assets.xcassets 中的测试图像所做的(这是唯一一个始终运行良好的图像):
let uiimage = UIImage(named: "testImage")
self.runTextRecognition(with: uiimage!)
我认为我的问题可能在于 UIImage 的方向,但我不确定。任何帮助将非常感激!
解决方案
如果您的图像选择器工作正常,则问题可能出在图像方向上。为了快速测试,您可以以不同的方向捕捉多张图像,看看它是否有效。
我的问题是文本识别是从画廊而不是从相机中挑选的图像进行的。那是方向问题。
解决方案 1
在转换为视觉图像之前,请按如下方式固定图像方向。
let fixedImage = pickedImage.fixImageOrientation()
添加此扩展程序。
extension UIImage {
func fixImageOrientation() -> UIImage {
UIGraphicsBeginImageContext(self.size)
self.draw(at: .zero)
let fixedImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return fixedImage ?? self
} }
解决方案 2
Firebase 文档提供了一种修复所有方向的方法。
func imageOrientation(
deviceOrientation: UIDeviceOrientation,
cameraPosition: AVCaptureDevice.Position
) -> VisionDetectorImageOrientation {
switch deviceOrientation {
case .portrait:
return cameraPosition == .front ? .leftTop : .rightTop
case .landscapeLeft:
return cameraPosition == .front ? .bottomLeft : .topLeft
case .portraitUpsideDown:
return cameraPosition == .front ? .rightBottom : .leftBottom
case .landscapeRight:
return cameraPosition == .front ? .topRight : .bottomRight
case .faceDown, .faceUp, .unknown:
return .leftTop
}
}
创建元数据:
let cameraPosition = AVCaptureDevice.Position.back // Set to the capture device you used.
let metadata = VisionImageMetadata()
metadata.orientation = imageOrientation(
deviceOrientation: UIDevice.current.orientation,
cameraPosition: cameraPosition
)
将元数据设置为视觉图像。
let image = VisionImage(buffer: sampleBuffer)
image.metadata = metadata
推荐阅读
- ios - 如何在 iOS 上为此 lang ibpreviewdocumenteditordoublelengthpseudolocale 启用本地化
- canvas - 有没有办法让chart.js中的饼图的外边框颜色与段之间的边框颜色不同?
- django - 如何在 GitHub 操作中编写 blob 以自动标记拉取请求?
- rabbitmq - 具有长 ETA 和 RabbitMQ 的 Celery 任务
- kotlin - 在 kotlin 中使用 Run 的 Elvis 运算符
- python - Python sharepoint 连接 - 无法访问
- sql-server - 为什么这个 T-SQL 查询在 Synapse 中不起作用?
- postgresql - 从 .NET 交互式笔记本中的 SQL 单元查询 postgres 数据库
- javascript - wordpress 上同时有两个活动链接
- c++ - 从分配器返回的内存指针算法