ML Kit를 사용하여 이미지에서 객체 감지: Android

1. 시작하기 전에

ML Kit는 Android 및 iOS 앱에 Google의 기기 내 머신러닝 전문 지식을 적용하는 모바일 SDK입니다. 강력하면서도 사용하기 쉬운 Vision 및 Natural Language API를 사용하여 앱의 일반적인 문제를 해결하거나 완전히 새로운 사용자 환경을 만들 수 있습니다. 모두 Google의 동급 최고 ML 모델을 기반으로 하며 무료로 제공됩니다.

ML Kit의 API는 모두 기기에서 실행되므로 실시간 카메라 스트림을 처리해야 하는 실시간 사용 사례를 지원할 수 있습니다. 즉, 이 기능은 오프라인에서도 사용할 수 있습니다.

이 Codelab에서는 기존 Android 앱에 특정 이미지의 객체 감지 및 추적 (ODT)을 추가하는 간단한 단계를 안내합니다. 이 Codelab에서는 ML Kit ODT 사용을 강조하기 위해 몇 가지 바로가기를 사용합니다.

빌드할 항목

이 Codelab에서는 ML Kit를 사용하여 Android 앱을 빌드합니다. 앱이 ML Kit 객체 감지 및 추적 API를 사용하여 지정된 이미지에서 객체를 감지합니다.완료되면 오른쪽 이미지와 유사한 이미지가 표시됩니다.

학습할 내용

  • ML Kit SDK를 Android 애플리케이션에 통합하는 방법
  • ML Kit 객체 감지 및 추적 API

필요한 항목

  • Android 스튜디오의 최신 버전 (v4.1.2 이상)
  • Android 스튜디오 에뮬레이터 또는 실제 Android 기기
  • 샘플 코드
  • Kotlin 기반 Android 개발에 관한 기본 지식

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

2. 설정

코드 다운로드

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

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

mlkit-android 저장소의 object-detection 하위 디렉터리에는 다음 두 디렉터리가 포함됩니다.

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

3. 프로젝트에 ML Kit 객체 감지 및 추적 API 추가

Android 스튜디오로 앱 가져오기

먼저 시작 앱을 Android 스튜디오로 가져옵니다.

Android 스튜디오를 열고 Import Project (Gradle, Eclipse ADT, etc.)를 선택한 다음 이전에 다운로드한 소스 코드에서 starter 폴더를 선택합니다.

7c0f27882a2698ac.png

ML Kit 객체 감지 및 추적의 종속 항목 추가

ML Kit 종속 항목을 사용하면 앱에 ML Kit ODT SDK를 통합할 수 있습니다. 프로젝트의 app/build.gradle 파일 끝에 다음 줄을 추가합니다.

build.gradle

dependencies {
  // ...
  implementation 'com.google.mlkit:object-detection:16.2.4'
}

프로젝트를 Gradle 파일과 동기화

앱에서 모든 종속 항목을 사용할 수 있도록 하려면 이 시점에서 프로젝트를 Gradle 파일과 동기화해야 합니다.

Android 스튜디오 툴바에서 Sync Project with Gradle Files(Gradle 파일과 프로젝트 동기화)( b451ab2d04d835f9.png)를 선택합니다.

(이 버튼이 사용 중지된 경우 전체 저장소가 아닌 starter/app/build.gradle 만 가져와야 합니다.)

4. 시작 앱 실행

이제 프로젝트를 Android 스튜디오로 가져오고 ML Kit 객체 감지 및 추적의 종속 항목을 추가했으므로 앱을 처음으로 실행할 수 있습니다.

USB를 통해 Android 기기를 호스트에 연결하거나 Android 스튜디오 에뮬레이터를 시작하고 Android 스튜디오 툴바에서 Run ( execute.png)을 클릭합니다.

앱 실행 및 탐색

Android 기기에서 앱이 실행됩니다. 이 파일에는 사진을 캡처하거나 사전 설정된 이미지를 선택하고 이 Codelab에서 빌드할 객체 감지 및 추적 파이프라인에 전달할 수 있는 상용구 코드가 포함되어 있습니다. 코드를 작성하기 전에 앱을 살펴보겠습니다.

먼저 하단에 다음과 같은 버튼 ( c6d965d639c3646.png)이 있습니다.

  • 기기/에뮬레이터에 통합된 카메라 앱을 표시합니다.
  • 카메라 앱에서 사진을 찍습니다.
  • 시작 앱에서 캡처된 이미지를 수신합니다.
  • 이미지 표시

