Deep_Dev
article thumbnail

 

๐Ÿ“ฑBrain Buddy โœ๏ธ

 

 

2023๋…„ 5์›” 17์ผ ~ 2023๋…„ 6์›”์ค‘ ( ์•ฝ 3์ฃผ )

 

- ๊ธฐํš

- ๊ฐœ๋ฐœ๊ณผ์ •

- ์—๋Ÿฌ์‚ฌํ•ญ

 

 

 

๊ธฐํš

์‚ฌ์‹ค ๊ธฐํš์˜๋„๋Š” ํ•™๋ถ€ ์‹œ์ ˆ ์ข…์ด์— ์ ์–ด๊ฐ€๋ฉฐ ์•”๊ธฐํ•˜๋ฉฐ ๊ณต๋ถ€ํ–ˆ๋˜ ๋‚˜์˜ ๋ชจ์Šต์„ ๋– ์˜ฌ๋ฆฌ๊ณ  ๊ธฐํšํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.

 

์ „๊ณต์„œ์ ์— ์žˆ๋Š” ๋‚ด์šฉ์„ ๋ฐฑ์ง€์— ์˜ฎ๊ฒจ ์ ์–ด๊ฐ€๋ฉฐ ์™ธ์šฐ๊ณ  ๋‚ฌ์„๋•Œ, ์ด๋ฅผ ๋‹ค์‹œ ๋นˆ์นธ์„ ๋‚ด๊ฐ€ ๋งŒ๋“ค์–ด์„œ ์ž˜ ์™ธ์› ๋‚˜ ์‹œํ—˜ ๋ณด๊ณ  ์‹ถ์—ˆ๋Š”๋ฐ

๋นˆ์นธ์„ ๋งŒ๋“ค์‹œ๊ฐ„์— ์ฐจ๋ผ๋ฆฌ ์กฐ๊ธˆ ๋” ์™ธ์šฐ๋Š”๋ฐ ์ง‘์ค‘์„ ํ•ด๋ณด๊ณ ์ž ํ–ˆ์—ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

๊ทธ๋ž˜์„œ 

 

์‚ฌ์šฉ์ž๊ฐ€ ์Šค์Šค๋กœ ๊ณต๋ถ€ํ•˜๋ฉฐ ๋ฐฑ์ง€์— ์ ์€ ๋‚ด์šฉ๋“ค์„ ์‚ฌ์ง„์œผ๋กœ ์ฐ์œผ๋ฉด ํ•ด๋‹น ๋‚ด์šฉ์ค‘์—์„œ ๋žœ๋ค์œผ๋กœ ๋นˆ์นธ์„ ์ƒ์„ฑํ•ด์ฃผ๋ฉฐ

๋นˆ์นธ ๋‚ด์šฉ์„ ์ฑ„์›Œ๋ณผ ์ˆ˜ ์žˆ๋Š” ์•ฑ์„ ์ƒ๊ฐํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.

 

๋˜ํ•œ ์‹ค์ œ๋กœ ํŽœ์„ ์ด์šฉํ•ด ์‹œํ—˜์„ ๋ณด๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ๋Š๋‚Œ์„ ์ฃผ๊ธฐ ์œ„ํ•ด์„œ 

ํ…์ŠคํŠธ ์ž…๋ ฅ๋ณด๋‹ค๋Š” ์• ํ”ŒํŽœ์Šฌ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ง์ ‘ ์“ธ ์ˆ˜ ์žˆ๋Š” 

iPad ์ „์šฉ ์•ฑ์œผ๋กœ ๊ฐœ๋ฐœ ํ•˜๊ธฐ๋กœ ํ•˜์˜€๋‹ค.

 

๊ทธ๋ ‡๊ฒŒ ์‚ฌ์ง„์ธ์‹, ํ…์ŠคํŠธ ๋ณ€ํ™˜ ๋“ฑ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ๊ธฐ์ˆ ๋“ค์„ ์ฐพ์•„๋ณด๋‹ค๊ฐ€

