错误:无法启动活动ComponentInfo {com.m.ocrapp / com.m.ocrapp.MainActivity}:java.lang.IllegalArgumentException:数据路径不存在

时间:2018-02-19 16:17:11

标签: android error-handling javacv opencv4android

我正试图从相机拍照并通过tesseract-ocr库对其进行OCR。这是我的完整代码:

清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.m.ocrapp">

    <uses-permission android:name="android.permission.INTERNET"/>

    <uses-permission android:name="android.permission.CAMERA"/>

    <uses-feature android:name="android.hardware.camera"/>
    <uses-feature android:name="android.hardware.camera.autofocus"/>
    <uses-feature android:name="android.hardware.camera.front"/>
    <uses-feature android:name="android.hardware.camera.front.autofocus"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity"
            android:screenOrientation="landscape">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

MainActivity:

package com.m.ocrapp;

public class MainActivity extends AppCompatActivity implements CameraBridgeViewBase.CvCameraViewListener2{


    Scalar CONTOUR_COLOR = new Scalar(255);

    private Bitmap bmp;
    private Mat mIntermediateMat , mGrey, mRgba;
    private JavaCameraView mOpenCvCameraView;
    private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
        @Override
        public void onManagerConnected(int status) {
            switch (status) {
                case LoaderCallbackInterface.SUCCESS: {
                    mOpenCvCameraView.enableView();
                }
                break;
                default: {
                    super.onManagerConnected(status);
                }
                break;
            }
        }
    };

    @Override
    public void onCameraViewStopped() {

    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);



        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        //FULLSCREEN MODE
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,      WindowManager.LayoutParams.FLAG_FULLSCREEN);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        setContentView(R.layout.activity_main);

        mOpenCvCameraView =  findViewById(R.id.my_java_camera);
        mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
        mOpenCvCameraView.setCvCameraViewListener(this);

    }

    public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
        mGrey = inputFrame.gray();
        mRgba = inputFrame.rgba();

        detectText();
        return mRgba;
    }
    @Override
    public void onPause() {
        super.onPause();
        if (mOpenCvCameraView != null)
            mOpenCvCameraView.disableView();
    }

    @Override
    public void onResume() {
        super.onResume();
        if (!OpenCVLoader.initDebug()) {
            OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_1_0, this, mLoaderCallback);
        } else {
            mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
        }
    }

    public void onDestroy() {
        super.onDestroy();

        if (mOpenCvCameraView != null)
            mOpenCvCameraView.disableView();
    }

    public void onCameraViewStarted(int width, int height) {
        mIntermediateMat = new Mat();
        mGrey = new Mat(height, width, CvType.CV_8UC4);
        mRgba = new Mat(height, width, CvType.CV_8UC4);
    }

    private void doOCR(final Bitmap bitmap) {
        String text = mTessOCR.getOCRResult(bitmap);
      //  String temp = mTessOCR.getOCRResult(bitmap);

    }

    private void detectText()
    {
        MatOfKeyPoint keypoint = new MatOfKeyPoint();
        List<KeyPoint> listpoint;
        KeyPoint kpoint;
        Mat mask = Mat.zeros(mGrey.size(), CvType.CV_8UC1);
        int rectanx1;
        int rectany1;
        int rectanx2;
        int rectany2;
        int imgsize = mGrey.height() * mGrey.width();
        Scalar zeos = new Scalar(0, 0, 0);

        List<MatOfPoint> contour2 = new ArrayList<MatOfPoint>();
        Mat kernel = new Mat(1, 50, CvType.CV_8UC1, Scalar.all(255));
        Mat morbyte = new Mat();
        Mat hierarchy = new Mat();

        Rect rectan3;
        //
        FeatureDetector detector = FeatureDetector
                .create(FeatureDetector.MSER);
        detector.detect(mGrey, keypoint);
        listpoint = keypoint.toList();
        //
        for (int ind = 0; ind < listpoint.size(); ind++) {
            kpoint = listpoint.get(ind);
            rectanx1 = (int) (kpoint.pt.x - 0.5 * kpoint.size);
            rectany1 = (int) (kpoint.pt.y - 0.5 * kpoint.size);
            rectanx2 = (int) (kpoint.size);
            rectany2 = (int) (kpoint.size);
            if (rectanx1 <= 0)
                rectanx1 = 1;
            if (rectany1 <= 0)
                rectany1 = 1;
            if ((rectanx1 + rectanx2) > mGrey.width())
                rectanx2 = mGrey.width() - rectanx1;
            if ((rectany1 + rectany2) > mGrey.height())
                rectany2 = mGrey.height() - rectany1;
            Rect rectant = new Rect(rectanx1, rectany1, rectanx2, rectany2);
            try {
                Mat roi = new Mat(mask, rectant);
                roi.setTo(CONTOUR_COLOR);
            } catch (Exception ex) {
                Log.d("mylog", "mat roi error " + ex.getMessage());
            }
        }

        Imgproc.morphologyEx(mask, morbyte, Imgproc.MORPH_DILATE, kernel);
        Imgproc.findContours(morbyte, contour2, hierarchy,
                Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_NONE);
        /*

        for (int ind = 0; ind < contour2.size(); ind++) {
            rectan3 = Imgproc.boundingRect(contour2.get(ind));
            rectan3 = Imgproc.boundingRect(contour2.get(ind));
            if (rectan3.area() > 0.5 * imgsize || rectan3.area() < 100
                    || rectan3.width / rectan3.height < 2) {
                Mat roi = new Mat(morbyte, rectan3);
                roi.setTo(zeos);

            } else
                Imgproc.rectangle(mRgba, rectan3.br(), rectan3.tl(), CONTOUR_COLOR);

            */


        for (int ind = 0; ind < contour2.size(); ind++)
        {
            rectan3 = Imgproc.boundingRect(contour2.get(ind));
            try {
                Mat croppedPart;
                croppedPart = mIntermediateMat.submat(rectan3);
                bmp = Bitmap.createBitmap(croppedPart.width(), croppedPart.height(), Bitmap.Config.ARGB_8888);
                Utils.matToBitmap(croppedPart, bmp);
            } catch (Exception e) {
             //   Log.d(TAG, "cropped part data error " + e.getMessage());
            }
            if (bmp != null) {
                doOCR(bmp);
            }
        }


    }

}