Take photo 버튼을 사용해 보고 메시지에 따라 사진을 찍은 다음 사진을 수락하고 시작 앱에 표시되는지 확인합니다.

작동 방식을 확인하기 위해 몇 번 반복합니다.

9ec541980dbe2d31.png 8312dde41425ba4b.png fa8492bfc1914ff0.png

두 번째로, 3가지 사전 설정된 이미지 중에서 선택할 수 있습니다. Android 에뮬레이터에서 실행하는 경우 나중에 이러한 이미지를 사용하여 객체 감지 코드를 테스트할 수 있습니다.

사전 설정된 3가지 이미지 중에서 이미지를 선택합니다. 이미지가 더 큰 뷰로 표시되는 것을 확인합니다.

1dd41b3ec978f1d9.png

5. 기기 내 객체 감지 추가

이 단계에서는 이미지에서 객체를 감지하는 기능을 시작 앱에 추가합니다. 이전 단계에서 보았듯이 시작 앱에는 기기의 카메라 앱으로 사진을 찍는 상용구 코드가 포함되어 있습니다. Android 에뮬레이터에서 Codelab을 실행하는 경우 앱에 3개의 사전 설정된 이미지가 있어 객체 감지를 시도해 볼 수 있습니다.

사전 설정된 이미지 중에서 이미지를 선택하거나 카메라 앱으로 사진을 찍으면 템플릿 코드가 해당 이미지를 Bitmap 인스턴스로 디코딩하고 화면에 표시한 후 이미지를 사용하여 runObjectDetection 메서드를 호출합니다.

이 단계에서는 runObjectDetection 메서드에 코드를 추가하여 객체 감지를 실행합니다.

이미지에 기기 내 객체 감지 설정 및 실행

ML Kit ODT를 설정하는 방법은 다음과 같이 3가지 API를 사용하는 간단한 3단계로 이루어져 있습니다.

  • 이미지 준비: InputImage
  • 감지기 객체 ObjectDetection.getClient(options) 만들기
  • 위의 두 객체를 연결합니다. process(image)

MainActivity.kt 파일의 runObjectDetection(bitmap: Bitmap) 함수 내에서 이를 실행합니다.

/**
 * ML Kit Object Detection Function
 */
private fun runObjectDetection(bitmap: Bitmap) {
}

현재 함수는 비어 있습니다. 다음 단계로 이동하여 ML Kit ODT를 구현하세요. 이 과정에서 Android 스튜디오에서 필요한 가져오기를 추가하라는 메시지를 표시합니다.

  • com.google.mlkit.vision.common.InputImage
  • com.google.mlkit.vision.objects.ObjectDetection
  • com.google.mlkit.vision.objects.defaults.ObjectDetectorOptions

1단계: InputImage 만들기

ML Kit는 Bitmap에서 InputImage를 만드는 간단한 API를 제공합니다. 그런 다음 InputImage를 ML Kit API에 제공할 수 있습니다.

// Step 1: create ML Kit's InputImage object
val image = InputImage.fromBitmap(bitmap, 0)

위의 코드를 runObjectDetection(bitmap:Bitmap) 상단에 추가합니다.

2단계: 감지기 인스턴스 만들기

ML Kit는 빌더 디자인 패턴을 따릅니다. 구성을 빌더에 전달한 후 빌더에서 감지기를 가져옵니다. 구성할 수 있는 옵션은 3가지가 있습니다. 이 Codelab에서는 굵은 글꼴로 표시된 옵션을 사용합니다.

  • 감지기 모드 (단일 이미지 또는 스트림)
  • 감지 모드 (단일 또는 복수 객체 감지)
  • 분류 모드 (사용 또는 사용 중지)

이 Codelab에서는 단일 이미지 - 여러 객체 감지 및 분류를 다룹니다. 지금 추가하세요.

// Step 2: acquire detector object
val options = ObjectDetectorOptions.Builder()
   .setDetectorMode(ObjectDetectorOptions.SINGLE_IMAGE_MODE)
   .enableMultipleObjects()
   .enableClassification()
   .build()
val objectDetector = ObjectDetection.getClient(options)

3단계: 감지기에 이미지 제공하기

