Google은 흑인 공동체를 위한 인종적 평등을 추구하기 위해 노력하고 있습니다. 자세히 알아보기
이 페이지는 Cloud Translation API를 통해 번역되었습니다.
Switch to English

iOS에서 Firebase ML을 사용하여 이미지의 텍스트 인식

Firebase ML을 사용하여 이미지의 텍스트를 인식 할 수 있습니다. Firebase ML에는 도로 표지판의 텍스트와 같이 이미지의 텍스트를 인식하는 데 적합한 범용 API와 문서의 텍스트를 인식하는 데 최적화 된 API가 있습니다.

시작하기 전에

  1. 앱에 Firebase를 아직 추가하지 않은 경우 시작 안내서 의 단계에 따라 추가하십시오.
  2. Podfile에 Firebase ML을 포함하십시오.
    pod 'Firebase/MLVision'
    
    프로젝트 포드를 설치하거나 업데이트 한 후에는 .xcworkspace 사용하여 Xcode 프로젝트를 열어야합니다.
  3. 앱에서 Firebase를 가져옵니다.

    빠른

    import Firebase

    목표 -C

    @import Firebase;
  4. 프로젝트에 클라우드 기반 API를 아직 활성화하지 않은 경우 지금 설정하십시오.

    1. Firebase 콘솔의 Firebase ML API 페이지 를 엽니 다.
    2. 프로젝트를 아직 Blaze 계획으로 업그레이드하지 않은 경우 업그레이드 를 클릭하여 업그레이드 하십시오. 프로젝트가 Blaze 계획에없는 경우에만 업그레이드하라는 메시지가 표시됩니다.

      Blaze 수준의 프로젝트 만 클라우드 기반 API를 사용할 수 있습니다.

    3. 클라우드 기반 API가 아직 활성화되지 않은 경우 클라우드 기반 API 사용을 클릭 하십시오 .

이제 이미지에서 텍스트 인식을 시작할 준비가되었습니다.

입력 이미지 지침

  • Firebase ML에서 텍스트를 정확하게 인식하려면 입력 이미지에 충분한 픽셀 데이터로 표시되는 텍스트가 포함되어야합니다. 이상적으로는 라틴 텍스트의 경우 각 문자는 16x16 픽셀 이상이어야합니다. 중국어, 일본어 및 한국어 텍스트의 경우 각 문자는 24x24 픽셀이어야합니다. 모든 언어에서 문자가 24x24 픽셀보다 큰 경우 일반적으로 정확도 이점이 없습니다.

    예를 들어 640x480 이미지는 이미지의 전체 너비를 차지하는 명함을 스캔하는 데 효과적 일 수 있습니다. 레터 크기 용지에 인쇄 된 문서를 스캔하려면 720x1280 픽셀 이미지가 필요할 수 있습니다.

  • 이미지 초점이 좋지 않으면 텍스트 인식 정확도가 떨어질 수 있습니다. 만족스러운 결과를 얻지 못하면 사용자에게 이미지를 다시 캡처하도록 요청하십시오.


이미지에서 텍스트 인식

이미지에서 텍스트를 인식하려면 아래 설명에 따라 텍스트 인식기를 실행하십시오.

1. 텍스트 인식기를 실행

이미지를 UIImage 또는 CMSampleBufferRefVisionTextRecognizerprocess(_:completion:) 메소드에 전달하십시오.

  1. cloudTextRecognizer 를 호출하여 VisionTextRecognizer 인스턴스를 cloudTextRecognizer .

    빠른

    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)
    

    목표 -C

    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];
    
  2. UIImage 또는 CMSampleBufferRef 사용하여 VisionImage 객체를 만듭니다.

    UIImage 를 사용하려면

    1. 필요한 경우 imageOrientation 속성이 .up 이되도록 이미지를 회전하십시오.
    2. 올바르게 회전 된 UIImage 사용하여 VisionImage 객체를 만듭니다. 회전 메타 데이터를 지정하지 마십시오. 기본값 인 .topLeft 를 사용해야합니다.

      빠른

      let image = VisionImage(image: uiImage)

      목표 -C

      FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];

    CMSampleBufferRef 를 사용하려면 다음을 CMSampleBufferRef .

    1. CMSampleBufferRef 버퍼에 포함 된 이미지 데이터의 방향을 지정하는 VisionImageMetadata 객체를 만듭니다.

      이미지 방향을 얻으려면 :

      빠른

      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
          }
      }

      목표 -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;
        }
      }

      그런 다음 메타 데이터 개체를 만듭니다.

      빠른

      let cameraPosition = AVCaptureDevice.Position.back  // Set to the capture device you used.
      let metadata = VisionImageMetadata()
      metadata.orientation = imageOrientation(
          deviceOrientation: UIDevice.current.orientation,
          cameraPosition: cameraPosition
      )

      목표 -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];
    2. CMSampleBufferRef 객체와 회전 메타 데이터를 사용하여 VisionImage 객체를 만듭니다.

      빠른

      let image = VisionImage(buffer: sampleBuffer)
      image.metadata = metadata

      목표 -C

      FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer];
      image.metadata = metadata;
  3. 그런 다음 이미지를 process(_:completion:) 메소드에 전달하십시오.

    빠른

    textRecognizer.process(visionImage) { result, error in
      guard error == nil, let result = result else {
        // ...
        return
      }
    
      // Recognized text
    }
    

    목표 -C

    [textRecognizer processImage:image
                      completion:^(FIRVisionText *_Nullable result,
                                   NSError *_Nullable error) {
      if (error != nil || result == nil) {
        // ...
        return;
      }
    
      // Recognized text
    }];
    