iOS๋‚ด VisionFramework๊ฐ€ ์กด์žฌํ•˜๊ณ  ํ•ด๋‹น VisionKit์ด ์กฐ๊ธˆ์”ฉ ์—…๋ฐ์ดํŠธ๋˜์–ด ํ˜„์žฌ 3๊นŒ์ง€ ๋‚˜์™€์žˆ๋‹ค๋Š”๊ฒƒ์„ ๋ณด๊ฒŒ ๋˜์—ˆ๊ณ 

์ด ๋‚ด์žฅ ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•˜๊ธฐ๋กœ ํ–ˆ์Šต๋‹ˆ๋‹ค.

 

 

๊ฐœ๋ฐœ ๊ณผ์ •

ํ•œ ๋ˆˆ์— ๋“ค์–ด์˜ค๋ฉฐ ์ง๊ด€์ ์ด๊ณ  ํŒŒ์ผ ์ €์žฅ๊ณผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๊ฒƒ์„ ํŽธํ•˜๊ฒŒ -> CollectionView & Cell

ํ…์ŠคํŠธ ์ด๋ฏธ์ง€๋ฅผ ๊ธฐ๊ณ„๊ฐ€ ์ฝ์„ ์ˆ˜ ์žˆ๋Š” ํ…์ŠคํŠธ ํฌ๋งท์œผ๋กœ ๋ณ€ํ™˜ -> VisionKit Framework

์‚ฌ์šฉ์ž์—๊ฒŒ ์•ฑ ์‚ฌ์šฉ ๋ฐฉ๋ฒ• ์•Œ๋ ค์ฃผ๊ธฐ -> Onboarding

์ „์ฒด์ ์ธ ๋ ˆ์ด์•„์›ƒ์€ SnapKit์„ ์‚ฌ์šฉํ–ˆ๋‹ค.

 

 

๐Ÿ“Œ VisionKit ์‚ฌ์šฉ๊ณผ์ •

1. Vision ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ž„ํฌํŠธ

 

 

 

 

2. CGImage๋กœ ์ด๋ฏธ์ง€ ํƒ€์ž… ๋ณ€ํ™˜

์ด๋ฏธ์ง€ ์ธ์‹์„ ์š”์ฒญํ•˜๋Š” handler๋ฅผ ์ƒ์„ฑํ•  ๋•Œ

= VNImageRequestHandler( cgImage: , options: [:])

cgImage๋ฅผ ์š”๊ตฌํ•œ๋‹ค. ์›ํ•˜๋Š” UIImage๋ฅผ cgImage๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค. 

 

 

 

 

3. VNRecognizeTextRequest ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ

๋ณธ๊ฒฉ์ ์ธ VisionKit ์‚ฌ์šฉ์ด๋‹ค.

VisionKit์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๊ฐ€์žฅ ๋จผ์ € ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ๋ถ€ํ„ฐ ํ•ด์•ผํ•œ๋‹ค.

 

 

 

 

4. Vision ๋ฒ„์ „๊ณผ ์–ธ์–ด ์„ค์ •

VNRecognizeTextRequest๋Š” ์—ฌ๋Ÿฌ๊ฐ€์ง€ ์˜ต์…˜์„ ์ œ๊ณตํ•œ๋‹ค.

์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ–ˆ์œผ๋ฉด ์˜ต์…˜ ์„ค์ •์„ ํ•˜๋ฉด ๋œ๋‹ค.

 

revision : VNRecognizeTextRequest์˜ ๋ฒ„์ „ ์„ ํƒ

( 2023.12์›” ๊ธฐ์ค€ revision3๊ฐ€ ๊ฐ€์žฅ ์ตœ์‹  ๋ฒ„์ „)

 

recognitionLevel : ๋ฒ„์ „ ์ธ์‹์˜ ์ •ํ™•๋„ ๋ ˆ๋ฒจ 

recognitionLanguages : ๋ฒˆ์—ญ ํ•  ์–ธ์–ด ์„ ํƒ

 

 

 

VisionKit์˜ ๊ฒฝ์šฐ ์ง€์›ํ•˜๋Š” ์–ธ์–ด๊ฐ€ ํ•œ์ •์ ์ธ๋ฐ

๋‚ด๊ฐ€ ์›ํ•˜๋Š” ์–ธ์–ด๊ฐ€ ์ง€์›ํ•˜๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ํ•จ์ˆ˜๊ฐ€ ์žˆ๋‹ค.

 

