텍스트 및 얼굴 특징 인식 ML Kit: iOS

1. 소개

ML Kit는 강력하고 사용하기 쉬운 패키지로 Android 및 iOS 앱에 Google의 머신러닝 전문 지식을 적용하는 모바일 SDK입니다. 머신러닝 분야에 경험이 있든 없든 코드 몇 줄만 작성하면 필요한 기능을 쉽게 구현할 수 있습니다. 따라서 신경망이나 모델 최적화에 대한 심층적인 지식 없이도 시작할 수 있습니다.

어떤 방식으로 작동되나요?

ML Kit를 사용하면 Mobile VisionTensorFlow Lite와 같은 Google의 ML 기술을 단일 SDK에 통합하여 앱에서 ML 기법을 쉽게 적용할 수 있습니다. Mobile Vision의 기기 내 모델의 실시간 기능이 필요하든, 맞춤 TensorFlow Lite 이미지 분류 모델의 유연성이 필요하든, ML Kit를 사용하면 단 몇 줄의 코드로 가능합니다.

이 Codelab에서는 이미지에서 텍스트와 얼굴 특징을 자동으로 감지할 수 있는 자체 iOS 앱을 만드는 방법을 안내합니다.

빌드할 항목

이 Codelab에서는 ML Kit을 사용하여 iOS 앱을 빌드합니다. 이 앱에는 아래의 기능이 있습니다.

  • ML Kit Text Recognition API를 사용하여 이미지에서 텍스트 감지
  • ML Kit 얼굴 인식 API를 사용하여 이미지에서 얼굴 특징 식별

ML Kit 얼굴 인식 API를 시연하는 그레이스 호퍼의 이미지텍스트 인식 API를 보여주는 잔디밭의 표지판 이미지

학습할 내용

  • ML Kit SDK를 사용하여 텍스트 인식, 얼굴 특징 감지와 같은 고급 머신러닝 기능을 iOS 앱에 쉽게 추가하는 방법

필요한 항목

  • 최신 버전의 Xcode (v12.4 이상)
  • iOS 시뮬레이터 또는 iOS 10.0 이상을 실행하는 실제 iOS 기기
  • ML Kit는 x86_64arm64의 두 가지 64비트 아키텍처만 지원합니다.
  • 샘플 코드
  • Swift를 사용한 iOS 개발에 관한 기본 지식
  • 머신러닝 모델에 대한 기본적인 이해

이 Codelab에서는 ML Kit에 중점을 둡니다. 따라서 이와 관련 없는 개념과 코드 블록은 그냥 넘어가겠습니다. 단, 필요할 때 복사해서 붙여넣을 수 있도록 다른 설명 없이 제공만 해드리겠습니다.

2. 설정

코드 다운로드

다음 링크를 클릭하면 이 Codelab의 모든 코드를 다운로드할 수 있습니다.

다운로드한 ZIP 파일의 압축을 해제합니다. 그러면 필요한 모든 리소스가 포함된 루트 폴더 (mlkit-ios-codelab)가 생성됩니다. 이 Codelab에서는 vision 하위 디렉터리의 리소스만 필요합니다.

mlkit-ios-codelab 저장소의 vision 하위 디렉터리에는 다음 두 디렉터리가 포함됩니다.

  • android_studio_folder.pngstarter: 이 Codelab에서 빌드할 시작 코드입니다.
  • android_studio_folder.pngfinal: 완성된 샘플 앱의 완료된 코드입니다.

CocoaPods를 사용하여 ML Kit 종속 항목 추가

CocoaPods는 앱에 ML Kit 종속 항목을 추가하는 데 사용됩니다. 머신에 CocoaPods가 설치되어 있지 않다면 여기에서 설치 안내를 확인하세요. 설치가 완료되면 즐겨 사용하는 편집기에서 Podfile을 열고 ML Kit을 종속 항목으로 추가합니다.

Podfile

platform :ios, '10.0'
use_frameworks!

pod 'GoogleMLKit/FaceDetection'
pod 'GoogleMLKit/TextRecognition'

target 'MLKit-codelab' do
end

ML Kit Cocoa Pod 설치

앱에서 모든 종속 항목을 사용할 수 있도록 하려면 명령줄을 사용하여 ML Kit Cocoa Pods를 설치해야 합니다.

명령줄

# Make sure you are in the root of your app
pod install
xed .

3. 시작 앱 실행

이제 앱을 처음으로 실행할 수 있습니다. Xcode에서 98205811bbed9d74.pngRun을 클릭하여 앱을 컴파일하고 iOS 시뮬레이터에서 실행합니다.

