简易OCR库不起作用

时间:2016-06-21 04:09:16

标签: java android ocr

这是我的第一个Android App项目,我正在尝试使用Priyank Verma Easy OCR Library制作的Easy OCR库在我的Android应用中应用OCR功能,因为它是最简化的&我可以使用最新的OCR库。但我认为该图书馆的创建者不会在他自己的博客中回答人们的查询,所以我试着在这里问一下。如果这不是一个好问题,我会删除它。

所以这就是问题,我有一个带有四个标签的应用程序,在其中一个标签中,我尝试使用库示例,我尝试在我的标签中应用它们。在该选项卡中,有一个“扫描”按钮,可以拍摄照片,保存并扫描。之后,它应该从扫描过程返回文本字符的输出。并且应用程序的执行成功返回,没有错误。

但问题在于,它无法保存图片,导致扫描过程失败,从而无法返回任何内容。我在这里看不到任何问题,也许有眼睛敏锐的人可以发现它们?

|||||更新1 |||||

我按照Ishita Sinha的建议设置了断点,我发现文件已保存,它只保存在我内部存储的不同目录中( / storage / emulated / 0 / EasyOcrScanner < / em>或内部存储/ EasyOcrScanner )。这里发生的真正冲突是在保存图像之后,即扫描图像。不过,我无法弄清楚为什么会这样。我在 FileUtils Java EasyOCRScanner Java 中标记了“ %% ” em> 显示我发现的内容。在保存图像后,我需要一些关于如何成功扫描的帮助。

||||||||||||||||||||||||||||||

|||||更新2 |||||

我已根据Anand Savjani的要求将我的项目推送到GitHub上。你们可以在那里查看。项目名称为“Queue-App”。

https://github.com/Kaydarin/Queue-App

||||||||||||||||||||||||||||||

----------来自我的应用程序选项卡----------

我应用的清单

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.kaydarinapp.queueappv2">
    <!-- Save file permission -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <!-- Read file permission -->
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <!-- Camera permission -->
    <uses-feature android:name="android.hardware.camera" />
    <uses-permission android:name="android.permission.CAMERA" />
    <!-- Internet permission -->
    <uses-permission android:name="android.permission.INTERNET" />
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity"
            android:screenOrientation="portrait"
            android:configChanges="keyboardHidden|orientation|screenSize">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>

我的标签的XML

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".Tab2"
    android:gravity="center_horizontal"
    >

    <TextView android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/textView"
        android:layout_marginTop="45dp"
        android:layout_gravity="center_horizontal"
        android:textSize="8pt"
        />


    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/button"
        android:layout_marginTop="20dp"
        android:text="Scan"
        android:layout_gravity="center_vertical" />

</LinearLayout>

我的标签页

package com.kaydarinapp.queueappv2;
import android.app.ProgressDialog;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.wordpress.priyankvex.easyocrscannerdemo.Config;
import com.wordpress.priyankvex.easyocrscannerdemo.EasyOcrScanner;
import com.wordpress.priyankvex.easyocrscannerdemo.EasyOcrScannerListener;

/**
 * Created by Kaydarin on 6/1/2016.
 */

//Our class extending fragment
public class Tab2 extends Fragment implements EasyOcrScannerListener {

    private LinearLayout linearLayout;
    private FragmentActivity fragActivity;
    EasyOcrScanner mEasyOcrScanner;
    TextView textView;
    ProgressDialog mProgressDialog;
    Button btnCapture;

    //Overriden method onCreateView
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        fragActivity = super.getActivity();
        linearLayout = (LinearLayout) inflater.inflate(R.layout.tab2, container, false);

        textView = (TextView) fragActivity.findViewById(R.id.textView);

        // initialize EasyOcrScanner instance.
        mEasyOcrScanner = new EasyOcrScanner(getActivity(), "EasyOcrScanner",
                Config.REQUEST_CODE_CAPTURE_IMAGE, "eng");

        // Set ocrScannerListener
        mEasyOcrScanner.setOcrScannerListener(this);

        btnCapture = (Button) linearLayout.findViewById(R.id.button);
        btnCapture.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                mEasyOcrScanner.takePicture();
            }
        });

        return linearLayout;
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        // Call onImageTaken() in onActivityResult.
        if (resultCode == getActivity().RESULT_OK && requestCode == Config.REQUEST_CODE_CAPTURE_IMAGE){
            mEasyOcrScanner.onImageTaken();
        }
    }

    /**
     * Callback when after taking picture, scanning process starts.
     * Good place to show a progress dialog.
     * @param filePath file path of the image file being processed.
     */
    @Override
    public void onOcrScanStarted(String filePath) {
        mProgressDialog = new ProgressDialog(getActivity());
        mProgressDialog.setMessage("Scanning...");
        mProgressDialog.show();
    }

    /**
     * Callback when scanning is finished.
     * Good place to hide teh progress dialog.
     * @param bitmap Bitmap of image that was scanned.
     * @param recognizedText Scanned text.
     */
    @Override
    public void onOcrScanFinished(Bitmap bitmap, String recognizedText) {
        textView.setText(recognizedText);
        if (mProgressDialog.isShowing()){
            mProgressDialog.dismiss();
        }
    }
}