supportedRecognitionLanguages() : ํ•จ์ˆ˜ ํ˜ธ์ถœ ์‹œ ์ง€์›ํ•˜๋Š” ์–ธ์–ด ํ™•์ธ ๊ฐ€๋Šฅ

 

iOS16์ด์ƒ, VNRecognizeTextRequestRevision3 ๋ฒ„์ „ = 14๊ฐ€์ง€ ์–ธ์–ด ์ง€์›

 

' ์˜์–ด, ๋ถˆ์–ด, ์ดํƒˆ๋ฆฌ์•„์–ด, ๋…์ผ์–ด, ์ŠคํŽ˜์ธ์–ด, ํฌ๋ฅดํˆฌ์นผ์–ด(๋ธŒ๋ผ์งˆ), ์ค‘๊ตญ์–ด ๊ฐ„์ฒด, ์ค‘๊ตญ์–ด ๋ฒˆ์ฒด, ๊ด‘๋™์–ด ๊ฐ„์ฒด, ๊ด‘๋™์–ด ๋ฒˆ์ฒด, 

ํ•œ๊ธ€, ์ผ๋ณธ์–ด, ๋Ÿฌ์‹œ์•„์–ด, ์šฐํฌ๋ผ์ด๋‚˜์–ด '

 

 

 

5. RequestHandler ๋™์ž‘

์œ„์—์„œ ์„ค์ •ํ•œ handler, request๋ฅผ ๋™์ž‘ํ•œ๋‹ค.

 

 

 

 

ํ•ด๋‹น ๊ธฐ์ˆ ์— ํ•ด๋‹นํ•˜๋Š” ์ „์ฒด ์ฝ”๋“œ

 /// Visision : Image -> TextRecognition
    private func recognizerText(image: UIImage?) { // ์ด๋ฏธ์ง€๋Š” ์„ ํƒ์‚ฌํ•ญ
        guard let cgImage = image?.cgImage else { return } // Ui ์ด๋ฏธ์ง€์˜ CG์ด๋ฏธ์ง€ ๋ฒ„์ „์„ ์–ป๋Š” ๊ฒƒ
        
        // Handler
        let handler = VNImageRequestHandler(cgImage: cgImage, options: [:])
        
        // Reqeust ( ํ…์ŠคํŠธ ๊ฐ์ง€๋ฅผ ์œ„ํ•œ ์š”์ฒญ ์ƒ์„ฑ )
        let request = VNRecognizeTextRequest{ [weak self] request, error in
            // ์‹ค์ œ ๊ด€์ฐฐ๋œ ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ ( request.results = ๊ด€์ฐฐ / ์—ฌ๊ธฐ์—์„œ ๋ฌธ์ž์—ด์„ ๊ฐ€์ ธ์˜ค๊ณ  )
            guard let observations = request.results as? [VNRecognizedTextObservation],
                  error == nil else {
                return
            }
            
            // ์••์ถ•๋งคํ•‘
            let text = observations.compactMap({
                $0.topCandidates(1).first?.string
            }).joined(separator:"\n") // ์ค„๋ฐ”๊ฟˆ์œผ๋กœ ๊ตฌ๋ถ„
            
            DispatchQueue.main.async {
                self?.addImageView.setTextViewText(text)
                self?.textTemp = text
            }
        }
        
        request.recognitionLevel = .accurate // ์ •ํ™•๋„ ๋ ˆ๋ฒจ
        request.recognitionLanguages = ["ko","en","zh-Hans","ja"] // ํ…์ŠคํŠธ ๊ฐ์ง€ ์–ธ์–ด -> ํ•œ๊ตญ์–ด, ์˜์–ด, ์ค‘๊ตญ์–ด ์ผ๋ณธ์–ด
        request.usesLanguageCorrection = true
        request.revision = VNRecognizeTextRequestRevision3 // ๋ฒ„์ „
        
        // Process request
        do {
            try handler.perform([request]) // Handler์—์„œ ์š”์ฒญ ์ˆ˜ํ–‰
        }
        catch {
            addImageView.setTextViewText("\(error)")
        }
    }

 

 

 

 

