ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • CameraX api 4편 : Anlysis와 text 분석 라이브러리(OCR)
    회사 생활/여권 NFC (CameraX + OCR + NFC) 2023. 11. 14. 11:01

    안드로이드에서 카메라 api와 함께 제공되는 재미있는 것들이 많았다. 예를 들면 OCR 기능이 그중 하나였다. 

     

    OCR이란?

    더보기
    광학 문자 인식(OCR)은 텍스트 이미지를 기계가 읽을 수 있는 텍스트 포맷으로 변환하는 과정입니다. 예를 들어 양식 또는 영수증을 스캔하는 경우 컴퓨터는 스캔본을 이미지 파일로 저장합니다. 이미지 파일에서는 텍스트 편집기를 사용하여 단어를 편집, 검색하거나 단어 수를 계산할 수 없습니다. 그러나 OCR을 사용하면 이미지를 텍스트 문서로 변환하여 내용을 텍스트 데이터로 저장할 수 있습니다.

    이미지안에 있는 텍스트를 안드로이드의 String 형식으로 가져오게 만든느 것이라고 이해하면 쉬울듯 싶다. 

     

     

    안드로이드 CameraX에서 이미지를 사용할 수 있는 부분은 2부분이 있다.

    • a) 사진 촬영 이후 이미지
    • b) Preview에서 실시간으로 나오는 이미지

    그래서 공부할겸 2가지 부분다 사진속 Text를 안드로이드에서 String으로 가져올 수 있는 예제를 만들어 봐야겠다. 

     

     

    먼저,

    build.gradle > dependencies

    implementation 'com.google.android.gms:play-services-mlkit-text-recognition:19.0.0'

    참고 : https://developers.google.com/ml-kit/vision/text-recognition/v2/android?hl=ko

     

     

    onCreate 부분에 선언!!!

    TextRecognizer textRecognizer = TextRecognition.getClient(TextRecognizerOptions.DEFAULT_OPTIONS);

     

     

     

    a) ImageCapture에서 촬영된 단일 이미지 활용

    // 이미지 캡처 콜백 등록
    imageCapture!!.takePicture(
        newExecutor,
        object : ImageCapture.OnImageCapturedCallback() {
            override fun onCaptureSuccess(image: ImageProxy) {
                // 이미지 데이터 추출 및 처리
                recognizeText(image)
            }
    
            override fun onError(exception: ImageCaptureException) {
                // 캡처 에러 처리
            }
        })

     

     

    b) Analysis에서 나오는 실시간 이미지 활용

        private fun setAnalysis(): ImageAnalysis.Analyzer {
            @ExperimentalGetImage
            val analysis = ImageAnalysis.Analyzer {
                recognizeText(it)
            }
            return analysis
        }

     

    ImageAnalysis.Analyzer 에서 callBack으로 오는 ImageProxy  OCR 하는 부분으로 넘겨줌.

     

        private fun recognizeText(imageProxy: ImageProxy) {
            @ExperimentalGetImage
            val mediaImage: Image? = imageProxy.image
            if (mediaImage != null) {
                val image = InputImage.fromMediaImage(
                    mediaImage,
                    imageProxy.imageInfo.rotationDegrees
                )
    
                // [START run_detector]
                textRecognizer!!.process(image)
                    .addOnSuccessListener { visionText -> processTextBlock(visionText) }
                    .addOnCompleteListener { imageProxy.close() }
                    .addOnFailureListener { e ->
                        Log.d(
                            TAG,
                            "Text detection failed.$e"
                        )
                    }
                // [END run_detector]
            }
        }

     

    이미지에서 String을 얻어오기 위해 ImageAnalysis.Analyzer에서 받아온 ImageProxy를 textRecognizer.process(image)로 넘겨줌. 

     

    성공적으로 된다면 addOnSuccessListener의 Text 타입(visionText) 결과값으로 넘어옴.

     

    이미지에 글자가 한줄만 있는게 아닐수 있어서 Text Block 형태로 넘어오는 것 같다.

        private fun processTextBlock(result: Text) {
            val blocks = result.textBlocks
            var curText:String = ""
            for (i in blocks.indices) {
                val lines = blocks[i].lines
                for (j in lines.indices) {
                    val elements = lines[j].elements
                    for (k in elements.indices) {
                        curText += elements[k].text
                    }
                    Log.d("curText : ", curText)
                }
            }
        }

     

    blocks.indices > lines.indices > elements.indices 이렇게 작게 쪼갤수 있나보다.

     

     

    Github :

    https://github.com/tvroom88/AIO_Android_Kotlin_Support_Material/tree/main/CameraX/CameraX_3_OCR

     

    전체 코드 : 

     

    완성된 화면 :

     

     

     

     

Designed by Tistory.