Google ML Kit на андроид очень плохо распознаёт текст
Хотел создать приложение, распознающее текст с картинки пользователя. Пробовал Google ML Kit - текст с изображения распознаётся очень плохо. Ещё пробовал Tesseract4Android, работает ещё хуже.
MainActivity.kt
package com.example.textrecognizer
import android.Manifest
import android.app.AlertDialog
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.provider.MediaStore
import androidx.activity.viewModels
import androidx.annotation.RequiresApi
import com.example.russiantextrecognizer.databinding.ActivityMainBinding
import java.io.IOException
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private val vm: MainViewModel by viewModels()
@RequiresApi(Build.VERSION_CODES.M)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
//
init()
}
@RequiresApi(Build.VERSION_CODES.M)
private fun init() {
binding.cameraBtn.setOnClickListener {
if (checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
val cameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
startActivityForResult(cameraIntent, 3)
} else {
requestPermissions(arrayOf(Manifest.permission.CAMERA), 100)
}
}
//
binding.galleryBtn.setOnClickListener {
val galleryIntent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
startActivityForResult(galleryIntent, 1)
}
// handling result text
vm.resultText.observe(this) {
val intent = Intent(this, ResultActivity::class.java)
intent.putExtra("text", it)
startActivity(intent)
}
}
// image handler
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == RESULT_OK) {
if (requestCode == 3) {
val image = data?.extras?.get("data") as Bitmap
vm.createPrediction(image)
} else {
val dataUri = data?.data
var image: Bitmap? = null
try {
image = MediaStore.Images.Media.getBitmap(contentResolver, dataUri)
} catch (e: IOException) {
e.printStackTrace()
}
if (image != null) {
vm.createPrediction(image)
}
}
}
}
// permission handler
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == 100 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
val cameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
startActivityForResult(cameraIntent, 3)
} else {
AlertDialog.Builder(this)
.setTitle("Внимание!")
.setMessage("Для использования приложения нужно принять разрешение на использование" +
" камеры")
.setPositiveButton("Ок") { dialog, _ ->
dialog.cancel()
finish()
}.create().show()
}
}
}
MainViewModel.kt
package com.example.textrecognizer
import android.graphics.Bitmap
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.google.mlkit.vision.common.InputImage
import com.google.mlkit.vision.text.TextRecognition
import com.google.mlkit.vision.text.latin.TextRecognizerOptions
class MainViewModel : ViewModel() {
val resultText = MutableLiveData<String>()
fun createPrediction(bitmap: Bitmap) {
val recognizer = TextRecognition.getClient(TextRecognizerOptions.DEFAULT_OPTIONS)
val image = InputImage.fromBitmap(bitmap, 0)
recognizer.process(image)
.addOnSuccessListener { visionText ->
resultText.value = visionText.text
}
.addOnFailureListener { error ->
error.printStackTrace()
}
}
}
ResultActivity.kt
package com.example.textrecognizer
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
import androidx.annotation.RequiresApi
import com.example.russiantextrecognizer.databinding.ActivityResultBinding
class ResultActivity : AppCompatActivity() {
private lateinit var binding: ActivityResultBinding
@RequiresApi(Build.VERSION_CODES.M)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityResultBinding.inflate(layoutInflater)
setContentView(binding.root)
//
init()
}
@RequiresApi(Build.VERSION_CODES.M)
private fun init() {
val extras = intent.extras
if (extras != null) {
val value = extras.getString("text")
binding.mainText.text = value
}
binding.backBtn.setOnClickListener {
finish()
}
binding.copyBtn.setOnClickListener {
val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val clip = ClipData.newPlainText("Copied data", binding.mainText.text.toString())
clipboard.setPrimaryClip(clip)
Toast.makeText(this@ResultActivity, "Copied!", Toast.LENGTH_LONG).show()
}
}
}
Возможно стоило бы как-то обрабатывать картинку перед подачей её в нейронку. Подскажите, в чём проблема.