Bạn có thể dùng Bộ công cụ học máy để nhận dạng văn bản trong hình ảnh. Bộ công cụ học máy có cả API đa năng phù hợp để nhận dạng văn bản trong hình ảnh, chẳng hạn như văn bản của biển báo đường phố và một API được tối ưu hoá để nhận dạng văn bản của tài liệu. API đa năng có cả mô hình trên thiết bị và dựa trên đám mây. Tính năng nhận dạng văn bản trong tài liệu chỉ có dưới dạng mô hình dựa trên đám mây. Hãy xem thông tin tổng quan để biết thông tin so sánh giữa các mô hình trên đám mây và trên thiết bị.
Trước khi bắt đầu
- Nếu bạn chưa thêm Firebase vào ứng dụng của mình, hãy làm như vậy bằng cách làm theo các bước trong hướng dẫn bắt đầu sử dụng.
- Đưa các thư viện ML Kit vào Podfile của bạn:
Sau khi cài đặt hoặc cập nhật Pod của dự án, hãy nhớ mở dự án Xcode bằngpod 'Firebase/MLVision', '6.25.0' # If using an on-device API: pod 'Firebase/MLVisionTextModel', '6.25.0'
.xcworkspace
. - Trong ứng dụng của bạn, hãy nhập Firebase:
Swift
import Firebase
Objective-C
@import Firebase;
-
Nếu muốn sử dụng mô hình dựa trên đám mây và bạn chưa bật API dựa trên đám mây cho dự án của mình, hãy bật ngay:
- Mở trang API ML Kit của bảng điều khiển Firebase.
-
Nếu bạn chưa nâng cấp dự án của mình lên gói giá linh hoạt, hãy nhấp vào Nâng cấp để nâng cấp. (Bạn sẽ chỉ được nhắc nâng cấp nếu dự án của bạn không sử dụng gói linh hoạt.)
Chỉ những dự án ở cấp Blaze mới có thể sử dụng các API dựa trên đám mây.
- Nếu bạn chưa bật API dựa trên đám mây, hãy nhấp vào Bật API dựa trên đám mây.
Nếu chỉ muốn sử dụng mô hình trên thiết bị, bạn có thể bỏ qua bước này.
Bây giờ, bạn đã sẵn sàng bắt đầu nhận dạng văn bản trong hình ảnh.
Nguyên tắc về hình ảnh đầu vào
-
Để Bộ công cụ học máy nhận dạng chính xác văn bản, hình ảnh đầu vào phải chứa văn bản được biểu thị bằng đủ dữ liệu pixel. Lý tưởng nhất là đối với văn bản Latinh, mỗi ký tự phải có kích thước tối thiểu là 16x16 pixel. Đối với văn bản tiếng Trung, tiếng Nhật và tiếng Hàn (chỉ được các API dựa trên đám mây hỗ trợ), mỗi ký tự phải có kích thước 24x24 pixel. Đối với tất cả các ngôn ngữ, thường không có lợi ích nào về độ chính xác khi các ký tự lớn hơn 24x24 pixel.
Ví dụ: hình ảnh 640x480 có thể phù hợp để quét một danh thiếp chiếm toàn bộ chiều rộng của hình ảnh. Để quét một tài liệu được in trên giấy cỡ chữ, bạn có thể cần hình ảnh có kích thước 720x1280 pixel.
-
Hình ảnh bị mờ có thể làm giảm độ chính xác của tính năng nhận dạng văn bản. Nếu bạn không nhận được kết quả chấp nhận được, hãy thử yêu cầu người dùng chụp lại hình ảnh.
-
Nếu đang nhận dạng văn bản trong một ứng dụng theo thời gian thực, bạn cũng có thể muốn xem xét kích thước tổng thể của hình ảnh đầu vào. Các hình ảnh nhỏ hơn có thể được xử lý nhanh hơn, vì vậy, để giảm độ trễ, hãy chụp ảnh ở độ phân giải thấp hơn (lưu ý các yêu cầu về độ chính xác ở trên) và đảm bảo rằng văn bản chiếm phần lớn hình ảnh có thể. Ngoài ra, hãy xem Mẹo cải thiện hiệu suất theo thời gian thực.
Nhận dạng văn bản trong hình ảnh
Để nhận dạng văn bản trong hình ảnh bằng cách sử dụng mô hình trên thiết bị hoặc dựa trên đám mây, hãy chạy trình nhận dạng văn bản như mô tả bên dưới.
1. Chạy trình nhận dạng văn bản
Truyền hình ảnh dưới dạng "UIImage" hoặc "CMSampleBufferRef" vào phương thức "process(_:completion:)" của "VisionTextRecognizer":- Nhận một phiên bản của
VisionTextRecognizer
bằng cách gọionDeviceTextRecognizer
hoặccloudTextRecognizer
:Swift
Cách sử dụng mô hình trên thiết bị:
let vision = Vision.vision() let textRecognizer = vision.onDeviceTextRecognizer()
Cách sử dụng mô hình đám mây:
let vision = Vision.vision() let textRecognizer = vision.cloudTextRecognizer() // Or, to provide language hints to assist with language detection: // See https://cloud.google.com/vision/docs/languages for supported languages let options = VisionCloudTextRecognizerOptions() options.languageHints = ["en", "hi"] let textRecognizer = vision.cloudTextRecognizer(options: options)
Objective-C
Cách sử dụng mô hình trên thiết bị:
FIRVision *vision = [FIRVision vision]; FIRVisionTextRecognizer *textRecognizer = [vision onDeviceTextRecognizer];
Cách sử dụng mô hình đám mây:
FIRVision *vision = [FIRVision vision]; FIRVisionTextRecognizer *textRecognizer = [vision cloudTextRecognizer]; // Or, to provide language hints to assist with language detection: // See https://cloud.google.com/vision/docs/languages for supported languages FIRVisionCloudTextRecognizerOptions *options = [[FIRVisionCloudTextRecognizerOptions alloc] init]; options.languageHints = @[@"en", @"hi"]; FIRVisionTextRecognizer *textRecognizer = [vision cloudTextRecognizerWithOptions:options];
-
Tạo đối tượng
VisionImage
bằng cách sử dụngUIImage
hoặcCMSampleBufferRef
.Cách sử dụng
UIImage
:- Nếu cần, hãy xoay hình ảnh sao cho thuộc tính
imageOrientation
của hình ảnh là.up
. - Tạo một đối tượng
VisionImage
bằng cách sử dụngUIImage
được xoay chính xác. Không chỉ định siêu dữ liệu xoay nào – bạn phải sử dụng giá trị mặc định là.topLeft
.Swift
let image = VisionImage(image: uiImage)
Objective-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];
Cách sử dụng
CMSampleBufferRef
:-
Tạo một đối tượng
VisionImageMetadata
chỉ định hướng của dữ liệu hình ảnh có trong vùng đệmCMSampleBufferRef
.Cách lấy hướng của hình ảnh:
Swift
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 } }
Objective-C
- (FIRVisionDetectorImageOrientation) imageOrientationFromDeviceOrientation:(UIDeviceOrientation)deviceOrientation cameraPosition:(AVCaptureDevicePosition)cameraPosition { switch (deviceOrientation) { case UIDeviceOrientationPortrait: if (cameraPosition == AVCaptureDevicePositionFront) { return FIRVisionDetectorImageOrientationLeftTop; } else { return FIRVisionDetectorImageOrientationRightTop; } case UIDeviceOrientationLandscapeLeft: if (cameraPosition == AVCaptureDevicePositionFront) { return FIRVisionDetectorImageOrientationBottomLeft; } else { return FIRVisionDetectorImageOrientationTopLeft; } case UIDeviceOrientationPortraitUpsideDown: if (cameraPosition == AVCaptureDevicePositionFront) { return FIRVisionDetectorImageOrientationRightBottom; } else { return FIRVisionDetectorImageOrientationLeftBottom; } case UIDeviceOrientationLandscapeRight: if (cameraPosition == AVCaptureDevicePositionFront) { return FIRVisionDetectorImageOrientationTopRight; } else { return FIRVisionDetectorImageOrientationBottomRight; } default: return FIRVisionDetectorImageOrientationTopLeft; } }
Sau đó, hãy tạo đối tượng siêu dữ liệu:
Swift
let cameraPosition = AVCaptureDevice.Position.back // Set to the capture device you used. let metadata = VisionImageMetadata() metadata.orientation = imageOrientation( deviceOrientation: UIDevice.current.orientation, cameraPosition: cameraPosition )
Objective-C
FIRVisionImageMetadata *metadata = [[FIRVisionImageMetadata alloc] init]; AVCaptureDevicePosition cameraPosition = AVCaptureDevicePositionBack; // Set to the capture device you used. metadata.orientation = [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation cameraPosition:cameraPosition];
- Tạo một đối tượng
VisionImage
bằng đối tượngCMSampleBufferRef
và siêu dữ liệu xoay:Swift
let image = VisionImage(buffer: sampleBuffer) image.metadata = metadata
Objective-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer]; image.metadata = metadata;
- Nếu cần, hãy xoay hình ảnh sao cho thuộc tính
-
Sau đó, hãy truyền hình ảnh đến phương thức
process(_:completion:)
:Swift
textRecognizer.process(visionImage) { result, error in guard error == nil, let result = result else { // ... return } // Recognized text }
Objective-C
[textRecognizer processImage:image completion:^(FIRVisionText *_Nullable result, NSError *_Nullable error) { if (error != nil || result == nil) { // ... return; } // Recognized text }];
2. Trích xuất văn bản từ các khối văn bản được nhận dạng
Nếu thao tác nhận dạng văn bản thành công, thao tác này sẽ trả về một đối tượng [`VisionText`][VisionText]. Đối tượng `VisionText` chứa toàn bộ văn bản được nhận dạng trong hình ảnh và không hoặc nhiều đối tượng [`VisionTextBlock`][VisionTextBlock]. Mỗi `VisionTextBlock` đại diện cho một khối văn bản hình chữ nhật, chứa từ 0 đến nhiều đối tượng [`VisionTextLine`][VisionTextLine]. Mỗi đối tượng `VisionTextLine` chứa từ 0 đối tượng [`VisionTextElement`][VisionTextElement] trở lên, đại diện cho các từ và thực thể giống từ (ngày, số, v.v.). Đối với mỗi đối tượng `VisionTextBlock`, `VisionTextLine` và `VisionTextElement`, bạn có thể nhận được văn bản được nhận dạng trong khu vực và toạ độ đường viền của khu vực. Ví dụ:Swift
let resultText = result.text for block in result.blocks { let blockText = block.text let blockConfidence = block.confidence let blockLanguages = block.recognizedLanguages let blockCornerPoints = block.cornerPoints let blockFrame = block.frame for line in block.lines { let lineText = line.text let lineConfidence = line.confidence let lineLanguages = line.recognizedLanguages let lineCornerPoints = line.cornerPoints let lineFrame = line.frame for element in line.elements { let elementText = element.text let elementConfidence = element.confidence let elementLanguages = element.recognizedLanguages let elementCornerPoints = element.cornerPoints let elementFrame = element.frame } } }
Objective-C
NSString *resultText = result.text; for (FIRVisionTextBlock *block in result.blocks) { NSString *blockText = block.text; NSNumber *blockConfidence = block.confidence; NSArray<FIRVisionTextRecognizedLanguage *> *blockLanguages = block.recognizedLanguages; NSArray<NSValue *> *blockCornerPoints = block.cornerPoints; CGRect blockFrame = block.frame; for (FIRVisionTextLine *line in block.lines) { NSString *lineText = line.text; NSNumber *lineConfidence = line.confidence; NSArray<FIRVisionTextRecognizedLanguage *> *lineLanguages = line.recognizedLanguages; NSArray<NSValue *> *lineCornerPoints = line.cornerPoints; CGRect lineFrame = line.frame; for (FIRVisionTextElement *element in line.elements) { NSString *elementText = element.text; NSNumber *elementConfidence = element.confidence; NSArray<FIRVisionTextRecognizedLanguage *> *elementLanguages = element.recognizedLanguages; NSArray<NSValue *> *elementCornerPoints = element.cornerPoints; CGRect elementFrame = element.frame; } } }
Mẹo cải thiện hiệu suất theo thời gian thực
Nếu bạn muốn sử dụng mô hình trên thiết bị để nhận dạng văn bản trong một ứng dụng theo thời gian thực, hãy làm theo các nguyên tắc sau để đạt được tốc độ khung hình tốt nhất:
- Điều chỉnh tốc độ gọi đến trình nhận dạng văn bản. Nếu có một khung hình video mới trong khi trình nhận dạng văn bản đang chạy, hãy thả khung hình đó.
- Nếu bạn đang sử dụng đầu ra của trình nhận dạng văn bản để phủ đồ hoạ lên hình ảnh đầu vào, trước tiên hãy lấy kết quả từ Bộ công cụ máy học, sau đó kết xuất hình ảnh và phủ lên trong một bước. Bằng cách này, bạn chỉ cần kết xuất vào bề mặt hiển thị một lần cho mỗi khung hình đầu vào. Hãy xem các lớp previewOverlayView và FIRDetectionOverlayView trong ứng dụng mẫu giới thiệu để biết ví dụ.
- Hãy cân nhắc chụp ảnh ở độ phân giải thấp hơn. Tuy nhiên, bạn cũng cần lưu ý các yêu cầu về kích thước hình ảnh của API này.
Các bước tiếp theo
- Trước khi triển khai một ứng dụng sử dụng Cloud API cho phiên bản phát hành công khai, bạn nên thực hiện thêm một số bước để ngăn chặn và giảm thiểu ảnh hưởng của việc truy cập API trái phép.
Nhận dạng văn bản trong hình ảnh của tài liệu
Để nhận dạng văn bản của một tài liệu, hãy định cấu hình và chạy trình nhận dạng văn bản tài liệu dựa trên đám mây như mô tả bên dưới.
API nhận dạng văn bản trong tài liệu (được mô tả bên dưới) cung cấp một giao diện thuận tiện hơn khi làm việc với hình ảnh của tài liệu. Tuy nhiên, nếu muốn dùng giao diện do API văn bản thưa cung cấp, bạn có thể dùng giao diện này để quét tài liệu bằng cách định cấu hình trình nhận dạng văn bản trên đám mây để sử dụng mô hình văn bản dày đặc.
Cách sử dụng API nhận dạng văn bản trong tài liệu:
1. Chạy trình nhận dạng văn bản
Truyền hình ảnh dưới dạngUIImage
hoặc CMSampleBufferRef
đến phương thức process(_:completion:)
của VisionDocumentTextRecognizer
:
- Nhận một thực thể của
VisionDocumentTextRecognizer
bằng cách gọicloudDocumentTextRecognizer
:Swift
let vision = Vision.vision() let textRecognizer = vision.cloudDocumentTextRecognizer() // Or, to provide language hints to assist with language detection: // See https://cloud.google.com/vision/docs/languages for supported languages let options = VisionCloudDocumentTextRecognizerOptions() options.languageHints = ["en", "hi"] let textRecognizer = vision.cloudDocumentTextRecognizer(options: options)
Objective-C
FIRVision *vision = [FIRVision vision]; FIRVisionDocumentTextRecognizer *textRecognizer = [vision cloudDocumentTextRecognizer]; // Or, to provide language hints to assist with language detection: // See https://cloud.google.com/vision/docs/languages for supported languages FIRVisionCloudDocumentTextRecognizerOptions *options = [[FIRVisionCloudDocumentTextRecognizerOptions alloc] init]; options.languageHints = @[@"en", @"hi"]; FIRVisionDocumentTextRecognizer *textRecognizer = [vision cloudDocumentTextRecognizerWithOptions:options];
-
Tạo đối tượng
VisionImage
bằng cách sử dụngUIImage
hoặcCMSampleBufferRef
.Cách sử dụng
UIImage
:- Nếu cần, hãy xoay hình ảnh sao cho thuộc tính
imageOrientation
của hình ảnh là.up
. - Tạo một đối tượng
VisionImage
bằng cách sử dụngUIImage
được xoay chính xác. Không chỉ định siêu dữ liệu xoay nào – bạn phải sử dụng giá trị mặc định là.topLeft
.Swift
let image = VisionImage(image: uiImage)
Objective-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];
Cách sử dụng
CMSampleBufferRef
:-
Tạo một đối tượng
VisionImageMetadata
chỉ định hướng của dữ liệu hình ảnh có trong vùng đệmCMSampleBufferRef
.Cách lấy hướng của hình ảnh:
Swift
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 } }
Objective-C
- (FIRVisionDetectorImageOrientation) imageOrientationFromDeviceOrientation:(UIDeviceOrientation)deviceOrientation cameraPosition:(AVCaptureDevicePosition)cameraPosition { switch (deviceOrientation) { case UIDeviceOrientationPortrait: if (cameraPosition == AVCaptureDevicePositionFront) { return FIRVisionDetectorImageOrientationLeftTop; } else { return FIRVisionDetectorImageOrientationRightTop; } case UIDeviceOrientationLandscapeLeft: if (cameraPosition == AVCaptureDevicePositionFront) { return FIRVisionDetectorImageOrientationBottomLeft; } else { return FIRVisionDetectorImageOrientationTopLeft; } case UIDeviceOrientationPortraitUpsideDown: if (cameraPosition == AVCaptureDevicePositionFront) { return FIRVisionDetectorImageOrientationRightBottom; } else { return FIRVisionDetectorImageOrientationLeftBottom; } case UIDeviceOrientationLandscapeRight: if (cameraPosition == AVCaptureDevicePositionFront) { return FIRVisionDetectorImageOrientationTopRight; } else { return FIRVisionDetectorImageOrientationBottomRight; } default: return FIRVisionDetectorImageOrientationTopLeft; } }
Sau đó, hãy tạo đối tượng siêu dữ liệu:
Swift
let cameraPosition = AVCaptureDevice.Position.back // Set to the capture device you used. let metadata = VisionImageMetadata() metadata.orientation = imageOrientation( deviceOrientation: UIDevice.current.orientation, cameraPosition: cameraPosition )
Objective-C
FIRVisionImageMetadata *metadata = [[FIRVisionImageMetadata alloc] init]; AVCaptureDevicePosition cameraPosition = AVCaptureDevicePositionBack; // Set to the capture device you used. metadata.orientation = [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation cameraPosition:cameraPosition];
- Tạo một đối tượng
VisionImage
bằng đối tượngCMSampleBufferRef
và siêu dữ liệu xoay:Swift
let image = VisionImage(buffer: sampleBuffer) image.metadata = metadata
Objective-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer]; image.metadata = metadata;
- Nếu cần, hãy xoay hình ảnh sao cho thuộc tính
-
Sau đó, hãy truyền hình ảnh đến phương thức
process(_:completion:)
:Swift
textRecognizer.process(visionImage) { result, error in guard error == nil, let result = result else { // ... return } // Recognized text }
Objective-C
[textRecognizer processImage:image completion:^(FIRVisionDocumentText *_Nullable result, NSError *_Nullable error) { if (error != nil || result == nil) { // ... return; } // Recognized text }];
2. Trích xuất văn bản từ các khối văn bản được nhận dạng
Nếu hoạt động nhận dạng văn bản thành công, thì hoạt động này sẽ trả về một đối tượngVisionDocumentText
. Đối tượng VisionDocumentText
chứa toàn bộ văn bản được nhận dạng trong hình ảnh và một hệ thống phân cấp các đối tượng phản ánh cấu trúc của tài liệu được nhận dạng:
Đối với mỗi đối tượng VisionDocumentTextBlock
, VisionDocumentTextParagraph
, VisionDocumentTextWord
và VisionDocumentTextSymbol
, bạn có thể nhận được văn bản được nhận dạng trong khu vực và toạ độ đường viền của khu vực.
Ví dụ:
Swift
let resultText = result.text for block in result.blocks { let blockText = block.text let blockConfidence = block.confidence let blockRecognizedLanguages = block.recognizedLanguages let blockBreak = block.recognizedBreak let blockCornerPoints = block.cornerPoints let blockFrame = block.frame for paragraph in block.paragraphs { let paragraphText = paragraph.text let paragraphConfidence = paragraph.confidence let paragraphRecognizedLanguages = paragraph.recognizedLanguages let paragraphBreak = paragraph.recognizedBreak let paragraphCornerPoints = paragraph.cornerPoints let paragraphFrame = paragraph.frame for word in paragraph.words { let wordText = word.text let wordConfidence = word.confidence let wordRecognizedLanguages = word.recognizedLanguages let wordBreak = word.recognizedBreak let wordCornerPoints = word.cornerPoints let wordFrame = word.frame for symbol in word.symbols { let symbolText = symbol.text let symbolConfidence = symbol.confidence let symbolRecognizedLanguages = symbol.recognizedLanguages let symbolBreak = symbol.recognizedBreak let symbolCornerPoints = symbol.cornerPoints let symbolFrame = symbol.frame } } } }
Objective-C
NSString *resultText = result.text; for (FIRVisionDocumentTextBlock *block in result.blocks) { NSString *blockText = block.text; NSNumber *blockConfidence = block.confidence; NSArray<FIRVisionTextRecognizedLanguage *> *blockRecognizedLanguages = block.recognizedLanguages; FIRVisionTextRecognizedBreak *blockBreak = block.recognizedBreak; CGRect blockFrame = block.frame; for (FIRVisionDocumentTextParagraph *paragraph in block.paragraphs) { NSString *paragraphText = paragraph.text; NSNumber *paragraphConfidence = paragraph.confidence; NSArray<FIRVisionTextRecognizedLanguage *> *paragraphRecognizedLanguages = paragraph.recognizedLanguages; FIRVisionTextRecognizedBreak *paragraphBreak = paragraph.recognizedBreak; CGRect paragraphFrame = paragraph.frame; for (FIRVisionDocumentTextWord *word in paragraph.words) { NSString *wordText = word.text; NSNumber *wordConfidence = word.confidence; NSArray<FIRVisionTextRecognizedLanguage *> *wordRecognizedLanguages = word.recognizedLanguages; FIRVisionTextRecognizedBreak *wordBreak = word.recognizedBreak; CGRect wordFrame = word.frame; for (FIRVisionDocumentTextSymbol *symbol in word.symbols) { NSString *symbolText = symbol.text; NSNumber *symbolConfidence = symbol.confidence; NSArray<FIRVisionTextRecognizedLanguage *> *symbolRecognizedLanguages = symbol.recognizedLanguages; FIRVisionTextRecognizedBreak *symbolBreak = symbol.recognizedBreak; CGRect symbolFrame = symbol.frame; } } } }
Các bước tiếp theo
- Trước khi triển khai một ứng dụng sử dụng Cloud API cho phiên bản phát hành công khai, bạn nên thực hiện thêm một số bước để ngăn chặn và giảm thiểu ảnh hưởng của việc truy cập API trái phép.