์—๋Ÿฌ์‚ฌํ•ญ

Onboarding ํ™”๋ฉด์„ ์ œ์™ธํ•œ Vision ๊ธฐ์ˆ , ์ „์ฒด์ ์ธ ํ™”๋ฉด์„ ๊ฑฐ์˜ ๋‹ค ๊ตฌํ˜„ํ–ˆ์„ ๋•Œ ์ฏค ์—๋Ÿฌ์‚ฌํ•ญ์„ ๋ฐœ๊ฒฌํ–ˆ๋‹ค.

 

๋ณ€ํ™˜ ์–ธ์–ด๋ฅผ request.recognitionLanguages = ["ko","en","zh-Hans","ja"] 

์ด๋ ‡๊ฒŒ ์ž˜ ์„ค์ •ํ–ˆ์Œ์—๋„ ์ž˜ ๋ฒˆ์—ญ๋˜์ง€ ์•Š๋Š” ๊ฒƒ์ด๋‹ค.

 

 

 

TEST 1 : ์ธํ„ฐ๋„ท์—์„œ ๋‹ค์šด๋ฐ›์€ ์ •๊ฐˆํ•œ ํ•œ๊ธ€๋งŒ ์žˆ๋Š” ๊ฒฝ์šฐ

๋ณด๋‹ค์‹œํ”ผ ๋ˆ„๊ฐ€๋ด๋„ ์ž˜ ์ฝ์„ ์ˆ˜ ์žˆ๋Š” ํ•œ๊ธ€์˜ ๊ฒฝ์šฐ ๊ฑฐ์˜ ๋ชจ๋“  ๊ธ€์ž๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ๋ณ€ํ™˜๋œ๋‹ค.

 

 

 

 

TEST 2 : ์‚ฌ๋žŒ์ด ์ง์ ‘ ํŽœ์œผ๋กœ ์˜ฎ๊ฒจ ์“ด ํ•œ๊ธ€๊ณผ ์˜์–ด

 

์™ผ์ชฝ : ์‹ค์ œ ๊ณต๋ถ€ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ์“ด ๊ฒƒ

์˜ค๋ฅธ์ชฝ :  ์•„์ดํŒจ๋“œ ์•ฑ ๋‚ด์—์„œ ํŽœ์Šฌ์„ ์ด์šฉํ•ด ์“ด ๊ธ€์”จ 

 

๋ณด๋‹ค์‹œํ”ผ ์‚ฌ๋žŒ์ด ์ง์ ‘ ํ•„๊ธฐํ•ด๋„ ๊นจ๋—ํ•˜๊ฒŒ ์ž˜ ์“ธ์ˆ˜๋ก ์ธ์‹๋ฅ ์ด ์ข‹๋‹ค. 

๋˜ํ•œ ๊ด„ํ˜ธ๋‚˜ ์˜์–ด๋„ ์ž˜ ๋ณ€ํ™˜๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ–ˆ๋‹ค.

 

 

 

 

TEST3 : ์˜์–ด๋งŒ ์žˆ๋Š” ๊ฒฝ์šฐ

์—ญ์‹œ ๊น”๋”ํ•˜๊ณ  ์ž˜ ์จ์ง„ ์˜์–ด ๋˜ํ•œ ์ž˜ ๋ณ€ํ™˜๋œ๋‹ค.

 

 

TEST 4 : ์ค‘๊ตญ์–ด , ์ผ๋ณธ์–ด๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ

 

์ธํ„ฐ๋„ท์—์„œ ๋‹ค์šด ๋ฐ›์€ ์ •๊ฐˆํ•œ ๊ธ€์”จ์ž„์—๋„ ์ค‘๊ตญ์–ด์™€ ์ผ๋ณธ์–ด๋Š” ์ž˜ ๋ฒˆ์—ญ๋˜์ง€ ์•Š๋Š”๋‹ค.

 

 

 

 

์‚ฌ์‹ค ํ•œ๊ตญ์–ด์™€ ์˜์–ด๋งŒ ์ž˜ ๋ฒˆ์—ญ๋œ๋‹คํ•ด๋„ ์ƒ๊ด€์—†๊ฒ ์ง€๋งŒ, ์ค‘๊ตญ์–ด์™€ ์ผ๋ณธ์–ด ์ •๋„๋Š” ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ์—ˆ๋‹ค.

 