시뮬레이터에서 앱이 실행됩니다. 이 시점에서 두 이미지 중에서 선택할 수 있는 선택기가 있는 기본 레이아웃이 표시됩니다. 다음 섹션에서는 앱에 텍스트 인식을 추가하여 이미지의 텍스트를 식별합니다.

4. 온디바이스 텍스트 인식 추가

이 단계에서는 이미지의 텍스트를 인식하는 기능을 앱에 추가합니다.

MLVision 모듈 가져오기

ViewController 클래스에 다음 가져오기가 있는지 확인합니다.

ViewController.swift

import MLKit

VisionTextRecognizer 만들기

ViewController 클래스에 다음 지연 속성을 추가합니다.

ViewController.swift

private lazy var textRecognizer = TextRecognizer.textRecognizer()

이미지에서 온디바이스 텍스트 인식 설정 및 실행

ViewController 클래스의 runTextRecognition 메서드에 다음을 추가합니다.

ViewController.swift

func runTextRecognition(with image: UIImage) {
  let visionImage = VisionImage(image: image)
  textRecognizer.process(visionImage) { features, error in
    self.processResult(from: features, error: error)
  }
}

위 코드는 텍스트 인식 감지기를 구성하고 응답과 함께 processResult(from:, error:) 함수를 호출합니다.

텍스트 인식 응답 처리

ViewController 클래스의 processResult에 다음 코드를 추가하여 결과를 파싱하고 앱에 표시합니다.

ViewController.swift

 func processResult(from text: Text?, error: Error?) {
    removeDetectionAnnotations()
    guard error == nil, let text = text else {
      let errorString = error?.localizedDescription ?? Constants.detectionNoResultsMessage
      print("Text recognizer failed with error: \(errorString)")
      return
    }

    let transform = self.transformMatrix()

    // Blocks.
    for block in text.blocks {
      drawFrame(block.frame, in: .purple, transform: transform)

      // Lines.
      for line in block.lines {
        drawFrame(line.frame, in: .orange, transform: transform)

        // Elements.
        for element in line.elements {
          drawFrame(element.frame, in: .green, transform: transform)

          let transformedRect = element.frame.applying(transform)
          let label = UILabel(frame: transformedRect)
          label.text = element.text
          label.adjustsFontSizeToFitWidth = true
          self.annotationOverlayView.addSubview(label)
        }
      }
    }
  }

시뮬레이터에서 앱 실행

이제 Xcode에서 98205811bbed9d74.png실행을 클릭합니다. 앱이 로드되면 선택기에서 Image 1가 선택되어 있는지 확인하고 Find Text 버튼을 클릭합니다.

이제 앱이 아래 이미지와 같이 텍스트 인식 결과와 경계 상자가 원본 이미지 위에 오버레이되어 표시됩니다.

7269fd8fcb4dc793.png

사진: Kai Schreiber / Wikimedia Commons / CC BY-SA 2.0

축하합니다. ML Kit를 사용하여 앱에 기기 내 텍스트 인식을 추가했습니다. On-Device 텍스트 인식은 앱이 인터넷에 연결되어 있지 않을 때도 작동하고 정지 이미지와 라이브 동영상 프레임에서 사용할 수 있을 만큼 빠르므로 다양한 사용 사례에 적합합니다.

5. 기기 내 얼굴 윤곽 감지 추가

이 단계에서는 이미지에서 얼굴의 윤곽을 감지하는 기능을 앱에 추가합니다.

FaceDetector 만들기

ViewController 클래스에 다음 지연 속성을 추가합니다.

ViewController.swift

private lazy var faceDetectorOption: FaceDetectorOptions = {
  let option = FaceDetectorOptions()
  option.contourMode = .all
  option.performanceMode = .fast
  return option
}()
private lazy var faceDetector = FaceDetector.faceDetector(options: faceDetectorOption)

이미지에서 온디바이스 얼굴 윤곽 감지 설정 및 실행

ViewController 클래스의 runFaceContourDetection 메서드에 다음을 추가합니다.

ViewController.swift

  func runFaceContourDetection(with image: UIImage) {
    let visionImage = VisionImage(image: image)
    faceDetector.process(visionImage) { features, error in
      self.processResult(from: features, error: error)
    }
  }

위 코드는 텍스트 인식 감지기를 구성하고 응답과 함께 processResult(from:, error:) 함수를 호출합니다.

얼굴 인식기 응답 처리

ViewController 클래스의 processResult에 다음 코드를 추가하여 결과를 파싱하고 앱에 표시합니다.