----------来自Easy OCR Library ----------

简易OCR图书馆的清单

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

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

</manifest>

配置Java

package com.wordpress.priyankvex.easyocrscannerdemo;

/**
 * Created by Priyank(@priyankvex) on 27/8/15.
 */
public class Config {

    public static String TAG = "OcrScanner";
    public static int REQUEST_CODE_CAPTURE_IMAGE = 1995;

}

EasyOCRScannerListener Java

package com.wordpress.priyankvex.easyocrscannerdemo;

import android.graphics.Bitmap;

/**
 * Created by Priyank(@priyankvex) on 27/8/15.
 *
 * Interface for the callbacks for {@link EasyOcrScanner}.
 */
public interface EasyOcrScannerListener {

    public void onOcrScanStarted(String filePath);

    public void onOcrScanFinished(Bitmap bitmap, String recognizedText);
}

EasyOCRScanner Java

package com.wordpress.priyankvex.easyocrscannerdemo;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.util.Log;

import java.io.File;
import java.util.Calendar;

/**
 * Created by Priyank(@priyankvex) on 27/8/15.
 *
 * Class to handle scanning of image.
 */
public class EasyOcrScanner {

    protected Activity mActivity;
    private String directoryPathOriginal;
    private String filePathOriginal;
    private int requestCode;
    private EasyOcrScannerListener mOcrScannerListener;
    private String trainedDataCode;

    public EasyOcrScanner(Activity activity, String directoryPath, int requestCode, String trainedDataCode){
        this.mActivity = activity;
        this.directoryPathOriginal = directoryPath;
        this.requestCode = requestCode;
        this.trainedDataCode = trainedDataCode;
    }

    public void takePicture(){
        Intent e = new Intent("android.media.action.IMAGE_CAPTURE");
        this.filePathOriginal = FileUtils.getDirectory(this.directoryPathOriginal) + File.separator + Calendar.getInstance().getTimeInMillis() + ".jpg";
        e.putExtra("output", Uri.fromFile(new File(this.filePathOriginal)));

        startActivity(e);
    } // %%%%%%%%%%%% POSITIVE BREAKPOINT: AFTER THIS POINT, THE APP DOES NOT APPEAR TO SCAN THE CAPTURED IMAGE AS IT RETURN BACK TO THE APP WITHOUT ANY SCANNED TEXT OUTPUT %%%%%%%%%%%%

    public void onImageTaken(){
        Log.d(Config.TAG, "onImageTaken with path " + this.filePathOriginal);
        ImageProcessingThread thread = new ImageProcessingThread(this.mOcrScannerListener,
                this.filePathOriginal, this.directoryPathOriginal, this.mActivity, this.trainedDataCode);
        thread.execute();
    }

    private void startActivity(Intent intent){
        if(this.mActivity != null) {
            this.mActivity.startActivityForResult(intent, this.requestCode);
        }
    }

    public void setOcrScannerListener(EasyOcrScannerListener mOcrScannerListener) {
        this.mOcrScannerListener = mOcrScannerListener;
    }


}

FileUtils Java

package com.wordpress.priyankvex.easyocrscannerdemo;

import android.os.Environment;
import android.util.Log;

import java.io.File;

/**
 * Created by Priyank(@priyankvex) on 27/8/15.
 */
public class FileUtils {

    public static String getDirectory(String folderName) {
        File directory = null;
        directory = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + folderName);
        if(!directory.exists()) {
            directory.mkdirs();
        }

        return directory.getAbsolutePath(); // %%%%%%%%%%%% POSITIVE BREAKPOINT: IT SHOWS THAT THE FILE DIRECTORY SAVED IN INTERNAL STORAGE %%%%%%%%%%%%
    }

    public static String getTessdataDirectory(String directoryPath){
        File tessdataDirectory = new File(directoryPath + "/tessdata");
        if (tessdataDirectory.mkdirs()){
            Log.d(Config.TAG, "tessdata directory created");
        }
        return tessdataDirectory.getAbsolutePath();
    }
}

ImageProcessingThread Java

package com.wordpress.priyankvex.easyocrscannerdemo;

import android.app.Activity;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.os.AsyncTask;
import android.util.Log;

import com.googlecode.tesseract.android.TessBaseAPI;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * Created by Priyank(@priyankvex) on 27/8/15.
 *
 * Async Task to process the image and scan the image using tesseract library.
 * Equipped with proper callbacks.
 */
public class ImageProcessingThread extends AsyncTask<Void, Void, Void> {

    private EasyOcrScannerListener mOcrScannerListener;
    private String filePath;
    private Bitmap mBitmap;
    private String scannedText;
    // trained data file used by Tesseract will be copied in directoryPath/tessdata
    private String directoryPath;
    private String absoluteDirectoryPath;
    private Activity mActivity;
    String trainedDataCode;

