iOS에서 ML Kit를 사용하여 이미지 속 텍스트 인식

ML Kit를 사용하여 이미지나 동영상 속 텍스트(예: 표지판이 있더군요. 이 기능의 주요 특징은 다음과 같습니다.

텍스트 인식 v2 API
설명이미지나 동영상 속 텍스트 인식, 라틴어, 중국어, 데바나가리 문자, 일본어 및 한국어 문자와 다양한 언어 지원
SDK 이름GoogleMLKit/TextRecognition
GoogleMLKit/TextRecognitionChinese
GoogleMLKit/TextRecognitionDevanagari
GoogleMLKit/TextRecognitionJapanese
GoogleMLKit/TextRecognitionKorean
구현애셋은 빌드 시간에 앱에 정적으로 연결됩니다.
앱 크기 영향스크립트 SDK당 약 38MB
성능라틴 스크립트 SDK의 경우 대부분의 기기에서 실시간이지만 다른 기기에서는 더 느립니다.

사용해 보기

  • 샘플 앱을 사용하여 이 API의 사용 예를 참조하세요.
  • Codelab을 참고하세요.

시작하기 전에

  1. Podfile에 다음 ML Kit 포드를 포함합니다.
    # To recognize Latin script
    pod 'GoogleMLKit/TextRecognition', '3.2.0'
    # To recognize Chinese script
    pod 'GoogleMLKit/TextRecognitionChinese', '3.2.0'
    # To recognize Devanagari script
    pod 'GoogleMLKit/TextRecognitionDevanagari', '3.2.0'
    # To recognize Japanese script
    pod 'GoogleMLKit/TextRecognitionJapanese', '3.2.0'
    # To recognize Korean script
    pod 'GoogleMLKit/TextRecognitionKorean', '3.2.0'
    
  2. 프로젝트의 포드를 설치하거나 업데이트한 후 포드를 사용하여 Xcode 프로젝트를 엽니다. .xcworkspace ML Kit는 Xcode 버전 12.4 이상에서 지원됩니다.

1. TextRecognizer 인스턴스 만들기

다음을 호출하여 TextRecognizer의 인스턴스를 만듭니다. +textRecognizer(options:): 선언한 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 또는 CMSampleBufferRefTextRecognizerprocess(_:completion:) 메서드:

VisionImage 객체를 UIImage 또는 CMSampleBuffer입니다.

UIImage를 사용하는 경우 다음 단계를 따르세요.

  • UIImageVisionImage 객체를 만듭니다. 올바른 .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;
      }
    }
          
  • 다음을 사용하여 VisionImage 객체를 만듭니다. CMSampleBuffer 객체 및 방향:

    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는 직사각형 형태의 텍스트 블록을 나타냅니다. 0개 이상의 TextLine 객체를 포함합니다. TextLine마다 객체에는 0개 이상의 TextElement 객체가 포함됩니다. 단어 및 단어와 유사한 항목(예: 날짜 및 숫자)을 나타냅니다.

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님의 alwaysDiscardsLateVideoFramestrue로 설정하여 감지기 호출을 제한합니다. 새 동영상 프레임은 감지기가 실행되는 동안 사용할 수 있게 되면 삭제됩니다.
  • 감지기 출력을 사용하여 그래픽 이미지를 먼저 ML Kit에서 결과를 가져온 후 이미지를 하나의 단계로 오버레이할 수 있습니다. 이렇게 하면 처리되어야 합니다 자세한 내용은 updatePreviewOverlayViewWithLastFrame을 를 참조하세요.
  • 낮은 해상도에서 이미지를 캡처하는 것이 좋습니다. 그러나 명심해야 할 점은 이 API의 이미지 크기 요구사항입니다.
  • 성능 저하를 방지하려면 한 번에 여러 개의 다른 스크립트 옵션을 동시에 사용하는 TextRecognizer 인스턴스