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数据也未能初始化。然而,这种方法做了同样的事情,但它使事情起作用了。