ViewController.swift

  func processResult(from faces: [Face]?, error: Error?) {
    removeDetectionAnnotations()
    guard let faces = faces else {
      return
    }

    for feature in faces {
      let transform = self.transformMatrix()
      let transformedRect = feature.frame.applying(transform)
      UIUtilities.addRectangle(
        transformedRect,
        to: self.annotationOverlayView,
        color: UIColor.green
      )
      self.addContours(forFace: feature, transform: transform)
    }
  }

마지막으로 ViewController 클래스에 도우미 메서드 addContours를 추가하여 윤곽선 포인트를 그립니다.

ViewController.swift

 private func addContours(forFace face: Face, transform: CGAffineTransform) {
    // Face
    if let faceContour = face.contour(ofType: .face) {
      for point in faceContour.points {
        drawPoint(point, in: .blue, transform: transform)
      }
    }

    // Eyebrows
    if let topLeftEyebrowContour = face.contour(ofType: .leftEyebrowTop) {
      for point in topLeftEyebrowContour.points {
        drawPoint(point, in: .orange, transform: transform)
      }
    }
    if let bottomLeftEyebrowContour = face.contour(ofType: .leftEyebrowBottom) {
      for point in bottomLeftEyebrowContour.points {
        drawPoint(point, in: .orange, transform: transform)
      }
    }
    if let topRightEyebrowContour = face.contour(ofType: .rightEyebrowTop) {
      for point in topRightEyebrowContour.points {
        drawPoint(point, in: .orange, transform: transform)
      }
    }
    if let bottomRightEyebrowContour = face.contour(ofType: .rightEyebrowBottom) {
      for point in bottomRightEyebrowContour.points {
        drawPoint(point, in: .orange, transform: transform)
      }
    }

    // Eyes
    if let leftEyeContour = face.contour(ofType: .leftEye) {
      for point in leftEyeContour.points {
        drawPoint(point, in: .cyan, transform: transform)
      }
    }
    if let rightEyeContour = face.contour(ofType: .rightEye) {
      for point in rightEyeContour.points {
        drawPoint(point, in: .cyan, transform: transform)
      }
    }

    // Lips
    if let topUpperLipContour = face.contour(ofType: .upperLipTop) {
      for point in topUpperLipContour.points {
        drawPoint(point, in: .red, transform: transform)
      }
    }
    if let bottomUpperLipContour = face.contour(ofType: .upperLipBottom) {
      for point in bottomUpperLipContour.points {
        drawPoint(point, in: .red, transform: transform)
      }
    }
    if let topLowerLipContour = face.contour(ofType: .lowerLipTop) {
      for point in topLowerLipContour.points {
        drawPoint(point, in: .red, transform: transform)
      }
    }
    if let bottomLowerLipContour = face.contour(ofType: .lowerLipBottom) {
      for point in bottomLowerLipContour.points {
        drawPoint(point, in: .red, transform: transform)
      }
    }

    // Nose
    if let noseBridgeContour = face.contour(ofType: .noseBridge) {
      for point in noseBridgeContour.points {
        drawPoint(point, in: .yellow, transform: transform)
      }
    }
    if let noseBottomContour = face.contour(ofType: .noseBottom) {
      for point in noseBottomContour.points {
        drawPoint(point, in: .yellow, transform: transform)
      }
    }
  }

시뮬레이터에서 앱 실행

이제 Xcode에서 98205811bbed9d74.png실행을 클릭합니다. 앱이 로드되면 선택기에서 Image 2가 선택되어 있는지 확인하고 Find Face Contour 버튼을 클릭합니다. 이제 앱이 아래 이미지와 같이 표시됩니다. 그레이스 호퍼의 얼굴 윤곽이 원본 이미지 위에 오버레이된 점으로 표시됩니다.

a5169b50dafbcb2f.png

축하합니다. 기기 내 ML Kit를 사용하여 앱에 기기 내 얼굴 윤곽 감지를 추가했습니다. 기기 내 ML Kit 얼굴 윤곽 감지는 앱에 인터넷 연결이 없어도 작동하고 정지 이미지와 실시간 동영상 프레임에서 사용할 수 있을 만큼 빠르기 때문에 다양한 사용 사례에 적합합니다.

6. 축하합니다.

ML Kit를 사용하여 앱에 고급 머신러닝 기능을 쉽게 추가했습니다.

학습한 내용

  • iOS 앱에 ML Kit를 추가하는 방법
  • ML Kit에서 기기 내 텍스트 인식을 사용하여 이미지에서 텍스트를 찾는 방법
  • ML Kit에서 기기 내 얼굴 인식을 사용하여 이미지의 얼굴 특징을 식별하는 방법

다음 단계

  • 자체 iOS 앱에서 ML Kit을 사용합니다.

자세히 알아보기

  • https://g.co/mlkit