    public ImageProcessingThread(EasyOcrScannerListener ocrScannerListener, String filePath,
                                 String directoryPath, Activity activity, String trainedDataCode) {
        this.mOcrScannerListener = ocrScannerListener;
        this.filePath = filePath;
        this.directoryPath = directoryPath;
        this.absoluteDirectoryPath = FileUtils.getDirectory(this.directoryPath);
        this.mActivity = activity;
        this.trainedDataCode = trainedDataCode;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        mOcrScannerListener.onOcrScanStarted(this.filePath);
    }

    @Override
    protected Void doInBackground(Void... params) {
        processImage();
        makeTessdataReady();
        scannedText = scanImage();
        Log.d(Config.TAG, "Scanned test : " + scannedText);
        return null;
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);
        mOcrScannerListener.onOcrScanFinished(mBitmap, scannedText);
    }

    private void processImage() {
        int imageOrientationCode = getImageOrientation();
        Bitmap rawBitmap = getBitmapFromPath();
        // Getting the bitmap in right orientation.
        this.mBitmap = rotateBitmap(rawBitmap, imageOrientationCode);
    }

    private Bitmap getBitmapFromPath() {
        BitmapFactory.Options bmOptions = new BitmapFactory.Options();
        bmOptions.inSampleSize = 4;
        Bitmap bitmap = BitmapFactory.decodeFile(this.filePath, bmOptions);
        return bitmap;
    }

    private int getImageOrientation() {
        ExifInterface exif = null;
        try {
            exif = new ExifInterface(this.filePath);
        } catch (IOException e) {
            e.printStackTrace();
        }

        assert exif != null;
        int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                ExifInterface.ORIENTATION_UNDEFINED);
        return orientation;
    }

    private Bitmap rotateBitmap(Bitmap bitmap, int orientation){

        Matrix matrix = new Matrix();
        switch (orientation) {
            case ExifInterface.ORIENTATION_NORMAL:
                return bitmap;
            case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
                matrix.setScale(-1, 1);
                break;
            case ExifInterface.ORIENTATION_ROTATE_180:
                matrix.setRotate(180);
                break;
            case ExifInterface.ORIENTATION_FLIP_VERTICAL:
                matrix.setRotate(180);
                matrix.postScale(-1, 1);
                break;
            case ExifInterface.ORIENTATION_TRANSPOSE:
                matrix.setRotate(90);
                matrix.postScale(-1, 1);
                break;
            case ExifInterface.ORIENTATION_ROTATE_90:
                matrix.setRotate(90);
                break;
            case ExifInterface.ORIENTATION_TRANSVERSE:
                matrix.setRotate(-90);
                matrix.postScale(-1, 1);
                break;
            case ExifInterface.ORIENTATION_ROTATE_270:
                matrix.setRotate(-90);
                break;
            default:
                return bitmap;
        }
        try {
            Bitmap bmRotated = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
            bitmap.recycle();
            return bmRotated;
        }
        catch (OutOfMemoryError e) {
            e.printStackTrace();
            return null;
        }
    }

    private String scanImage(){
        TessBaseAPI baseApi = new TessBaseAPI();
        Log.d(Config.TAG, "Data path : " + FileUtils.getDirectory(this.directoryPath));
        baseApi.init(FileUtils.getDirectory(this.directoryPath) + "/", this.trainedDataCode);
        baseApi.setImage(this.mBitmap);
        String recognizedText = baseApi.getUTF8Text();
        baseApi.end();

        return recognizedText;
    }

    private void makeTessdataReady(){

        // created tessdata directory if necessary under absoluteDirectoryPath and returns its absolute path.
        String tessdirectoryPath = FileUtils.getTessdataDirectory(this.absoluteDirectoryPath);

        if (!(new File(tessdirectoryPath+ "/" + this.trainedDataCode + ".traineddata")).exists()) {
            try {

                AssetManager assetManager = mActivity.getAssets();
                InputStream in = assetManager.open("tessdata/" + this.trainedDataCode + ".traineddata");
                //GZIPInputStream gin = new GZIPInputStream(in);
                // Output stream with the location where we have to write the eng.traineddata file.
                OutputStream out = new FileOutputStream(tessdirectoryPath + "/"  + this.trainedDataCode
                        + ".traineddata");

                // Transfer bytes from in to out
                byte[] buf = new byte[1024];
                int len;
                //while ((lenf = gin.read(buff)) > 0) {
                while ((len = in.read(buf)) > 0) {
                    out.write(buf, 0, len);
                }
                in.close();
                //gin.close();
                out.close();

                Log.v(Config.TAG, "Copied " + " traineddata");
            } catch (IOException e) {
                Log.e(Config.TAG, "Was unable to copy " + " traineddata " + e.toString());
            }
        }
        else{
            Log.d(Config.TAG, "tessdata already present");
        }
    }

}

希望有人可以帮助我。真的很感激..... ...

0 个答案:

没有答案