ML Kit를 사용하여 도로 표지판 텍스트와 같은 이미지 또는 동영상 속 텍스트를 인식할 수 있습니다. 이 기능의 주요 특징은 다음과 같습니다.
| Text Recognition v2 API | |
|---|---|
| 설명 | 이미지 또는 동영상의 텍스트를 인식하고 라틴어, 중국어, 데바나가리, 일본어, 한국어 스크립트와 다양한 언어를 지원합니다. |
| SDK 이름 | GoogleMLKit/TextRecognition |
| 구현 | 애셋은 빌드 시 앱에 정적으로 연결됩니다. |
| 앱 크기 영향 | 스크립트 SDK당 약 38MB |
| 성능 | 라틴어 스크립트 SDK의 경우 대부분의 기기에서 실시간으로, 그 외의 경우에는 더 느리게 작동합니다. |
사용해 보기
시작하기 전에
- Podfile에 다음 ML Kit 포드를 포함합니다.
# To recognize Latin script pod 'GoogleMLKit/TextRecognition', '8.0.0' # To recognize Chinese script pod 'GoogleMLKit/TextRecognitionChinese', '8.0.0' # To recognize Devanagari script pod 'GoogleMLKit/TextRecognitionDevanagari', '8.0.0' # To recognize Japanese script pod 'GoogleMLKit/TextRecognitionJapanese', '8.0.0' # To recognize Korean script pod 'GoogleMLKit/TextRecognitionKorean', '8.0.0'
- 프로젝트의 포드를 설치하거나 업데이트한 후
.xcworkspace를 사용하여 Xcode 프로젝트를 엽니다. ML Kit는 Xcode 버전 12.4 이상에서 지원됩니다.
1. TextRecognizer 인스턴스 만들기
+textRecognizer(options:)를 호출하여 TextRecognizer의 인스턴스를 만들고 위에서 종속 항목으로 선언한 SDK와 관련된 옵션을 전달합니다.
Swift
// When using Latin script recognition SDK let latinOptions = TextRecognizerOptions() let latinTextRecognizer = TextRecognizer.textRecognizer(options:options) // When using Chinese script recognition SDK let chineseOptions = ChineseTextRecognizerOptions() let chineseTextRecognizer = TextRecognizer.textRecognizer(options:options) // When using Devanagari script recognition SDK let devanagariOptions = DevanagariTextRecognizerOptions() let devanagariTextRecognizer = TextRecognizer.textRecognizer(options:options) // When using Japanese script recognition SDK let japaneseOptions = JapaneseTextRecognizerOptions() let japaneseTextRecognizer = TextRecognizer.textRecognizer(options:options) // When using Korean script recognition SDK let koreanOptions = KoreanTextRecognizerOptions() let koreanTextRecognizer = TextRecognizer.textRecognizer(options:options)
Objective-C
// When using Latin script recognition SDK MLKTextRecognizerOptions *latinOptions = [[MLKTextRecognizerOptions alloc] init]; MLKTextRecognizer *latinTextRecognizer = [MLKTextRecognizer textRecognizerWithOptions:options]; // When using Chinese script recognition SDK MLKChineseTextRecognizerOptions *chineseOptions = [[MLKChineseTextRecognizerOptions alloc] init]; MLKTextRecognizer *chineseTextRecognizer = [MLKTextRecognizer textRecognizerWithOptions:options]; // When using Devanagari script recognition SDK MLKDevanagariTextRecognizerOptions *devanagariOptions = [[MLKDevanagariTextRecognizerOptions alloc] init]; MLKTextRecognizer *devanagariTextRecognizer = [MLKTextRecognizer textRecognizerWithOptions:options]; // When using Japanese script recognition SDK MLKJapaneseTextRecognizerOptions *japaneseOptions = [[MLKJapaneseTextRecognizerOptions alloc] init]; MLKTextRecognizer *japaneseTextRecognizer = [MLKTextRecognizer textRecognizerWithOptions:options]; // When using Korean script recognition SDK MLKKoreanTextRecognizerOptions *koreanOptions = [[MLKKoreanTextRecognizerOptions alloc] init]; MLKTextRecognizer *koreanTextRecognizer = [MLKTextRecognizer textRecognizerWithOptions:options];
2. 입력 이미지 준비
이미지를UIImage 또는 CMSampleBufferRef로 TextRecognizer의 process(_:completion:) 메서드에 전달합니다.
UIImage 또는 CMSampleBuffer를 사용하여 VisionImage 객체를 만듭니다.
UIImage를 사용하는 경우 다음 단계를 따르세요.
UIImage를 사용하여VisionImage객체를 만듭니다. 올바른.orientation를 지정해야 합니다.Swift
let image = VisionImage(image: UIImage) visionImage.orientation = image.imageOrientation
Objective-C
MLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image]; visionImage.orientation = image.imageOrientation;
CMSampleBuffer를 사용하는 경우 다음 단계를 따르세요.
-
CMSampleBuffer에 포함된 이미지 데이터의 방향을 지정합니다.이미지 방향을 가져오는 방법은 다음과 같습니다.
Swift
func imageOrientation( deviceOrientation: UIDeviceOrientation, cameraPosition: AVCaptureDevice.Position ) -> UIImage.Orientation { switch deviceOrientation { case .portrait: return cameraPosition == .front ? .leftMirrored : .right case .landscapeLeft: return cameraPosition == .front ? .downMirrored : .up case .portraitUpsideDown: return cameraPosition == .front ? .rightMirrored : .left case .landscapeRight: return cameraPosition == .front ? .upMirrored : .down case .faceDown, .faceUp, .unknown: return .up } }
Objective-C
- (UIImageOrientation) imageOrientationFromDeviceOrientation:(UIDeviceOrientation)deviceOrientation cameraPosition:(AVCaptureDevicePosition)cameraPosition { switch (deviceOrientation) { case UIDeviceOrientationPortrait: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationLeftMirrored : UIImageOrientationRight; case UIDeviceOrientationLandscapeLeft: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationDownMirrored : UIImageOrientationUp; case UIDeviceOrientationPortraitUpsideDown: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationRightMirrored : UIImageOrientationLeft; case UIDeviceOrientationLandscapeRight: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationUpMirrored : UIImageOrientationDown; case UIDeviceOrientationUnknown: case UIDeviceOrientationFaceUp: case UIDeviceOrientationFaceDown: return UIImageOrientationUp; } }
CMSampleBuffer객체와 방향을 사용하여VisionImage객체를 만듭니다.Swift
let image = VisionImage(buffer: sampleBuffer) image.orientation = imageOrientation( deviceOrientation: UIDevice.current.orientation, cameraPosition: cameraPosition)
Objective-C
MLKVisionImage *image = [[MLKVisionImage alloc] initWithBuffer:sampleBuffer]; image.orientation = [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation cameraPosition:cameraPosition];
3. 이미지 처리
이제 이미지를 process(_:completion:) 메서드에 전달합니다.
Swift
textRecognizer.process(visionImage) { result, error in
guard error == nil, let result = result else {
// Error handling
return
}
// Recognized text
}Objective-C
[textRecognizer processImage:image completion:^(MLKText *_Nullable result, NSError *_Nullable error) { if (error != nil || result == nil) { // Error handling return; } // Recognized text }];
4. 인식된 텍스트 블록에서 텍스트 추출
텍스트 인식 작업이 성공하면 Text 객체가 반환됩니다. Text 객체는 이미지에서 인식된 전체 텍스트 및 0개 이상의 TextBlock 객체를 포함합니다.
각 TextBlock은 TextLine 객체를 0개 이상 포함하는 사각형 모양의 텍스트 블록을 나타냅니다. 각 TextLine 객체는 단어 및 단어와 유사한 항목(날짜, 숫자 등)을 나타내는 TextElement 객체를 0개 이상 포함합니다.
각 TextBlock, TextLine, TextElement 객체에 대해 해당 영역에서 인식된 텍스트와 영역의 경계 좌표를 가져올 수 있습니다.
예를 들면 다음과 같습니다.
Swift
let resultText = result.text
for block in result.blocks {
let blockText = block.text
let blockLanguages = block.recognizedLanguages
let blockCornerPoints = block.cornerPoints
let blockFrame = block.frame
for line in block.lines {
let lineText = line.text
let lineLanguages = line.recognizedLanguages
let lineCornerPoints = line.cornerPoints
let lineFrame = line.frame
for element in line.elements {
let elementText = element.text
let elementCornerPoints = element.cornerPoints
let elementFrame = element.frame
}
}
}Objective-C
NSString *resultText = result.text;
for (MLKTextBlock *block in result.blocks) {
NSString *blockText = block.text;
NSArray<MLKTextRecognizedLanguage *> *blockLanguages = block.recognizedLanguages;
NSArray<NSValue *> *blockCornerPoints = block.cornerPoints;
CGRect blockFrame = block.frame;
for (MLKTextLine *line in block.lines) {
NSString *lineText = line.text;
NSArray<MLKTextRecognizedLanguage *> *lineLanguages = line.recognizedLanguages;
NSArray<NSValue *> *lineCornerPoints = line.cornerPoints;
CGRect lineFrame = line.frame;
for (MLKTextElement *element in line.elements) {
NSString *elementText = element.text;
NSArray<NSValue *> *elementCornerPoints = element.cornerPoints;
CGRect elementFrame = element.frame;
}
}
}입력 이미지 가이드라인
-
ML Kit가 텍스트를 정확하게 인식하려면 입력 이미지에 충분한 픽셀 데이터로 표시된 텍스트가 있어야 합니다. 각 문자가 16x16픽셀 이상이어야 좋습니다. 일반적으로 문자가 24x24픽셀보다 크면 정확도가 더 이상 향상되지 않습니다.
예를 들어 이미지의 전체 너비를 차지하는 명함을 스캔하려면 640x480픽셀 이미지가 적합합니다. 레터 사이즈 용지에 인쇄된 문서 스캔은 720x1280픽셀 이미지가 적합합니다.
-
이미지 초점이 잘 맞지 않으면 텍스트 인식 정확도에 영향을 미칠 수 있습니다. 인식 결과가 만족스럽지 않다면 사용자가 이미지를 다시 캡처하도록 요청합니다.
-
실시간 애플리케이션에서 텍스트를 인식하는 경우 입력 이미지의 전체 크기를 고려해야 합니다. 이미지 크기가 작을수록 더 빠르게 처리될 수 있습니다. 지연 시간을 줄이려면 텍스트가 가능한 한 많은 이미지를 차지하도록 하고 위의 정확도 요구사항에 유의하여 낮은 해상도에서 이미지를 캡처합니다. 자세한 내용은 성능 개선을 위한 도움말을 참고하세요.
실적 개선을 위한 팁
- 동영상 프레임을 처리하려면 감지기의
results(in:)동기 API를 사용합니다.AVCaptureVideoDataOutputSampleBufferDelegate의captureOutput(_, didOutput:from:)함수에서 이 메서드를 호출하여 지정된 동영상 프레임에서 동기식으로 결과를 가져옵니다.AVCaptureVideoDataOutput의alwaysDiscardsLateVideoFrames를true로 유지하여 감지기 호출을 제한합니다. 인식기가 실행 중일 때 새 동영상 프레임이 제공되는 경우 해당 프레임이 삭제됩니다. - 인식기 출력을 사용해서 입력 이미지에서 그래픽을 오버레이하는 경우 먼저 ML Kit에서 결과를 가져온 후 이미지를 렌더링하고 단일 단계로 오버레이합니다. 이렇게 하면 처리된 입력 프레임별로 한 번만 디스플레이 표면에 렌더링됩니다. 관련 예시는 ML Kit 빠른 시작 샘플에서 updatePreviewOverlayViewWithLastFrame을 참조하세요.
- 낮은 해상도에서 이미지 캡처를 고려합니다. 단, API의 이미지 크기 요구사항도 유의해야 합니다.
- 잠재적인 성능 저하를 방지하려면 스크립트 옵션이 다른 여러
TextRecognizer인스턴스를 동시에 실행하지 마세요.