모바일/안드로이드

android camera 2 api를 이용해서 사진을 찍고 ondevice로 object detection하기

jinmc 2025. 1. 7. 15:31
반응형

안드로이드의 Camera2 API와 TensorFlow Lite를 사용해 사진을 찍고 기기(On-Device)에서 실시간 Object Detection을 수행하는 방법을 소개합니다. 이 글은 Camera2 API를 활용한 이미지 캡처와 TensorFlow Lite 모델 통합 과정을 설명하며, 여러분의 Android 프로젝트에서 직접 구현할 수 있도록 자세히 안내합니다.

 

github repository: https://github.com/jinmc/camera_test_android/tree/main


주요 기능

  • Camera2 API: 고급 카메라 기능과 이미지 캡처 제공.
  • TensorFlow Lite Object Detection: 사전 학습된 TensorFlow Lite 모델을 사용해 실시간 객체 탐지.
  • 로컬 저장: 캡처한 이미지를 기기에 저장.
  • 온디바이스(On-Device): 네트워크 연결 없이 기기에서 직접 객체 탐지 실행.

준비 사항

1. 개발 환경

  • Android Studio: Bumblebee 또는 최신 버전
  • Android Device: Android 6.0(API 23) 이상

2. 필요한 파일

  • TensorFlow Lite 모델(.tflite): 예를 들어 MobileNet SSD 모델.
  • assets 디렉터리에 .tflite 파일 추가.

구현 단계

1. 프로젝트 설정

1.1. 의존성 추가

build.gradle (Module: app)에 다음 의존성을 추가합니다:

implementation 'org.tensorflow:tensorflow-lite:2.13.0'
implementation 'org.tensorflow:tensorflow-lite-task-vision:0.4.3'

1.2. 권한 요청

AndroidManifest.xml에 필요한 권한을 추가합니다:

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

런타임 권한 요청도 코드에 추가하세요.

2. Camera2 API로 이미지 캡처

MainActivity에서 Camera2 API를 설정하고 이미지를 캡처하는 코드를 작성합니다:

imageReader = ImageReader.newInstance(640, 480, ImageFormat.JPEG, 1)
imageReader.setOnImageAvailableListener(object : ImageReader.OnImageAvailableListener {
    override fun onImageAvailable(reader: ImageReader) {
        val image = reader.acquireLatestImage()
        val buffer = image.planes[0].buffer
        val bytes = ByteArray(buffer.remaining())
        buffer.get(bytes)

        val bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
        val rotatedBitmap = rotateBitmap(bitmap, 90f)

        // Object Detection 실행
        detectObjects(rotatedBitmap)

        // 이미지 저장
        val file = File(getExternalFilesDir(null), "captured_image.jpg")
        FileOutputStream(file).use { output ->
            rotatedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, output)
        }

        image.close()
    }
}, handler)

3. TensorFlow Lite Object Detection 통합

ObjectDetectionHelper 클래스를 생성하여 TensorFlow Lite 모델을 로드하고 객체 탐지를 실행합니다:

class ObjectDetectionHelper(context: Context) {
    private val objectDetector: ObjectDetector

    init {
        val options = ObjectDetectorOptions.builder()
            .setMaxResults(5)
            .setScoreThreshold(0.5f)
            .build()

        objectDetector = ObjectDetector.createFromFileAndOptions(
            context,
            "model.tflite",
            options
        )
    }

    fun detect(bitmap: Bitmap): List<Detection> {
        val tensorImage = TensorImage.fromBitmap(bitmap)
        return objectDetector.detect(tensorImage)
    }
}

4. 탐지 결과 처리

MainActivity에서 탐지 결과를 처리하고 Logcat에 출력합니다:

private fun detectObjects(bitmap: Bitmap) {
    val detectionResults = objectDetector.detect(bitmap)

    detectionResults.forEach { detection ->
        val boundingBox = detection.boundingBox
        val category = detection.categories.firstOrNull()

        category?.let {
            Log.d("ObjectDetection", "Detected ${it.label} with confidence ${it.score} at $boundingBox")
        }
    }
}

결과

  • Camera2 API를 통해 이미지를 캡처하고, TensorFlow Lite 모델로 객체 탐지를 수행합니다.
  • 탐지 결과는 Logcat에 출력되며, 캡처된 이미지는 기기에 저장됩니다.

참고 자료


참고로 tensorflow lite를 사용한 모델은 다음과 같습니다. 

 

  • EfficientDet-Lite0 [권장] - BiFPN 특징 추출기, 공유 상자 예측기 및 초점 손실이 있는 경량의 객체 감지 모델. COCO 2017 검증 데이터세트의 mAP(평균 평균 정밀도)는 25.69%입니다.
  • EfficientDet-Lite1 - 중간 크기의 EfficientDet 객체 감지 모델. COCO 2017 검증 데이터세트의 mAP는 30.55%입니다.
  • EfficientDet-Lite2 - 더 큰 EfficientDet 객체 감지 모델. COCO 2017 검증 데이터세트의 mAP는 33.97%입니다.

 

 

 

TensorFlow Lite와 Camera2 API를 활용해 안드로이드에서 실시간 Object Detection을 구현해 보세요! 질문이나 개선 사항이 있다면 댓글로 남겨주세요. 😊

반응형