android 中的 Tesseract(苔丝二):使用 nep.traineddata 时应用程序崩溃并且来自相机的输入不工作
Tesseract in android (Tess Two): Application crashes while using nep.traineddata and Input from Camera is not working
我不太会 expert.I 我正在使用 tesseract (tess-two) 为我的大学项目开发 android 应用程序。当我 select 尼泊尔训练数据时应用程序崩溃。
*该应用程序仅适用于 select 图片库中的图片。从相机拍摄的图像 returns 空结果。所以,是的!我这里有大麻烦了!!
这是我使用 eng.trainddata 时 LogCat 的片段:
04-26 22:52:02.286 26503-26509/com.l.android.neptext I/zygote64: Do partial code cache collection, code=124KB, data=69KB
After code cache collection, code=124KB, data=69KB
Increasing code cache capacity to 512KB
04-26 22:52:02.347 26503-26520/com.l.android.neptext I/vndksupport: sphal namespace is not configured for this process. Loading /vendor/lib64/hw/gralloc.msm8996.so from the current namespace instead.
04-26 22:52:08.559 26503-26503/com.l.android.neptext D/com.l.android.neptext.MainActivity@2314718: onClick:
04-26 22:52:08.612 26503-26503/com.l.android.neptext D/AppTracker: App Event: stop
04-26 22:52:21.431 26503-26503/com.l.android.neptext D/AppTracker: App Event: start
04-26 22:52:21.603 26503-26589/com.l.android.neptext I/com.l.android.neptext.MainActivity@8074bd5: bitmap size8294400
04-26 22:52:22.232 26503-26589/com.l.android.neptext I/Tesseract(native): Initialized Tesseract API with language=eng
04-26 22:52:35.031 26503-26509/com.l.android.neptext I/zygote64: Compiler allocated 6MB to compile void android.view.ViewRootImpl.performTraversals()
04-26 22:52:39.452 26503-26503/com.l.android.neptext D/AppTracker: App Event: stop
我使用 nep.traineddata 时的另一个片段:
04-26 22:53:44.007 26764-26769/com.l.android.neptext I/zygote64: Compiler allocated 6MB to compile void android.view.ViewRootImpl.performTraversals()
04-26 22:53:44.095 26764-26780/com.l.android.neptext D/OpenGLRenderer: endAllActiveAnimators on 0x7e841e2000 (DropDownListView) with handle 0x7e7abf6840
04-26 22:53:46.978 26764-26764/com.l.android.neptext D/com.l.android.neptext.MainActivity@cc3f660: onClick:
04-26 22:53:47.033 26764-26764/com.l
.android.neptext D/AppTracker: App Event: stop
04-26 22:54:00.276 26764-26764/com.l.android.neptext D/AppTracker: App Event: start
04-26 22:54:00.449 26764-26815/com.l.android.neptext I/com.l.android.neptext.MainActivity@c8be754: bitmap size8294400
应用程序崩溃,没有其他错误消息。
项目代码:
public class MainActivity extends AppCompatActivity {
public static Button camera,gallery,cut,copy,speech;
public static EditText text;
public static TextView textView;
public static final int GALERY_ACTION=100;
public static final int CAMERA_ACTION=101;
public static Uri imageuri=null;
Handler texthandler;
TextToSpeech t1;
Spinner spinner;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
camera=findViewById(R.id.button1);
gallery=findViewById(R.id.button2);
cut=findViewById(R.id.cut_btn);
copy=findViewById(R.id.copy_btn);
speech=findViewById(R.id.speech_btn);
text = findViewById(R.id.result_text);
textView=findViewById(R.id.textView);
spinner=findViewById(R.id.spinner);
spinner=findViewById(R.id.spinner);
List<String> categories = new ArrayList<String>();
categories.add("eng");
categories.add("nep");
// Creating adapter for spinner
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, categories);
// Drop down layout style - list view with radio button
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// attaching data adapter to spinner
spinner.setAdapter(dataAdapter);
t1=new TextToSpeech(getApplicationContext(), new TextToSpeech.OnInitListener() {
@Override
public void onInit(int status) {
if(status != TextToSpeech.ERROR) {
t1.setLanguage(Locale.UK);
}
}
});
texthandler=new Handler(Looper.myLooper()){
@Override
public void handleMessage(Message msg) {
String t=(String)msg.obj;
if(t==null){
Toast.makeText(getApplicationContext(),"Cannot find any letters ",Toast.LENGTH_LONG).show();
}
text = findViewById(R.id.result_text);
text.setText((String)msg.obj);
}
};
onButtonClickListiner();
//copying tranning datas
try {
MainApplication.instance.copydata("eng");
MainApplication.instance.copydata("nep");
}catch(Exception e){
Log.d("OcrManager",e.getMessage());
}
}
public void copy(View view){
text = findViewById(R.id.result_text);
Log.d(this.toString(),text.getText().toString());
ClipboardManager clipboardManager=(ClipboardManager)getApplicationContext().getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clipData=ClipData.newPlainText("label",text.getText().toString());
clipboardManager.setPrimaryClip(clipData);
Toast.makeText(MainActivity.this,"Text copied to clipbaord",Toast.LENGTH_LONG).show();
}
public void cut(View view){
text = findViewById(R.id.result_text);
Log.d(this.toString(),text.getText().toString());
ClipboardManager clipboardManager=(ClipboardManager)getApplicationContext().getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clipData=ClipData.newPlainText("label",text.getText().toString());
clipboardManager.setPrimaryClip(clipData);
text.setText("");
Toast.makeText(MainActivity.this,"Text copied to clipbaord",Toast.LENGTH_LONG).show();
}
public void speech(View view){
text = findViewById(R.id.result_text);
Log.d(this.toString(),text.getText().toString());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
t1.speak(text.getText().toString(),TextToSpeech.QUEUE_FLUSH,null,null);
} else {
t1.speak(text.getText().toString(), TextToSpeech.QUEUE_FLUSH, null);
}
Toast.makeText(this,"Speaking now",Toast.LENGTH_LONG).show();
}
private void onButtonClickListiner(){
gallery.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try{
Log.d(this.toString(), "onClick: ");
Intent galaryIntent=new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI);
startActivityForResult(galaryIntent,GALERY_ACTION);
gallery.setVisibility(View.GONE);
camera.setVisibility(View.GONE);
textView.setVisibility(View.GONE);
cut.setVisibility(View.VISIBLE);
copy.setVisibility(View.VISIBLE);
speech.setVisibility(View.VISIBLE);
text.setVisibility(View.VISIBLE);
spinner.setVisibility(View.GONE);
}catch(Exception e){
Log.d("Main actiity",e.getMessage());
}
}
});
camera.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try{
Intent cameraIntent=new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent,CAMERA_ACTION);
gallery.setVisibility(View.GONE);
camera.setVisibility(View.GONE);
textView.setVisibility(View.GONE);
cut.setVisibility(View.VISIBLE);
copy.setVisibility(View.VISIBLE);
speech.setVisibility(View.VISIBLE);
text.setVisibility(View.VISIBLE);
spinner.setVisibility(View.GONE);
}catch(Exception e){
Log.d("Main actiity",e.getMessage());
}
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, final Intent data) {
if (resultCode == RESULT_OK && data != null) {
if (requestCode == GALERY_ACTION) {
imageuri = data.getData();
try {
MainApplication.instance.showToast("Rendering Started,Please wait");
new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare();
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), imageuri);
Log.i(this.toString(),"bitmap size"+bitmap.getByteCount());
OcrManager ocrManager= new OcrManager();
ocrManager.ocrStart(spinner.getSelectedItem().toString());
final String s = ocrManager.getText(bitmap);
Message m = new Message();
m.obj = s;
texthandler.sendMessage(m);
} catch (Exception e) {
Log.e("Main actiity", e.getMessage());
}
}
}).start();
} catch (Exception e) {
Log.d(this.toString(), e.getMessage());
}
}else if(requestCode==CAMERA_ACTION){
try {
MainApplication.instance.showToast("Rendering Started,Please wait");
new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare();
try {
Bundle bundle=data.getExtras();
Bitmap bitmap = (Bitmap)bundle.get("data");
OcrManager ocrManager= new OcrManager();
ocrManager.ocrStart(spinner.getSelectedItem().toString());
final String s = ocrManager.getText(bitmap);
Message m = new Message();
m.obj = s;
texthandler.sendMessage(m);
} catch (Exception e) {
Log.d("Main actiity", e.getMessage());
}
}
}).start();
} catch (Exception e) {
Log.d(this.toString(), e.getMessage());
}
}
}
}
}
OCRManager Class:
public class OcrManager {
public static TessBaseAPI base=null;
public void ocrStart(String lang) {
try{
base = new TessBaseAPI();
String dataDirectory = MainApplication.instance.tessDataPathParent();
base.init(dataDirectory, lang);
}catch(Exception e){}
}
public String getText(Bitmap bitmap){
base.setImage(bitmap);
MainApplication.instance.showToast("Conversion Started");
String out=base.getUTF8Text();
MainApplication.instance.showToast("Conversion finished");
return out;
}
}
另外还有一个class成功复制尼泊尔语和英语训练数据到存储。
那么,我做错了什么?使用相机时没有任何结果,当尼泊尔训练数据与图库源一起使用时应用程序崩溃。请帮帮我。我不想再这样做了。
所以我做错的另一件事是 dataDirectory 的值,仅仅改变它的值就使应用程序非常稳定。之后nep.trained数据被tesseract找到并初始化。
private static final String dataDirectory = Environment.getExternalStorageDirectory().getAbsolutePath() + "/com.lokensapkota.android.neptext/";
此外,如果我更改 MainApplication 中的整个函数 class;它只是用来将训练数据复制到方法中,然后 运行 它在后台。:
private void copyAssets() {
AssetManager assetManager = getAssets();
String[] files = null;
try {
files = assetManager.list("trainneddata");
} catch (IOException e) {
Log.e("tag", "Failed to get asset file list.", e);
}
for(String filename : files) {
Log.i("files",filename);
InputStream in = null;
OutputStream out = null;
String dirout= dataDirectory + "tessdata/";
File outFile = new File(dirout, filename);
if(!outFile.exists()) {
try {
in = assetManager.open("trainneddata/"+filename);
(new File(dirout)).mkdirs();
out = new FileOutputStream(outFile);
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch (IOException e) {
Log.e("tag", "Error creating files", e);
}
}
}
}
private void copyFile(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while((read = in.read(buffer)) != -1){
out.write(buffer, 0, read);
}
}
即使之前的MainApplication.class将英语和尼泊尔语训练数据复制到应用程序目录,nep.trained数据也未能初始化。然而,这种方法做了同样的事情,但它使事情起作用了。
我不太会 expert.I 我正在使用 tesseract (tess-two) 为我的大学项目开发 android 应用程序。当我 select 尼泊尔训练数据时应用程序崩溃。
*该应用程序仅适用于 select 图片库中的图片。从相机拍摄的图像 returns 空结果。所以,是的!我这里有大麻烦了!!
这是我使用 eng.trainddata 时 LogCat 的片段:
04-26 22:52:02.286 26503-26509/com.l.android.neptext I/zygote64: Do partial code cache collection, code=124KB, data=69KB
After code cache collection, code=124KB, data=69KB
Increasing code cache capacity to 512KB
04-26 22:52:02.347 26503-26520/com.l.android.neptext I/vndksupport: sphal namespace is not configured for this process. Loading /vendor/lib64/hw/gralloc.msm8996.so from the current namespace instead.
04-26 22:52:08.559 26503-26503/com.l.android.neptext D/com.l.android.neptext.MainActivity@2314718: onClick:
04-26 22:52:08.612 26503-26503/com.l.android.neptext D/AppTracker: App Event: stop
04-26 22:52:21.431 26503-26503/com.l.android.neptext D/AppTracker: App Event: start
04-26 22:52:21.603 26503-26589/com.l.android.neptext I/com.l.android.neptext.MainActivity@8074bd5: bitmap size8294400
04-26 22:52:22.232 26503-26589/com.l.android.neptext I/Tesseract(native): Initialized Tesseract API with language=eng
04-26 22:52:35.031 26503-26509/com.l.android.neptext I/zygote64: Compiler allocated 6MB to compile void android.view.ViewRootImpl.performTraversals()
04-26 22:52:39.452 26503-26503/com.l.android.neptext D/AppTracker: App Event: stop
我使用 nep.traineddata 时的另一个片段:
04-26 22:53:44.007 26764-26769/com.l.android.neptext I/zygote64: Compiler allocated 6MB to compile void android.view.ViewRootImpl.performTraversals()
04-26 22:53:44.095 26764-26780/com.l.android.neptext D/OpenGLRenderer: endAllActiveAnimators on 0x7e841e2000 (DropDownListView) with handle 0x7e7abf6840
04-26 22:53:46.978 26764-26764/com.l.android.neptext D/com.l.android.neptext.MainActivity@cc3f660: onClick:
04-26 22:53:47.033 26764-26764/com.l
.android.neptext D/AppTracker: App Event: stop
04-26 22:54:00.276 26764-26764/com.l.android.neptext D/AppTracker: App Event: start
04-26 22:54:00.449 26764-26815/com.l.android.neptext I/com.l.android.neptext.MainActivity@c8be754: bitmap size8294400
应用程序崩溃,没有其他错误消息。
项目代码:
public class MainActivity extends AppCompatActivity {
public static Button camera,gallery,cut,copy,speech;
public static EditText text;
public static TextView textView;
public static final int GALERY_ACTION=100;
public static final int CAMERA_ACTION=101;
public static Uri imageuri=null;
Handler texthandler;
TextToSpeech t1;
Spinner spinner;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
camera=findViewById(R.id.button1);
gallery=findViewById(R.id.button2);
cut=findViewById(R.id.cut_btn);
copy=findViewById(R.id.copy_btn);
speech=findViewById(R.id.speech_btn);
text = findViewById(R.id.result_text);
textView=findViewById(R.id.textView);
spinner=findViewById(R.id.spinner);
spinner=findViewById(R.id.spinner);
List<String> categories = new ArrayList<String>();
categories.add("eng");
categories.add("nep");
// Creating adapter for spinner
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, categories);
// Drop down layout style - list view with radio button
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// attaching data adapter to spinner
spinner.setAdapter(dataAdapter);
t1=new TextToSpeech(getApplicationContext(), new TextToSpeech.OnInitListener() {
@Override
public void onInit(int status) {
if(status != TextToSpeech.ERROR) {
t1.setLanguage(Locale.UK);
}
}
});
texthandler=new Handler(Looper.myLooper()){
@Override
public void handleMessage(Message msg) {
String t=(String)msg.obj;
if(t==null){
Toast.makeText(getApplicationContext(),"Cannot find any letters ",Toast.LENGTH_LONG).show();
}
text = findViewById(R.id.result_text);
text.setText((String)msg.obj);
}
};
onButtonClickListiner();
//copying tranning datas
try {
MainApplication.instance.copydata("eng");
MainApplication.instance.copydata("nep");
}catch(Exception e){
Log.d("OcrManager",e.getMessage());
}
}
public void copy(View view){
text = findViewById(R.id.result_text);
Log.d(this.toString(),text.getText().toString());
ClipboardManager clipboardManager=(ClipboardManager)getApplicationContext().getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clipData=ClipData.newPlainText("label",text.getText().toString());
clipboardManager.setPrimaryClip(clipData);
Toast.makeText(MainActivity.this,"Text copied to clipbaord",Toast.LENGTH_LONG).show();
}
public void cut(View view){
text = findViewById(R.id.result_text);
Log.d(this.toString(),text.getText().toString());
ClipboardManager clipboardManager=(ClipboardManager)getApplicationContext().getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clipData=ClipData.newPlainText("label",text.getText().toString());
clipboardManager.setPrimaryClip(clipData);
text.setText("");
Toast.makeText(MainActivity.this,"Text copied to clipbaord",Toast.LENGTH_LONG).show();
}
public void speech(View view){
text = findViewById(R.id.result_text);
Log.d(this.toString(),text.getText().toString());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
t1.speak(text.getText().toString(),TextToSpeech.QUEUE_FLUSH,null,null);
} else {
t1.speak(text.getText().toString(), TextToSpeech.QUEUE_FLUSH, null);
}
Toast.makeText(this,"Speaking now",Toast.LENGTH_LONG).show();
}
private void onButtonClickListiner(){
gallery.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try{
Log.d(this.toString(), "onClick: ");
Intent galaryIntent=new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI);
startActivityForResult(galaryIntent,GALERY_ACTION);
gallery.setVisibility(View.GONE);
camera.setVisibility(View.GONE);
textView.setVisibility(View.GONE);
cut.setVisibility(View.VISIBLE);
copy.setVisibility(View.VISIBLE);
speech.setVisibility(View.VISIBLE);
text.setVisibility(View.VISIBLE);
spinner.setVisibility(View.GONE);
}catch(Exception e){
Log.d("Main actiity",e.getMessage());
}
}
});
camera.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try{
Intent cameraIntent=new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent,CAMERA_ACTION);
gallery.setVisibility(View.GONE);
camera.setVisibility(View.GONE);
textView.setVisibility(View.GONE);
cut.setVisibility(View.VISIBLE);
copy.setVisibility(View.VISIBLE);
speech.setVisibility(View.VISIBLE);
text.setVisibility(View.VISIBLE);
spinner.setVisibility(View.GONE);
}catch(Exception e){
Log.d("Main actiity",e.getMessage());
}
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, final Intent data) {
if (resultCode == RESULT_OK && data != null) {
if (requestCode == GALERY_ACTION) {
imageuri = data.getData();
try {
MainApplication.instance.showToast("Rendering Started,Please wait");
new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare();
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), imageuri);
Log.i(this.toString(),"bitmap size"+bitmap.getByteCount());
OcrManager ocrManager= new OcrManager();
ocrManager.ocrStart(spinner.getSelectedItem().toString());
final String s = ocrManager.getText(bitmap);
Message m = new Message();
m.obj = s;
texthandler.sendMessage(m);
} catch (Exception e) {
Log.e("Main actiity", e.getMessage());
}
}
}).start();
} catch (Exception e) {
Log.d(this.toString(), e.getMessage());
}
}else if(requestCode==CAMERA_ACTION){
try {
MainApplication.instance.showToast("Rendering Started,Please wait");
new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare();
try {
Bundle bundle=data.getExtras();
Bitmap bitmap = (Bitmap)bundle.get("data");
OcrManager ocrManager= new OcrManager();
ocrManager.ocrStart(spinner.getSelectedItem().toString());
final String s = ocrManager.getText(bitmap);
Message m = new Message();
m.obj = s;
texthandler.sendMessage(m);
} catch (Exception e) {
Log.d("Main actiity", e.getMessage());
}
}
}).start();
} catch (Exception e) {
Log.d(this.toString(), e.getMessage());
}
}
}
}
}
OCRManager Class:
public class OcrManager {
public static TessBaseAPI base=null;
public void ocrStart(String lang) {
try{
base = new TessBaseAPI();
String dataDirectory = MainApplication.instance.tessDataPathParent();
base.init(dataDirectory, lang);
}catch(Exception e){}
}
public String getText(Bitmap bitmap){
base.setImage(bitmap);
MainApplication.instance.showToast("Conversion Started");
String out=base.getUTF8Text();
MainApplication.instance.showToast("Conversion finished");
return out;
}
}
另外还有一个class成功复制尼泊尔语和英语训练数据到存储。
那么,我做错了什么?使用相机时没有任何结果,当尼泊尔训练数据与图库源一起使用时应用程序崩溃。请帮帮我。我不想再这样做了。
所以我做错的另一件事是 dataDirectory 的值,仅仅改变它的值就使应用程序非常稳定。之后nep.trained数据被tesseract找到并初始化。
private static final String dataDirectory = Environment.getExternalStorageDirectory().getAbsolutePath() + "/com.lokensapkota.android.neptext/";
此外,如果我更改 MainApplication 中的整个函数 class;它只是用来将训练数据复制到方法中,然后 运行 它在后台。:
private void copyAssets() {
AssetManager assetManager = getAssets();
String[] files = null;
try {
files = assetManager.list("trainneddata");
} catch (IOException e) {
Log.e("tag", "Failed to get asset file list.", e);
}
for(String filename : files) {
Log.i("files",filename);
InputStream in = null;
OutputStream out = null;
String dirout= dataDirectory + "tessdata/";
File outFile = new File(dirout, filename);
if(!outFile.exists()) {
try {
in = assetManager.open("trainneddata/"+filename);
(new File(dirout)).mkdirs();
out = new FileOutputStream(outFile);
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch (IOException e) {
Log.e("tag", "Error creating files", e);
}
}
}
}
private void copyFile(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while((read = in.read(buffer)) != -1){
out.write(buffer, 0, read);
}
}
即使之前的MainApplication.class将英语和尼泊尔语训练数据复制到应用程序目录,nep.trained数据也未能初始化。然而,这种方法做了同样的事情,但它使事情起作用了。