๊ตฌ๊ธ€๋ง ํ•ด๋ณธ ๊ฒฐ๊ณผ ๋‚˜์™€ ๋˜‘๊ฐ™์€ ์ƒํ™ฉ์„ ๊ฒช๊ณ ์žˆ๋Š” ๊ธ€์„ ๋ณผ ์ˆ˜ ์žˆ์—ˆ๋Š”๋ฐ, 

์˜ค๋ฒ„ํ”Œ๋กœ์šฐ์‚ฌ์ดํŠธ์ž„์—๋„ ์ข‹์€ ํ•ด๊ฒฐ๋ฐฉ์•ˆ์€ ์—†์—ˆ๋‹ค.

 

 

https://stackoverflow.com/questions/69546997/swifts-vision-framework-not-recognizing-japanese-characters

 

Swift's Vision framework not recognizing Japanese characters

I would like to read Japanese characters from a scanned image using swift's Vision framework. However, when I attempt to set the recognition language of VNRecognizeTextRequest to Japanese using req...

stackoverflow.com

 

 

์ด๋Ÿฐ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ๊ฒฐ๊ตญ ์ค‘๊ตญ์–ด์™€ ์ผ๋ณธ์–ด๊นŒ์ง€ ์ž˜ ์ธ์‹ํ•˜๊ฒŒ ํ•˜๋ ค๋ฉด 

๋‚ด์žฅ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋ง๊ณ  ์ง์ ‘ OCR๊ธฐ์ˆ  ์ž์ฒด๋ฅผ ๊ตฌํ˜„ํ•ด์„œ ์—ฐ๋™ํ•ด์•ผํ•˜๋Š”๊ฒƒ์ด ์•„๋‹Œ๊ฐ€.. ์ƒ๊ฐ์ด ๋“ค์—ˆ๋‹ค.

 

 

์‚ฌ์‹ค ๊ธฐํš ํ•  ๋•Œ ๋ฐฑ์ง€์— ๋‚ด์šฉ๋“ค์„ ์ ๊ณ  -> ์ค‘์š”ํ•œ ํ‚ค์›Œ๋“œ๋“ค์„ ํ˜•๊ด‘ํŽœ์œผ๋กœ ์น ํ•˜๋ฉด

์ด ํ˜•๊ด‘ํŽœ์œผ๋กœ ์น ํ•ด์ง„ ๋ถ€๋ถ„๋งŒ ์ธ์‹ํ•˜์—ฌ ๋นˆ์นธ์œผ๋กœ ๋งŒ๋“ค๊ณ  ์‹ถ์—ˆ๋‹ค๋Š” ์•„์ฃผ ํฐ ์š•์‹ฌ์„ ์ƒ๊ฐํ•ด๋ณด๊ธฐ๋„ ํ–ˆ์ง€๋งŒ

์ด๋Š” ๋‚˜ ํ˜ผ์ž๋กœ๋Š” ์ •๋ง ์–ด๋ ค์› ์„ ๊ฒƒ์ด๋ผ๋Š”๊ฒƒ์ด๋‹ค..

 

 

์ด ํ”„๋กœ์ ํŠธ๋ฅผ ํ˜„์žฌ ์ƒํ™ฉ์—์„œ ์ถœ์‹œํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ๋ฐ”๊ฟ”์•ผํ• ์ง€, 

์ถœ์‹œ๋ฅผ ๋ชปํ•œ๋‹คํ•˜๋”๋ผ๋„ ์–ด๋–ป๊ฒŒ ๋ฐ”๊พธ๋ฉด ์ข‹์„์ง€ ์ƒ๊ฐํ•ด๋ด์•ผ๊ฒ ๋‹ค. 

ApplePencilKit

VisionKit

SnapKit

MVC 

๋“ฑ ์จ๋ณด์ง€ ๋ชปํ–ˆ๋˜ ๊ฒƒ๋“ค์„ ์‚ฌ์šฉํ•ด๋ณธ๊ฒƒ์ด ์ข‹์•˜๋‹ค.