如何解决快速的多列文字识别
在多于一列的图像上使用文本识别时遇到一些麻烦。例如:
cars:
1 red car 1 blue car
2 red car 2 blue car
3 red car 3 blue car
将返回:
cars:
1 red car
1 blue car
2 red car
2 blue car
3 red car
3 blue car
我需要它退货的是
cars:
1 red car
2 red car
3 red car
1 blue car
2 blue car
3 blue car
并非我需要分析的每张图像都有2列,但有很多列。
我当前使用的代码如下:
let requestHandler = VNImageRequestHandler(ciImage: image)
let textRecognitionRequest = VNRecognizeTextRequest(completionHandler: recognizeTextHandler)
textRecognitionRequest.recognitionLevel = VNRequestTextRecognitionLevel.accurate
do {
try requestHandler.perform([textRecognitionRequest])
}
catch {
print(error)
}
func recognizeTextHandler(request: VNRequest,error: Error?) {
let text = ""
guard let results =
request.results as? [VNRecognizedTextObservation] else {
fatalError("Could Not Detect Text")
}
for visionResult in results {
let maximumCandidates = 1
guard let candidate = visionResult.topCandidates(maximumCandidates).first else {
continue
}
let string = candidate.string
text += "\n"
text += candidate.string
}
print(text)
}
任何帮助将不胜感激。预先感谢!
解决方法
几个月前,我遇到了一个类似的模块,其中我必须从图像中提取文本。我在GitHub上找到了一个项目,这确实很有帮助。不幸的是,我没有该GitHub项目的链接,但我要在这里从我的项目中共享代码。
**我不算学分。该Github项目的所有学分。找到链接后,我将共享该链接。**
import UIKit
import Reachability
创建网络可达性实例。
let reachability = try! Reachability()
从图库中拾取图像并提取文本。
extension ExtractTextViewController: UIImagePickerControllerDelegate,UINavigationControllerDelegate {
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true)
}
func imagePickerController(_ picker: UIImagePickerController,didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
picker.dismiss(animated: true)
if let pickedImage = info[.originalImage] as? UIImage {
// check internet connection first..
if reachability.connection == .wifi || reachability.connection == .cellular {
// using google api to detect text from images..
// it will extract text from any image,be it in english,spanish,german etc..
GoogleAPI.taskDetect(form: pickedImage) { (result,errorString) in
guard let result = result else {
self.showAlert(title: "Erorr",message: errorString!)
return
}
// Text has been extracted.. It's as simple as that..
let extractedText = result.fullTextAnnotation.text.replacingOccurrences(of: "\n",with: " ")
print(extractedText)
}
}
else {
// some alert when internet is not connected..
self.showAlert(title: "Warning",message: "Please check your internet connection. It is required to extract text from images.")
}
}
picker.dismiss(animated: true,completion: nil)
}
}
GoogleAPI.swift
import Foundation
import UIKit
import Alamofire
class GoogleAPI {
enum Endpoint {
static let endPoint = "https://vision.googleapis.com/v1/images:annotate"
// This api key was mentioned in that GitHub project. I'm using the same and it's working perfectly fine.
static let apiKey = "AIzaSyD-IAmWA0NKGNarU0Bxtz-esSp47V5phBo"
case detectImage
var stringValue: String {
switch self {
case .detectImage: return "\(Endpoint.endPoint)?key=\(Endpoint.apiKey)"
}
}
var url: URL {
return URL(string: stringValue)!
}
}
class func base64EncodeImage(_ image: UIImage) -> String? {
return image.pngData()?.base64EncodedString(options: .endLineWithCarriageReturn)
}
class func taskDetect(form image: UIImage,completion: @escaping (Results?,String?) -> Void) {
guard let base64Image = base64EncodeImage(image) else {
completion(nil,"Error while base64 encoding image")
return
}
let parameters: Parameters = [
"requests": [
[
"image": [
"content": base64Image
],"features": [
[
"type": "TEXT_DETECTION"
]
]
]
]
]
let headers: HTTPHeaders = [
"X-Ios-Bundle-Identifier": Bundle.main.bundleIdentifier ?? "",]
AF.request(
Endpoint.detectImage.url,method: .post,parameters: parameters,encoding: JSONEncoding.default,headers: headers)
.responseData { response in
guard let data = response.data else {
completion(nil,response.error?.localizedDescription)
return
}
do {
let object = try JSONDecoder().decode(GoogleResponse.self,from: data)
completion(object.responses[0],nil)
} catch {
print(error.localizedDescription)
completion(nil,error.localizedDescription)
}
}
}
}
GoogleResponse.swift
import Foundation
import UIKit
struct Vertex: Codable {
let x: Int?
let y: Int?
}
struct BoundingBox: Codable {
let vertices: [Vertex]
}
struct Annotation: Codable {
let description: String
let boundingPoly: BoundingBox
}
struct Full: Codable {
let text: String
}
struct Results: Codable {
let textAnnotations: [Annotation]
let fullTextAnnotation: Full
}
struct GoogleResponse: Codable {
let responses: [Results]
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。