Тессеракт в андроиде (Tess Two): сбой приложения при использовании nep.traineddata и не работает ввод с камеры - PullRequest
0 голосов
/ 26 апреля 2018

Я не большой эксперт. Я использую tesseract (tess-two) для разработки приложения для Android для своего проекта в колледже. Приложение вылетает, когда я выбираю непальские обученные данные.

* Приложение работает только с изображением, выбранным из галереи. Изображение с камеры возвращает пустой результат. Так да! У меня большие проблемы здесь !!

Вот фрагмент LogCat, когда я использовал eng.trainddata:

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$3@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$5@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$3@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$5@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:

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;
    }
}

Также есть еще один класс, который успешно копирует обученные непальским и английским языком данные в хранилище.

Так, что я здесь не так делаю? Нет никакого результата, когда камера используется, и приложение вылетает, когда непалые обученные данные используются с источником галереи. Пожалуйста, помогите мне здесь. Я не хочу делать это снова в resit.

1 Ответ

0 голосов
/ 04 мая 2018

Итак, еще одна вещь, которую я сделал неправильно, это значение dataDirectory, и просто изменение его значения сделало приложение очень стабильным. Данные nep.trained были найдены и инициализированы тессерактом после этого.

private static final String dataDirectory = Environment.getExternalStorageDirectory().getAbsolutePath() + "/com.lokensapkota.android.neptext/";

Кроме того, если я изменил всю функцию в классе MainApplication; который был просто там, чтобы скопировать обученные данные, в метод и запустить его в фоновом режиме.

 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.traineddata не удалось инициализировать. этот метод, однако, делал то же самое, но он заставлял вещи работать.

...