2. 인식 된 텍스트 블록에서 텍스트 추출

텍스트 인식 작업이 성공하면 VisionText 객체를 반환합니다. VisionText 객체는 이미지에서 인식 된 전체 텍스트와 0 개 이상의 VisionTextBlock 객체를 포함합니다.

VisionTextBlock 은 0 개 이상의 VisionTextLine 객체를 포함하는 직사각형 텍스트 블록을 나타냅니다. 각 VisionTextLine 객체에는 0 개 이상의 VisionTextElement 객체가 포함되며, 단어 및 단어와 같은 엔터티 (날짜, 숫자 등)를 나타냅니다.

VisionTextBlock , VisionTextLineVisionTextElement 객체에 대해 영역에서 인식 된 텍스트와 영역의 경계 좌표를 얻을 수 있습니다.

예를 들면 다음과 같습니다.

빠른

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
        }
    }
}

목표 -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;
    }
  }
}

다음 단계


문서 이미지에서 텍스트 인식

문서의 텍스트를 인식하려면 아래 설명에 따라 문서 텍스트 인식기를 구성하고 실행하십시오.

아래에 설명 된 문서 텍스트 인식 API는 문서 이미지 작업에보다 편리한 인터페이스를 제공합니다. 그러나 스파 스 텍스트 API가 제공하는 인터페이스를 선호하는 경우 짙은 텍스트 모델사용 하도록 클라우드 텍스트 인식기를 구성하여 대신 문서를 스캔 할 수 있습니다.

문서 텍스트 인식 API를 사용하려면

1. 텍스트 인식기를 실행

이미지를 UIImage 또는 CMSampleBufferRefVisionDocumentTextRecognizerprocess(_:completion:) 메소드에 전달하십시오.

  1. VisionDocumentTextRecognizer 를 호출하여 VisionDocumentTextRecognizer 인스턴스를 VisionDocumentTextRecognizer cloudDocumentTextRecognizer .

    빠른

    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)
    

    목표 -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];
    
  2. UIImage 또는 CMSampleBufferRef 사용하여 VisionImage 객체를 만듭니다.

    UIImage 를 사용하려면

    1. 필요한 경우 imageOrientation 속성이 .up 이되도록 이미지를 회전하십시오.
    2. 올바르게 회전 된 UIImage 사용하여 VisionImage 객체를 만듭니다. 회전 메타 데이터를 지정하지 마십시오. 기본값 인 .topLeft 를 사용해야합니다.

      빠른

      let image = VisionImage(image: uiImage)

      목표 -C

      FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];

    CMSampleBufferRef 를 사용하려면 다음을 CMSampleBufferRef .

    1. CMSampleBufferRef 버퍼에 포함 된 이미지 데이터의 방향을 지정하는 VisionImageMetadata 객체를 만듭니다.

      이미지 방향을 얻으려면 :

      빠른

      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
          }
      }

      목표 -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;
        }
      }

      그런 다음 메타 데이터 개체를 만듭니다.

      빠른

      let cameraPosition = AVCaptureDevice.Position.back  // Set to the capture device you used.
      let metadata = VisionImageMetadata()
      metadata.orientation = imageOrientation(
          deviceOrientation: UIDevice.current.orientation,
          cameraPosition: cameraPosition
      )

      목표 -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];
    2. CMSampleBufferRef 객체와 회전 메타 데이터를 사용하여 VisionImage 객체를 만듭니다.

      빠른

      let image = VisionImage(buffer: sampleBuffer)
      image.metadata = metadata

      목표 -C

      FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer];
      image.metadata = metadata;
  3. 그런 다음 이미지를 process(_:completion:) 메소드에 전달하십시오.

    빠른

    textRecognizer.process(visionImage) { result, error in
      guard error == nil, let result = result else {
        // ...
        return
      }
    
      // Recognized text
    }
    

    목표 -C

    [textRecognizer processImage:image
                      completion:^(FIRVisionDocumentText *_Nullable result,
                                   NSError *_Nullable error) {
      if (error != nil || result == nil) {
        // ...
        return;
      }
    
        // Recognized text
    }];
    

2. 인식 된 텍스트 블록에서 텍스트 추출

텍스트 인식 작업이 성공하면 VisionDocumentText 객체를 반환합니다. VisionDocumentText 객체에는 이미지에서 인식되는 전체 텍스트와 인식 된 문서의 구조를 반영하는 객체 계층이 포함됩니다.

VisionDocumentTextBlock , VisionDocumentTextParagraph , VisionDocumentTextWordVisionDocumentTextSymbol 객체에 대해 영역에서 인식 된 텍스트와 영역의 경계 좌표를 얻을 수 있습니다.

예를 들면 다음과 같습니다.

빠른

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
            }
        }
    }
}

목표 -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;
      }
    }
  }
}

다음 단계