객체 감지 및 분류는 비동기 처리입니다.

  • process()를 통해 감지기에 이미지를 전송합니다.
  • 감지기는 이를 위해 열심히 작동합니다.
  • 감지기는 콜백을 통해 결과를 다시 보고합니다.

다음 코드는 fun runObjectDetection(bitmap:Bitmap)): 내의 기존 코드에 복사 및 추가합니다.

// Step 3: feed given image to detector and setup callback
objectDetector.process(image)
   .addOnSuccessListener {
       // Task completed successfully
        debugPrint(it)
   }
   .addOnFailureListener {
       // Task failed with an exception
       Log.e(TAG, it.message.toString())
   }

완료되면 감지기가 다음과 같은 알림을 전송합니다.

  • 감지된 총 객체 수입니다. 감지된 각 객체는 다음으로 설명됩니다.
  • trackingId: 교차 프레임을 추적하는 데 사용하는 정수입니다 (이 Codelab에서는 사용되지 않음).
  • boundingBox: 객체의 경계 상자입니다.
  • labels: 감지된 객체의 라벨 목록(분류가 사용 설정된 경우에만 해당):
  • index (이 라벨의 색인을 가져옵니다.)
  • text('패션 상품', '식품', '홈 상품', '장소', '식물'을 포함한 이 라벨의 텍스트 가져오기)
  • confidence ( 0.0~1.0 사이의 부동 소수점 수, 1.0은 100%를 의미함)

코드가 debugPrint()를 사용하여 감지된 결과에 대해 printf 유형의 처리를 실행하는 것을 확인했을 것입니다.

MainActivity 클래스에 추가합니다.

private fun debugPrint(detectedObjects: List<DetectedObject>) {
   detectedObjects.forEachIndexed { index, detectedObject ->
       val box = detectedObject.boundingBox

       Log.d(TAG, "Detected object: $index")
       Log.d(TAG, " trackingId: ${detectedObject.trackingId}")
       Log.d(TAG, " boundingBox: (${box.left}, ${box.top}) - (${box.right},${box.bottom})")
       detectedObject.labels.forEach {
           Log.d(TAG, " categories: ${it.text}")
           Log.d(TAG, " confidence: ${it.confidence}")
       }
   }
}

이제 감지를 위해 이미지를 수락할 준비가 되었습니다.

Android 스튜디오 툴바에서 Run ( execute.png)을 클릭하여 Codelab을 실행해 보겠습니다. 사전 설정된 이미지를 선택하거나 사진을 찍은 다음 IDE 내의 logcat 창( 16bd6ea224cf8cf1.png)을 확인합니다.

다음과 비슷한 모습이어야 합니다.

D/MLKit Object Detection: Detected object: 0
D/MLKit Object Detection:  trackingId: null
D/MLKit Object Detection:  boundingBox: (481, 2021) - (2426,3376)
D/MLKit Object Detection:  categories: Food
D/MLKit Object Detection:  confidence: 0.90234375
D/MLKit Object Detection: Detected object: 1
D/MLKit Object Detection:  trackingId: null
D/MLKit Object Detection:  boundingBox: (2639, 2633) - (3058,3577)
D/MLKit Object Detection: Detected object: 2
D/MLKit Object Detection:  trackingId: null
D/MLKit Object Detection:  boundingBox: (3, 1816) - (615,2597)
D/MLKit Object Detection:  categories: Home good
D/MLKit Object Detection:  confidence: 0.75390625

즉, 감지기는 3개의 객체를 감지했습니다.

  • 카테고리는 식품가정용품입니다.
  • 알 수 없는 클래스이므로 두 번째에 대해 반환된 카테고리가 없습니다.
  • trackingId가 없습니다 (단일 이미지 감지 모드이기 때문).
  • boundingBox 직사각형 내의 위치입니다 (예: (481, 2021)~(2426, 3376)).
  • 감지기는 첫 번째가 음식이라고 확신합니다 (90% 확신도 - 샐러드였습니다).

이제 ML Kit 객체 감지를 사용 설정하기 위해 필요한 모든 작업을 완료했습니다. 축하합니다!

UI 측면에서는 아직 시작 단계에 있지만, UI에서 감지된 결과를 활용하여 더 나은 환경을 만들 수 있습니다(예: 경계 상자를 그리는 것). 다음 단계로 넘어가 감지된 결과를 후처리해 보겠습니다.

6. 감지 결과 후처리

