반응형
안드로이드의 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 Android Object Detection Tutorial
- YouTube: Real-Time Object Detection with TensorFlow Lite
참고로 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을 구현해 보세요! 질문이나 개선 사항이 있다면 댓글로 남겨주세요. 😊
반응형