org.opencv.core.CvException:cv :: Exception

时间:2019-01-07 06:02:48

标签: java android android-studio opencv

我是android的初学者,在应用启动后一切正常,但我创建了一个文本识别应用程序,但是从相机捕获图像后,我无法在textview框中获取结果。

然后我检入logcat并在logcat中发现一些例外,并在

中带有蓝色下划线
  

“ PROCESSIMAGE.JAVA:84,RECOGNIZETEXTACTIVITY.JAVA:161和   RECOGNIZETEXTACTIVITY:152“。

此后,我在google中找到了解决方案,但不幸的是我没有找到。

CvException [org.opencv.core.CvException: cv::Exception: /hdd2/buildbot/slaves/slave_ardbeg1/50-SDK/opencv/modules/core/src/matrix.cpp:323: error: (-215) 0 <= roi.x && 0 <= roi.width && roi.x + roi.width <= m.cols && 0 <= roi.y && 0 <= roi.height && roi.y + roi.height <= m.rows in function cv::Mat::Mat(const cv::Mat&, const Rect&)
]
    at org.opencv.core.Mat.n_submat(Native Method)
    at org.opencv.core.Mat.submat(Mat.java:2325)
    at com.example.nabil.ocr.compa.readerocr.ProcessImage.parseBitmap(ProcessImage.java:84)
    at com.example.nabil.ocr.compa.readerocr.RecognizeTextActivity.displayResult(RecognizeTextActivity.java:161)
    at com.example.nabil.ocr.compa.readerocr.RecognizeTextActivity.onActivityResult(RecognizeTextActivity.java:152)
    at android.app.Activity.dispatchActivityResult(Activity.java:7701)
    at android.app.ActivityThread.deliverResults(ActivityThread.java:5031)
    at android.app.ActivityThread.handleSendResult(ActivityThread.java:5078)
    at android.app.ActivityThread.-wrap20(Unknown Source:0)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2053)
    at android.os.Handler.dispatchMessage(Handler.java:108)
    at android.os.Looper.loop(Looper.java:166)
    at android.app.ActivityThread.main(ActivityThread.java:7523)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)

ProcessImage.java

public class ProcessImage {

static {
    if (!OpenCVLoader.initDebug()) {
        Log.w(TAG, "Unable to load OpenCV");
    } else {
        info("OpenCV loaded");
    }

    // For OCR
    System.loadLibrary("gnustl_shared");
    System.loadLibrary("nonfree");
}

public static boolean DEBUG = false; // Debug mode
public static String language = "eng";

public int sourceWidth = 1366; // To scale to
public static int thresholdMin = 85; // Threshold 80 to 105 is Ok
private int thresholdMax = 255; // Always 255

public String recognizeResult = "";

// Write debug image
private void writeImage(String name, Mat origin) {
    if (!DEBUG) {
        return;
    }
    String appPath = APP_PATH;
    info("Writing " + appPath + name + "...");
    imwrite(appPath + name, origin);
}

public boolean parseBitmap(Bitmap bitmap, int top, int bot, int right, int left) {
    try {
        Mat origin = new Mat();
        Utils.bitmapToMat(bitmap, origin);
        info("Mat size: " + origin.width() + ":" + origin.height());
        // Crop image to get the resion inside the rectangle only
        info("Crop T: " + top + " B: " + bot + " R: " + right + " L: " + left);
        if (top != 0 && bot != 0 && right != 0 && left != 0) {
            info("Cropping...");    
            origin = origin.submat(new Rect(right, top, left, bot));
            writeImage("crop.jpg", origin);
        }

        boolean result = recognizeImage(origin);
        origin.release();
        return result;
    } catch (Exception e) {
        Log.e(TAG, "Error parse image. Message: " + e.getMessage(), e);
    }
    return false;
}

/**
 * 
 * Parse image
 * 
 * @Param origin
 * @return
 */
private boolean recognizeImage(Mat origin) {
    info("recognizeImage");
    // Reset value
    recognizeResult = "";

    // Resize origin image
    Size imgSize = origin.size();
    resize(origin, origin, new Size(sourceWidth, imgSize.height * sourceWidth / imgSize.width), 1.0, 1.0,
            INTER_CUBIC);

    writeImage("resize.jpg", origin);

    // Convert the image to GRAY
    Mat originGray = new Mat();
    cvtColor(origin, originGray, COLOR_BGR2GRAY);

    // Process noisy, blur, and threshold to get black-white image
    originGray = processNoisy(originGray);

    writeImage("gray.jpg", originGray); // Black-White image

    recognizeResult = matToString(originGray);
    info("Done recognize");

    originGray.release();
    originGray = null;

    info("Result: " + recognizeResult);
    return true;
}

/**
 * Crop sub mat by four points.
 * 
 * @Param origin
 * @Param tl
 * @Param tr
 * @Param bl
 * @Param br
 * @return
 */
private Mat cropSub(Mat origin, Point tl, Point tr, Point bl, Point br) {
    info("cropSub");

    int resultWidth = (int) (tr.x - tl.x);
    int bottomWidth = (int) (br.x - bl.x);
    if (bottomWidth > resultWidth)
        resultWidth = bottomWidth;

    int resultHeight = (int) (bl.y - tl.y);
    int bottomHeight = (int) (br.y - tr.y);
    if (bottomHeight > resultHeight)
        resultHeight = bottomHeight;

    List<Point> source = new ArrayList<Point>();
    source.add(tl);
    source.add(tr);
    source.add(bl);
    source.add(br);
    Mat startM = Converters.vector_Point2f_to_Mat(source);

    Point outTL = new Point(0, 0);
    Point outTR = new Point(resultWidth, 0);
    Point outBL = new Point(0, resultHeight);
    Point outBR = new Point(resultWidth, resultHeight);
    List<Point> dest = new ArrayList<Point>();
    dest.add(outTL);
    dest.add(outTR);
    dest.add(outBL);
    dest.add(outBR);
    Mat endM = Converters.vector_Point2f_to_Mat(dest);

    Mat subTrans = getPerspectiveTransform(startM, endM);
    Mat subMat = new Mat();
    warpPerspective(origin, subMat, subTrans, new Size(resultWidth, resultHeight));
    subTrans.release();
    return subMat;
}

/**
 * Process noisy or blur image with simplest filters
 * @Param grayMat
 * @return
 */
private Mat processNoisy(Mat grayMat) {
    Mat element1 = getStructuringElement(MORPH_RECT, new Size(2, 2), new Point(1, 1));
    Mat element2 = getStructuringElement(MORPH_RECT, new Size(2, 2), new Point(1, 1));
    dilate(grayMat, grayMat, element1);
    erode(grayMat, grayMat, element2);

    GaussianBlur(grayMat, grayMat, new Size(3, 3), 0);
    // The thresold value will be used here
    threshold(grayMat, grayMat, thresholdMin, thresholdMax, THRESH_BINARY);

    return grayMat;
}

/**
 * Convert mat to string
 * 
 * @Param source
 * @return
 */
private String matToString(Mat source) {
    int newWidth = source.width()/2;
    resize(source, source, new Size(newWidth, (source.height() * newWidth) / source.width()));
    writeImage("text.jpg", source);
    CharDetectOCR ocrReader = new CharDetectOCR();
    String result = ocrReader.getOCRResult(toBitmap(source));
    //result = result.replace("O", "0"); // Replace O to 0 if have.
    return result;
}

/**
 * Convert mat to bitmap
 * 
 * @Param mat
 * @return
 */
public static Bitmap toBitmap(Mat mat) {
    Bitmap bitmap = Bitmap.createBitmap(mat.width(), mat.height(), Bitmap.Config.ARGB_8888);
    Utils.matToBitmap(mat, bitmap);
    return bitmap;
}
}

RecognizeTextActivity.Java

public class RecognizeTextActivity extends Activity { static int REQUEST_IMAGE_CAPTURE = 1; static ProcessImage processImg = new ProcessImage();

Button btnStartCamera;
Button btnExit;

private String language;
private TouchImageView image;
private EditText recognizeResult;

private int sourceW = 0;
private int sourceH = 0;
private String lastFileName = "";
private boolean isRecognized = false;

ProgressDialog progressBar;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_reader);
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    Bundle b = getIntent().getExtras();
    language = b.getString("language");
    ProcessImage.language = language;
    ProcessImage.thresholdMin =  Integer.parseInt(b.getString("threshold"));
    info("Language: "+ language + "   threshold: "+ ProcessImage.thresholdMin);

    btnStartCamera = (Button) findViewById(R.id.btnStartCamera);
    btnExit = (Button) findViewById(R.id.btnExit);

    btnStartCamera.setOnTouchListener(new OnTouchListener() {

        @Override
        public boolean onTouch(View arg0, MotionEvent arg1) {
            if (arg1.getAction() == MotionEvent.ACTION_UP) {
                takePicture();
            }
            return false;
        }
    });

    btnExit.setOnTouchListener(new OnTouchListener() {
        @Override
        public boolean onTouch(View arg0, MotionEvent arg1) {
            if (arg1.getAction() == MotionEvent.ACTION_UP) {
                existApp();
            }
            return false;
        }
    });

    recognizeResult = (EditText) findViewById(R.id.recognize_result);
    image = (TouchImageView) findViewById(R.id.grid_img);
    image.setScaleType(ScaleType.CENTER_INSIDE);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        new InitTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
    } else {
        new InitTask().execute();
    }

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.recognize, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}

private void takePicture() {
    Intent takePicIntent = new Intent(RecognizeTextActivity.this, AndroidCamera.class);
    lastFileName = CommonUtils.APP_PATH + "capture" + System.currentTimeMillis() + ".jpg";
    takePicIntent.putExtra("output", lastFileName);
    info(lastFileName);
    startActivityForResult(takePicIntent, REQUEST_IMAGE_CAPTURE);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        Bitmap imageBitmap = BitmapFactory.decodeFile(lastFileName, options);

        if (imageBitmap == null) {
            // Try again
            isRecognized = false;
            image.setImageBitmap(imageBitmap);
            hideProcessBar();
            dialogBox("Can not recognize sheet. Please try again", "Retry", "Exist", true);
            return;
        }
        final Bitmap finalImageBitmap = imageBitmap.getWidth() > imageBitmap.getHeight()
                ? rotateBitmap(imageBitmap, 90) : imageBitmap;

        int top = data.getIntExtra("top", 0);
        int bot = data.getIntExtra("bot", 0);
        int right = data.getIntExtra("right", 0);
        int left = data.getIntExtra("left", 0);

        image.setImageBitmap(finalImageBitmap);
        displayResult(finalImageBitmap, top, bot, right, left);

    }
}

public void displayResult(Bitmap imageBitmap, int top, int bot, int right, int left) {
    info("Origin size: " + imageBitmap.getWidth() + ":" + imageBitmap.getHeight());
    // Parser
    recognizeResult.setText("");
    if (processImg.parseBitmap(imageBitmap, top, bot, right, left)) {
        // TODO: set result
        recognizeResult.setText(processImg.recognizeResult);
        // TODO: write result to image
        // image.setImageBitmap(toBitmap(processImg.drawAnswered(numberAnswer)));
        isRecognized = true;
        hideProcessBar();
    } else {
        // Try again
        isRecognized = false;
        image.setImageBitmap(imageBitmap);
        hideProcessBar();
        dialogBox("Can not recognize sheet. Please try again", "Retry", "Exist", true);
    }
}

public Bitmap rotateBitmap(Bitmap source, float angle) {
    Matrix matrix = new Matrix();
    matrix.postRotate(angle);
    return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);
}

public void dialogBox(String message, String bt1, String bt2, final boolean flagContinue) {
    AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
    alertDialogBuilder.setMessage(message);
    alertDialogBuilder.setPositiveButton(bt1, new DialogInterface.OnClickListener() {

        @Override
        public void onClick(DialogInterface arg0, int arg1) {
            if (flagContinue) {
                takePicture();
            }
        }
    });

    if (bt2 != "") {
        alertDialogBuilder.setNegativeButton(bt2, new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface arg0, int arg1) {
                existApp();
                // return false;
            }
        });
    }

    AlertDialog alertDialog = alertDialogBuilder.create();
    alertDialog.show();
}

public void existApp() {
    CommonUtils.cleanFolder();
    this.finish();
}

public void showProgressBar(String title, String message) {
    progressBar = ProgressDialog.show(this, title, message, false, false);
}

public void hideProcessBar() {
    runOnUiThread(new Runnable() {

        @Override
        public void run() {
            if (progressBar != null && progressBar.isShowing()) {
                progressBar.dismiss();
            }
        }
    });
}

private class InitTask extends AsyncTask<String, Void, String> {
    @Override
    protected String doInBackground(String... data) {
        try {
            CharDetectOCR.init(getAssets());
            return "";
        } catch (Exception e) {
            Log.e("COMPA", "Error init data OCR. Message: " + e.getMessage());
        }
        return "";
    }

    @Override
    protected void onPostExecute(String result) {

    }
}

}

0 个答案:

没有答案