์์ฆ ์งํ ์ค์ธ ํ ์ด ํ๋ก์ ํธ์์ ๊ฝค ๊ด์ฐฎ์ ์์ด๋์ด๊ฐ ๋ ์ฌ๋๋ค.
ํ๋ก์ ํธ์ ์ฃผ์ ๋ ์ผ์๋ง์ ๋ฉ๋ชจ์ฅ์ ๋์ฐ๋ ์ฑ์ธ๋ฐ ์ฌ์ฉ์๊ฐ ์ธ์ฐ๊ณ ์ถ๊ฑฐ๋ ๊น๋จน์ผ๋ฉด ์ ๋๋ ๋จ์ด๋ค์ ์ํ๋ ์์์ผ๋ก ์ ์ด๋๊ณ , ์ค๋งํธํฐ์ ์ผค ๋๋ง๋ค ๊ทธ ํ๋ฉด์ด ๋ณด์ด๋ ์ฑ์ด๋ค. ์ฌ์ค ์ด์ ์ ํ๋กํ ํ์ ์์ค์ผ๋ก ์งํํด๋ณธ ๊ฒฝํ์ด ์์์ง๋ง, ํ๋ ์ด์คํ ์ด ๋ฐ์นญ์ ๋ชฉ์ ์ผ๋ก ์์ ๋ฆฌํฉํ ๋งํ์ฌ ๋ง๋ค๊ธฐ๋ก ๊ฒฐ์ ํ ๊ฒ์ด๋ค. ๊ทธ๋ฆฌ๊ณ ๋ค์ผ๋ก ์ฝํ๋ฆฐ๋ ๋ฐฐ์๋ณผ ๊ฒธ 100% ์ฝํ๋ฆฐ์ ์ฌ์ฉํ์๋ค.
๊ทธ๋ฆฌ๊ณ ์ฌ์ฉ์๊ฐ ์ํ๋ ๋จ์ด๋ ๋ฌธ์ฅ์ ์ค๋งํธํฐ ์นด๋ฉ๋ผ๋ก ์บก์ณํ์ฌ ์๋์ผ๋ก ์ธ์ํ๊ฒ ๋ง๋ ํ ๋ฒ์ญ ๊ธฐ๋ฅ๊น์ง ์ถ๊ฐํ๋ฉด ๊ฝค ๋๋ด์ฃผ๋ ์์ดํ ์ด ๋ ๊ฒ ๊ฐ์์ ์ฐ์ ๊ธ์ ์ธ์ API์ธ Tesseract์ ๋ํด ์์๋ณด์๋ค.
Tesseract๋ ํด๋ ํฉ์ปค๋ ์ฐ๊ตฌ์์์ 1984๋ ~1994๋ ์ฌ์ด ๋ ์ ์ํํธ์จ์ด๋ก ๊ฐ๋ฐ๋์์ผ๋ฉฐ, 1996๋ ๋ถํฐ ์๋์ฐ๋ก๋ ๋ง์ด๊ทธ๋ ์ด์ ์ด ๋๊ณ ๋๋ถ๋ถ ์ฝ๋๊ฐ C๋ก ์์ฑ๋์๋ค. ์ดํ 10๋ ๋์์ ์์ ์ด ๊ฑฐ์ ์ด๋ค์ง์ง ์๋ค๊ฐ 2005๋ ๋ค๋ฐ๋ค ๋ํ๊ต์์ ์คํ์์ค๋ก ์ถ์ํ ํ 2006๋ ๋ถํฐ ๊ตฌ๊ธ์์ ํ์์ ํ๋ฉฐ ์ ์ฐจ ๋ฐ์ ํด ๋๊ฐ๊ณ ์๋ ์์ง์ด๋ผ๊ณ ํ๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก ๋ชฉ์ ์ ๊ธ์๋ฅผ ์ธ์ํ์ฌ ๋ฐ์ดํฐ๋ก ์ ์ฅํ๋ ๊ฒ์ธ๋ฐ, ๊ธฐ์กด์ ๋ค์ํ ๊ธ์ ์ด๋ฏธ์ง ์ํ๋ค๊ณผ ๋น๊ตํ์ฌ ์ ๋ ฅ๋ ์ด๋ฏธ์ง์ ์ ์ฌ๋์ ๋ฐ๋ผ ๊ธ์๋ฅผ ํ๋ณํด์ฃผ๋ ๋ฐฉ์์ด๋ค. ์คํ์์ค์ด๊ธฐ ๋๋ฌธ์ ์๋นํ ์ฝ๊ฒ ์ด์ฉํ ์ ์๊ณ ์ธ์ด ๋ฐ์ดํฐ๋ ๋ค์ํ๋ค. ๋จ, ์์ด์์์ ์ธ์๋ฅ ์ ์๋นํ ์ข์ ํธ์ด๋ ํ๊ธ์ด๋ ๋ค๋ฅธ ๋ฌธ์๋ค์ ์ธ์๋ฅ ์ ์กฐ๊ธ ์ ์กฐํ ํธ์ด๋ผ๊ณ ํ๋ค.
์ฉ๋ ์์ฒด๋ง ๋ณด๋๋ผ๋ ํ๊ธ์ ๋จ์ด ๋ฐ์ดํฐ๊ฐ ์์ด์ ๋ฐ๋ฐ์ ๋์ง๋ ์๊ณ ํ๊ธ์ ๊ฒฝ์ฐ ์์ ๋ชจ์ ๋ฐ์นจ ๋ฑ์ ์กฐํฉํ๋ฉด ์์ด ์ํ๋ฒณ ์์ ๋ช ๋ฐฐ๊ฐ ๋๋ ๊ธ์๊ฐ ๋ง๋ค์ด์ง๋๋ฐ ๊ทธ์ ๋ฐํด ๋ฐ์ดํฐ๊ฐ ๋ถ์กฑํ๋ฉด ์ธ์๋ฅ ์ด ํจ์ฌ ์ ์กฐํด์ง ์๋ฐ์ ์๋ค. ๋ฌผ๋ก ์ํํ ์ฌ์ฉ์ ์ํด ํ๊ธ ๋ฐ์ดํฐ๋ฅผ ๋ง์ด ํ์ต์ํฌ ํ์๊ฐ ์๊ฒ ์ง๋ง, ๋์ค์ Tesseract์ ๋ํด ๋ ์์๋ณด๊ณ ๋ด๊ฐ ์ง์ ํ์ต์ํค๊ฑฐ๋ ๊ผผ์๋ฅผ ์จ๋ณผ ์์ ์ด๋ค.
์์
๊ฐ์ฅ ๋จผ์ Tesseract ๋ฅผ ์๋๋ก์ด๋์์ ์ฌ์ฉํ๊ธฐ ์ํด dependencies๋ฅผ implement ํด์ค์ผ ํ๋ค.
๊ฐ์ฅ ์ต์ ๋ฒ์ ์ด ์ฌ๋ผ์ ์์ผ๋ ๊ตณ์ด ์๋์ ๋ฒ์ ์ ์ฌ์ฉํ์ง ์์๋ ๋๋ค.
์ต์ ๋ฒ์ ํ์ธ : github.com/rmtheis/tess-two/releases
๊ทธ๋ฆฌ๊ณ ์ธ์ด ํ์ผ์ ๋ค์ด๋ก๋ํ๋ค.
ํ์์ ๊ฒฝ์ฐ ์์ด์ ํ๊ธ์ ๋ฐ์๋ ์ํ์ด๋ค.
์ธ์ด ๋ฐ์ดํฐ : github.com/tesseract-ocr/tessdata
๋ค์ด๋ก๋ํ ์ธ์ด ๋ฐ์ดํฐ๋ assetsํด๋๋ฅผ ๋ง๋ ํ ๊ทธ ์์๋ค tessdata ํด๋๋ฅผ ๋ ๋ง๋ค์ด์ผ ํ๋ค. ๊ฑฐ๊ธฐ๋ค ๋ฃ์ผ๋ฉด ๋๋ค.
์ด์ ์ธ์์ํฌ ๊ธ์๊ฐ ์ ํ ์ด๋ฏธ์ง ํ์ผ์ ๋ง๋ค์
์ธ์๋ฅ ์ด ์๋นํ ๋ฎ์ ๊ฒ์ ๊ฐ์ํด ์นด๋ฉ๋ผ๋ก ์ฐ์ ์ฌ์ง์ ์ฌ์ฉํ์ง ์๊ณ PC ๋ด ์คํฌ๋ฆฐ์ท์ ํ์ฉํด์ ์ฌ์ง ํ์ผ์ ๋ง๋ค์๋ค.
์ด์ ์ด ๊ธ์๋ฅผ ์บก์ฒํด์ drawable ํด๋์ ๋ฃ์ด๋๋๋ก ํ์.
๋ฉ๋ชจ์ฅ txt ํ์ผ์ ์ ์ฅํ๋ ๊ฒ ์๋๋ผ ์ด ๊ธ์๋ฅผ ์ฐ์ ์คํฌ๋ฆฐ์ท์ ์ ์ฅํ๋ ๊ฑฐ๋ค!!
์ด์ ํ๋ฉด ์ธ์ํ ๊ธ์๋ฅผ ๋์ธ ๋ ์ด์์ ํ์ผ๋ถํฐ ๋ง๋ค์
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/activitymain_tv_result"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
๊ทธ๋ฆฌ๊ณ ๋ฐ๋ก ์ฝ๋ฉ์ ์งํํ๊ฒ ๋ค
์์ ์ ๋ชจ๋ MainActivityํด๋์ค ์์์ ์งํํ๋ค.
MainActivity.kt
...
class MainActivity : AppCompatActivity() {
lateinit var tess : TessBaseAPI //Tesseract API ๊ฐ์ฒด ์์ฑ
var dataPath : String = "" //๋ฐ์ดํฐ ๊ฒฝ๋ก ๋ณ์ ์ ์ธ
...
์ ์ญ ๋ณ์๋ 2๊ฐ์ง๋ฅผ ์ ์ธํ๋ค.
MainActivity.kt
...
fun copyFile(lang : String){
try{
//์ธ์ด๋ฐ์ดํํ์ผ์ ์์น
var filePath : String = dataPath+"/tessdata/"+lang+".traineddata"
//AssetManager๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํ ๊ฐ์ฒด ์์ฑ
var assetManager : AssetManager = getAssets();
//byte ์คํธ๋ฆผ์ ์ฝ๊ธฐ ์ฐ๊ธฐ์ฉ์ผ๋ก ์ด๊ธฐ
var inputStream : InputStream = assetManager.open("tessdata/"+lang+".traineddata")
var outStream : OutputStream = FileOutputStream(filePath)
//์์ ์ ์ด๋ ํ์ผ ๊ฒฝ๋ก์ชฝ์ผ๋ก ํด๋น ๋ฐ์ดํธ์ฝ๋ ํ์ผ์ ๋ณต์ฌํ๋ค.
var buffer : ByteArray = ByteArray(1024)
var read : Int = 0
read = inputStream.read(buffer)
while(read!=-1){
outStream.write(buffer,0,read)
read = inputStream.read(buffer)
}
outStream.flush()
outStream.close()
inputStream.close()
}catch(e : FileNotFoundException){
Log.v("์ค๋ฅ๋ฐ์",e.toString())
}catch (e : IOException)
{
Log.v("์ค๋ฅ๋ฐ์",e.toString())
}
}
...
๊ทธ๋ค์ copyFile ๋ฉ์๋๋ฅผ ์ถ๊ฐํ๊ณ Assetsํด๋์ ์๋ ์ฌ๊ธฐ์๋ ์ธ์ด๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด ๋ด๋ถ์ ์ฅ์๋ก ์ด๋์ ์ํค๋ ๋ชจ์ต์ด๋ค. ๋จ์ํ ์ธ์ด๋ฐ์ดํฐ๋ฅผ ๋ณต์ฌํ๋ค๊ณ ์๊ฐํ๋ฉด ๋๋ค.
MainActivity.kt
...
fun checkFile(dir : File, lang : String){
//ํ์ผ์ ์กด์ฌ์ฌ๋ถ ํ์ธ ํ ๋ด๋ถ๋ก ๋ณต์ฌ
if(!dir.exists()&&dir.mkdirs()){
copyFile(lang)
}
if(dir.exists()){
var datafilePath : String = dataPath+"/tessdata/"+lang+".traineddata"
var dataFile : File = File(datafilePath)
if(!dataFile.exists()){
copyFile(lang)
}
}
}
...
์์์ ์ธ์ด ๋ฐ์ดํฐ๋ฅผ ๋ณต์ฌํด์ฃผ๋ ๋ฉ์๋๋ฅผ ๋ง๋ ์ด์ ๋ ์ธ์ด๋ฐ์ดํฐ๊ฐ ๋ด๋ถ์ ์ฅ์์ ์กด์ฌ์ฌ๋ถ๋ฅผ ํ์ธํ ํ ์์ผ๋ฉด ์ธ์ด๋ฐ์ดํฐ๋ฅผ ๋ด๋ถ์ ์ฅ์๋ก ๋ณต์ฌ๋ฅผ ํด์ฃผ๊ธฐ ์ํ ์ฉ๋์๋ค. ๋ฐ๋ผ์ checkFile ๋ฉ์๋์์๋ ์ด๋ ๊ฒ ์ค๊ณ๋ฅผ ํด๋๋ค.
MainActivity.kt
...
fun processImage(bitmap : Bitmap){
Toast.makeText(applicationContext,"์ ์ ๊ธฐ๋ค๋ ค ์ฃผ์ธ์",Toast.LENGTH_SHORT).show()
var ocrResult : String? = null;
tess.setImage(bitmap)
ocrResult = tess.utF8Text
activitymain_tv_result.text = ocrResult
}
...
test์ด๋ฏธ์ง ํ์ผ์ ๋ถ์ํด์ ํ ์คํธ๋ทฐ์ ๋์ธ ๋ฉ์๋๋ฅผ ๋ง๋ค์ด ๋๋ค.
MainActivity.kt
...
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
dataPath = filesDir.toString()+ "/tesseract/" //์ธ์ด๋ฐ์ดํฐ์ ๊ฒฝ๋ก ๋ฏธ๋ฆฌ ์ง์
checkFile(File(dataPath+"tessdata/"),"kor") //์ฌ์ฉํ ์ธ์ดํ์ผ์ ์ด๋ฆ ์ง์
checkFile(File(dataPath+"tessdata/"),"eng")
var lang : String = "kor+eng"
tess = TessBaseAPI() //api์ค๋น
tess.init(dataPath,lang) //ํด๋น ์ฌ์ฉํ ์ธ์ด๋ฐ์ดํฐ๋ก ์ด๊ธฐํ
processImage(BitmapFactory.decodeResource(resources,R.drawable.test)) //์ด๋ฏธ์ง ๊ฐ๊ณตํ ํ
์คํธ๋ทฐ์ ๋์ฐ๊ธฐ
}
...
์ด์ ํ ์คํธ๋ฅผ ํด๋ณผ๊น๋
์ด ์ฌ์ง์
์ด๋ ๊ฒ ์ธ์ํ๋ค.
ํ๊ธ์ ์ธ์๋ฅ ์ด ์ข์ง ์๋ค๋ ๊ฒ์ ํ๋์ ์ ์ ์๋ค.
๋ ์ ๋ฑ์ด๋ผ๊ณ ์ธ์ํ๋ค๋.. (์ญ์ ํ๊ตญ์ด๋ ๊ธฐ๊ณ๋ ์ด๋ ค์ด๊ฐ๋ณด๋ค)
ํ์ง๋ง ์ด๋ ์ธ์ด ๋ฐ์ดํฐ์ ํ์ต์ ํตํด ์ด๋ ์ ๋ ๊ฐ์ ์ด ๊ฐ๋ฅํ ๊ฒ์ผ๋ก ๋ณด์ธ๋ค.
๋ถ๋ช ํ๊ธ๋ ๋ฐ์ดํฐ์ ํ์ต์ด ๊พธ์คํ๊ฒ ์ด๋ค์ง๋ค๋ฉด ๋ ์ข์ ์ด๋ฏธ์ง ์ธ์์ด ๊ฐ๋ฅํ ๊ฒ์ผ๋ก ๋ณด์ธ๋ค.
๋์ค์๋ ์นด๋ฉ๋ผ๋ก ์บก์ฒํ ์ด๋ฏธ์ง๋ฅผ ๊ธ์๋ก ์ธ์ํ์ ์๋๋ก ๋ง๋ค์ด๋ณผ ์์ ์ด๋ค. ๊ธ์์ ์๊น์ด๋ ์ฝ๊ฐ์ ๋ ธ์ด์ฆ๋ง์ผ๋ก๋ Tesseract์ ํ๋ณ์ฑ๋ฅ์ด ๋ง์ด ๋จ์ด์ง๋ค๊ณ ํ๋๋ฐ ์ด๋ ์นด๋ฉ๋ผ ์บก์ณ ์ดํ ์ฌ์ง์ 'ํ๊ฐ๊ณต' ํ๋ฉด ์ด๋ ์ ๋ ๊ฐ์ ๋์ง ์์๊น ์ถ๋ค. ๋์๊ฐ ์ฌ๋์ด ์ด ์๊ธ์จ๋ ์ธ์์ด ๊ฐ๋ฅํ๊ฒ ํ๊ณ ์ถ์๋ฐ ์ปค์คํ Tessdata ๊ฐ์ ๊ฒ์ ๋ง๋ค์ด์ ์ฌ์ฉํ ์ ์์ง ์์๊น?๋ผ๋ ์์ ํฌ๋ง์ ํ์ผ๋ฉฐ ํฌ์คํ ์ ๋ง๋ฌด๋ฆฌํ๊ฒ ๋ค.