이전 단계에서는 감지된 결과를 logcat에 출력했습니다. 간단하고 빠릅니다.

이 섹션에서는 결과를 이미지에 활용합니다.

  • 이미지에 경계 상자 그리기
  • 경계 상자 내에 카테고리 이름과 신뢰도 표시

시각화 유틸리티 이해하기

감지 결과를 시각화하는 데 도움이 되는 상용구 코드가 Codelab 내에 있습니다. 다음 유틸리티를 활용하여 시각화 코드를 간단하게 만드세요.

  • data class BoxWithText(val box: Rect, val text: String) 시각화를 위해 객체 감지 결과를 저장하는 데이터 클래스입니다. box는 객체가 있는 경계 상자이고 text는 객체의 경계 상자와 함께 표시할 감지 결과 문자열입니다.
  • fun drawDetectionResult(bitmap: Bitmap, detectionResults: List<BoxWithText>): Bitmap 이 메서드는 입력 bitmapdetectionResults에 객체 감지 결과를 그리고 수정된 사본을 반환합니다.

다음은 drawDetectionResult 유틸리티 메서드의 출력 예입니다.

58c6f1d4ddb00dfa.png

ML Kit 감지 결과 시각화

시각화 유틸리티를 사용하여 입력 이미지 위에 ML Kit 객체 감지 결과를 그립니다.

debugPrint()를 호출하는 위치로 이동하여 그 아래에 다음 코드 스니펫을 추가합니다.

// Parse ML Kit's DetectedObject and create corresponding visualization data
val detectedObjects = it.map { obj ->
    var text = "Unknown"

    // We will show the top confident detection result if it exist
    if (obj.labels.isNotEmpty()) {
        val firstLabel = obj.labels.first()
        text = "${firstLabel.text}, ${firstLabel.confidence.times(100).toInt()}%"
    }
    BoxWithText(obj.boundingBox, text)
}

// Draw the detection result on the input bitmap
val visualizedResult = drawDetectionResult(bitmap, detectedObjects)

// Show the detection result on the app screen
runOnUiThread {
    inputImageView.setImageBitmap(visualizedResult)
}
  • 먼저 ML Kit의 DetectedObject를 파싱하고 시각화 결과를 표시할 BoxWithText 객체 목록을 만듭니다.
  • 그런 다음 drawDetectionResult 유틸리티 메서드를 사용하여 입력 이미지 위에 감지 결과를 그리고 화면에 표시합니다.

실행하기

이제 Android 스튜디오 툴바에서 Run ( execute.png)을 클릭합니다.

앱이 로드되면 카메라 아이콘이 있는 버튼을 누르고 카메라를 물체에 가져가 사진을 찍은 후 카메라 앱에서 사진을 수락하거나 사전 설정된 이미지를 쉽게 탭할 수 있습니다. 감지 결과가 표시됩니다. 버튼을 다시 누르거나 다른 이미지를 선택하여 몇 번 반복하면 최신 ML Kit ODT를 경험할 수 있습니다.

a03109cb30d5014d.png

7. 축하합니다.

ML Kit를 사용하여 앱에 객체 감지 기능을 추가했습니다.

  • 3가지 API를 사용한 3단계
  • 입력 이미지 만들기
  • 검사 프로그램 만들기
  • 감지기에 이미지 전송

이제 앱을 실행할 준비가 되었습니다.

진행하면서 모델을 개선할 수 있습니다. 기본 모델은 5개 카테고리만 인식할 수 있으며 칼, 포크, 병은 인식하지 못합니다. 기기 내 머신러닝 - 객체 감지 학습 개발자 과정에서 다른 Codelab을 확인하여 맞춤 모델을 학습시키는 방법을 알아보세요.

학습한 내용

  • Android 앱에 ML Kit 객체 감지 및 추적을 추가하는 방법
  • ML Kit에서 기기 내 객체 감지 및 추적을 사용하여 이미지에서 객체를 감지하는 방법

다음 단계

  • 더 많은 이미지와 라이브 동영상을 사용하여 ML Kit ODT를 자세히 살펴보고 감지 및 분류 정확성과 성능을 경험하세요.
  • 기기 내 머신러닝 - 객체 감지 학습 개발자 과정에서 커스텀 모델을 학습하는 방법을 알아보세요.
  • 자체 Android 앱에 ML Kit ODT 적용

자세히 알아보기