MyTessOCR:

package com.m.ocrapp;

public class MyTessOCR
{
        private String datapath;
        private TessBaseAPI mTess;
        Context context;

    public MyTessOCR(Context context)
    {
            datapath = Environment.getExternalStorageDirectory() + "/ocrctz/";
            File dir = new File(datapath + "/tessdata/");
            File file = new File(datapath + "/tessdata/" + "eng.traineddata");
            if (!file.exists()) {
                Log.d("mylog", "in file doesn't exist");
                dir.mkdirs();
                copyFile(context);
            }

            mTess = new TessBaseAPI();
            String language = "eng";
            mTess.init(datapath, language);
            //Auto only        mTess.setPageSegMode(TessBaseAPI.PageSegMode.PSM_AUTO_ONLY);
        }

        public void stopRecognition()
        {
            mTess.stop();
        }

        public String getOCRResult(Bitmap bitmap)
        {
            mTess.setImage(bitmap);
            String result = mTess.getUTF8Text();
            return result;
        }

        public void onDestroy()
        {
            if (mTess != null)
                mTess.end();
        }

        private void copyFile(Context context)
        {
            AssetManager assetManager = context.getAssets();
            try {
                InputStream in = assetManager.open("eng.traineddata");
                OutputStream out = new FileOutputStream(datapath + "/tessdata/" + "eng.traineddata");
                byte[] buffer = new byte[1024];
                int read = in.read(buffer);
                while (read != -1)
                {
                    out.write(buffer, 0, read);
                    read = in.read(buffer);
                }
            } catch (Exception e)
            {
                Log.d("mylog", "couldn't copy with the following error : " + e.toString());
            }
        }
  //  }

}

但在此行的MainActivity内:mTess.init(datapath, language); 我收到此错误消息:

  

java.lang.RuntimeException:无法启动活动   ComponentInfo {com.m.ocrapp / com.m.ocrapp.MainActivity}:   java.lang.IllegalArgumentException:数据路径不存在!

我还必须说我已在项目的assets路径中创建了app/src/main/assets文件夹,并将eng.traineddatahttps://github.com/tesseract-ocr/tessdata/blob/master/eng.traineddata复制到其中。但我认为这还不够,我应该将更多文件从tesseract复制到我的项目中?但我不知道哪些文件在哪里?

(事实上,我在网站内看到了这段代码,并按上述方式进行了尝试)

1 个答案:

答案 0 :(得分:1)

<uses-permission android:name="android.permission.CAMERA"/>

<uses-feature android:name="android.hardware.camera"/>
<uses-feature android:name="android.hardware.camera.autofocus"/>
<uses-feature android:name="android.hardware.camera.front"/>
<uses-feature android:name="android.hardware.camera.front.autofocus"/>

缺少android权限。您尝试触摸文件存储系统时需要这些权限。

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />