错误:(-215)sz.width%2 == 0&& sz.height%3 == 0&&深度== CV_8U函数void cv :: cvtColor(cv :: InputArray,cv :: OutputArray,int,int)

时间:2016-12-16 21:03:30

标签: java android opencv image-processing

目前我正在开发一个Android应用程序,它可以在运行时查找相机预览中最大的矩形(检测页面或矩形对象)并对其执行OCR。我在运行时检测图像有问题。它显示以下错误。

FATAL EXCEPTION: main Process: sansys.helpinghands, PID: 978 CvException [org.opencv.core.CvException: cv::Exception: /Volumes/Linux/builds/master_pack-android/opencv/modules/imgproc/src/color.cpp:8282: error: (-215) sz.width % 2 == 0 && sz.height % 3 == 0 && depth == CV_8U in function void cv::cvtColor(cv::InputArray, cv::OutputArray, int, int) ]
    at org.opencv.imgproc.Imgproc.cvtColor_0(Native Method)
    at org.opencv.imgproc.Imgproc.cvtColor(Imgproc.java:1715)
    at sansys.helpinghands.CameraPreview.processFrame(CameraPreview.java:201)
    at sansys.helpinghands.CameraPreview.onPreviewFrame(CameraPreview.java:65)
    at android.hardware.Camera$EventHandler.handleMessage(Camera.java:1129)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:148)
    at android.app.ActivityThread.main(ActivityThread.java:5443)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)

我在下面提供了我的代码。

CAMERA PREVIEW CLASS

public class CameraPreview implements SurfaceHolder.Callback,         Camera.PreviewCallback {
    private Camera mCamera = null;
    private ImageView MyCameraPreview = null;
    private Bitmap bitmap, bmp = null;
    private int[] pixels = null;
    private byte[] FrameData = null;
    private int imageFormat;
    private int PreviewSizeWidth;
    private int PreviewSizeHeight;
    private boolean bProcessing = false;
    private Mat mYuv;

    Handler mHandler = new Handler(Looper.getMainLooper());

    public CameraPreview(int PreviewlayoutWidth, int PreviewlayoutHeight, ImageView CameraPreview) {
        PreviewSizeWidth = PreviewlayoutWidth;
        PreviewSizeHeight = PreviewlayoutHeight;
        MyCameraPreview = CameraPreview;
        mYuv = new Mat(PreviewlayoutHeight + PreviewlayoutWidth / 2,   PreviewlayoutWidth, CvType.CV_8UC1);
        Log.v("-------------------->", "" + mYuv.channels());

        pixels = new int[PreviewSizeWidth * PreviewSizeHeight];
    }

    @Override
    public void onPreviewFrame(byte[] arg0, Camera arg1) {
        // At preview mode, the frame data will push to here.
        if (imageFormat == ImageFormat.NV21) {
            // We only accept the NV21(YUV420) format.
            if (!bProcessing) {
                FrameData = arg0;
                this.processFrame(arg0);
                bmp = processFrame(arg0);

                mHandler.post(DoImageProcessing);
            }
        }
    }

    public void onPause() {
        mCamera.stopPreview();
    }

    @Override
    public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
        Camera.Parameters parameters;

        parameters = mCamera.getParameters();
        // Set the camera preview size
        parameters.setPreviewSize(PreviewSizeWidth, PreviewSizeHeight);

        imageFormat = parameters.getPreviewFormat();

        mCamera.setParameters(parameters);

        mCamera.startPreview();
    }

    @Override
    public void surfaceCreated(SurfaceHolder arg0) {
        mCamera = Camera.open();
        try {
            // If did not set the SurfaceHolder, the preview area will be black.
            mCamera.setPreviewDisplay(arg0);
            mCamera.setPreviewCallback(this);
        } catch (IOException e) {
            mCamera.release();
            mCamera = null;
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder arg0) {
        mCamera.setPreviewCallback(null);
        mCamera.stopPreview();
        mCamera.release();
        mCamera = null;
    }


    static {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    }

    private Runnable DoImageProcessing = new Runnable() {
        public void run() {

            System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
            // Mat mat = Imgcodecs.imdecode(new MatOfByte(FrameData), Imgcodecs.CV_LOAD_IMAGE_UNCHANGED);
            Mat tmp = new Mat(bitmap.getHeight(), bitmap.getWidth(), CvType.CV_8UC3);
            bitmap = Bitmap.createBitmap(PreviewSizeWidth, PreviewSizeHeight, Bitmap.Config.ARGB_8888);
            Log.i("MyRealTimeImageProcess", "DoImageProcessing():");
            bProcessing = true;

            bitmap.sameAs(bmp);
            Utils.bitmapToMat(bitmap, tmp);
            Log.v("qweedfdfbfdbf", tmp.width() + "" + tmp.height());
            // detection d = new detection(PreviewSizeWidth, PreviewSizeHeight, FrameData, pixels);
            detection d = new detection();
            MatOfPoint point = null;
            try {
                point = d.find(tmp);
            } catch (Exception e) {
                e.printStackTrace();
            }
            //  MatOfPoint c=d.detection_result();

            List<MatOfPoint> contours = new ArrayList<>();

            contours.add(point);
            MatOfPoint2f approxCurve = new MatOfPoint2f();
            for (int i = 0; i < contours.size(); i++) {
                Imgproc.drawContours(tmp, contours, i, new Scalar(255, 255, 255), -1);
            }
        };
    };
    protected Bitmap processFrame(byte[] data) {

        Mat mRgba = new Mat();
        mYuv.put(0, 0, data);
        Imgproc.cvtColor(mYuv, mRgba, Imgproc.COLOR_YUV420sp2RGB, 4);

        //process mat with native code

        Utils.matToBitmap(mRgba, bitmap);
        return bitmap;
    }
}

检测课程

public class detection {
    private MatOfPoint contour;
    private Mat mat;

    detection(int h, int w, byte[] b, int[] p) {

        Mat mat = Imgcodecs.imdecode(new MatOfByte(b), Imgcodecs.CV_LOAD_IMAGE_UNCHANGED);
        try {
            this.contour = this.find(mat);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    detection(Mat m) {
        this.mat = m;
    }
    MatOfPoint detection_result() {
        return this.contour;
    }
    detection() {}

    public static double angle(Point p1, Point p2, Point p0) {
        double dx1 = p1.x - p0.x;
        double dy1 = p1.y - p0.y;
        double dx2 = p2.x - p0.x;
        double dy2 = p2.y - p0.y;
        return (dx1 * dx2 + dy1 * dy2) / Math.sqrt((dx1 * dx1 + dy1 * dy1) * (dx2 * dx2 + dy2 * dy2) + 1e-10);
    }

    public static MatOfPoint find(Mat src) throws Exception {
        Mat blurred = src.clone();
        Imgproc.medianBlur(src, blurred, 9);

        Mat gray0 = new Mat(blurred.size(), CvType.CV_8U), gray = new Mat();

        List<MatOfPoint> contours = new ArrayList<>();

        List<Mat> blurredChannel = new ArrayList<>();
        blurredChannel.add(blurred);
        List<Mat> gray0Channel = new ArrayList<>();
        gray0Channel.add(gray0);

        MatOfPoint2f approxCurve;

        double maxArea = 0;
        int maxId = -1;

        for (int c = 0; c < 3; c++) {
            int ch[] = {c, 0};
            Core.mixChannels(blurredChannel, gray0Channel, new MatOfInt(ch));

            int thresholdLevel = 1;
            for (int t = 0; t < thresholdLevel; t++) {
                if (t == 0) {
                    Imgproc.Canny(gray0, gray, 10, 20, 3, true); // true ?
                    Imgproc.dilate(gray, gray, new Mat(), new Point(-1, -1), 1); // 1 ?
                } else {
                    Imgproc.adaptiveThreshold(gray0, gray, thresholdLevel, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C, Imgproc.THRESH_BINARY, (src.width() + src.height()) / 200, t);
                }

                Imgproc.findContours(gray, contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);

                for (MatOfPoint contour : contours) {
                    MatOfPoint2f temp = new MatOfPoint2f(contour.toArray());

                    double area = Imgproc.contourArea(contour);
                    approxCurve = new MatOfPoint2f();
                    Imgproc.approxPolyDP(temp, approxCurve, Imgproc.arcLength(temp, true) * 0.02, true);

                    if (approxCurve.total() == 4 && area >= maxArea) {
                        double maxCosine = 0;

                        List<Point> curves = approxCurve.toList();
                        for (int j = 2; j < 5; j++) {

                            double cosine = Math.abs(angle(curves.get(j % 4), curves.get(j - 2), curves.get(j - 1)));
                            maxCosine = Math.max(maxCosine, cosine);
                        }

                        if (maxCosine < 0.3) {
                            maxArea = area;
                            maxId = contours.indexOf(contour);
                            //contours.set(maxId, getHull(contour));
                        }
                    }
                }
            }
        }

        if (maxId >= 0) {
            return contours.get(maxId);
            //Imgproc.drawContours(src, contours, maxId, new Scalar(255, 0, 0, .8), 8);
        }
        return null;
    }

    public static void main(String args[]) throws Exception {

    }
}

0 个答案:

没有答案